Structure of a space
On a file-level, a Waytale Space is a directory that holds specific files and directories. A directory in the folder of a space is supposed to represent a Waytale Map.
Please note that in the current phase of development there might still be some breaking changes. While this section documents a standard, that standard is still changing here and there. Expects updates for the next weeks as long as this notice is still present.
Directory structures
A Waytale space is a directory with the following structure. Entries ending in / are directory names. Names in "pointy brackets" (< and >) are arbitrary (see section below). Entries marked with (*) are optional.
/space.json
/index.html
/<mapname>/
/_waytale/style.css
/_waytale/waytale.js
/_waytale/proxy.html *
/_waytale/gadgets/<gadgetname>/
/_waytale/avatars.json
/_waytale/avatars/<avatarname>.png
Typically the index.html file and _waytale directory are provided by a distribution of the Waytale Viewer.
A map directory from above has the following structure. Files in the resources directory are referenced by name in map.json.
/
/map.json
/background.png
/foreground.png *
/resources/ *
/resources/<file> *
Valid names
The names of maps (<mapname> above) or resources are arbitrary, but generally they should be safe filenames to avoid trouble. It is recommended to stick to alphanumerical characters and characters that do not require URL-encoding such as -._. See also RFC 3986 for details.
Space configuration (space.json)
The space.json file describes general information for the whole space and all included maps. Following table describes all relevant properties and afterwards is an example file. Also see the notes for suitable WebRTC settings below.
| Key | Type | Description |
|---|---|---|
version |
Float | Version of file format |
info.author |
String | The owners of the space |
info.description |
String | A short description of the space |
info.maps |
Array[String] | Recommendation of maps to start |
webrtc.signalling |
Array[String] | List of URIs to signalling server |
webrtc.iceServers |
Array[IceServer] | List of STUN/TURN servers. |
Example file:
{
"version": 1.0,
"info": {
"author": "John Doe",
"description": "My private corner on the internet",
"maps": [
"<map1>",
"<map2>"
]
},
"webrtc": {
"signaling": [
"wss://signalling1.example.com",
"wss://signalling2.example.com"
],
"iceServers": [
{
"urls": "stun:stun.example.com:80"
},
{
"urls": "turn:turn.example.com:80",
"username": "great_username",
"credential": "secure_token"
},
{
"urls": "turn:turn.example.com:80?transport=tcp",
"username": "great_username",
"credential": "secure_token"
}
]
}
}
WebRTC configuration
This section has some hints regarding the WebRTC-specific settings for space.json.
Signalling server
One reliable signalling server is sufficient. Specifying multiple signalling server that do not synchronise can lead to connectivity problems with other peers. Ideally, URIs use the secure websocket protocol (wss:// instead of ws://).
ICE servers (STUN/TURN)
Specifying more than one STUN server can help reduce connection time, but generally 2 STUN servers are enough. In contrast, TURN servers relay traffic, so a good number of TURN servers depends on factors like the number of peer connections, bandwidth, and of course traffic volume. For small spaces, 1 or 2 TURN servers should be enough.
Public STUN and TURN servers can be found online, but sometimes sources or servers themselves are unreliable, so some checking and testing is recommended. Setting up a server yourself is quite possible, but may require hosting costs.
Some tools that might help finding and testing servers:
- Trickle ICE, online tool by the WebRTC project to test STUN/TURN servers.
- List of WebRTC ICE Servers by Metered, including explantions, exsamples, and hosting options (not affiliated).
Map configuration (map.json)
The map.json file describes the particular maps. Following table describes all relevant properties and afterwards is an example file.
| Key | Type | Description |
|---|---|---|
version |
Float | Version of file format |
size |
Tuple[Integer, Integer] | Width and height of the map |
tileSize |
Tuple[Integer, Integer] | Width and height of a tile (currently this must be 32x32) |
collision |
String | Base64-encoded bit-map (not byte-map) of collision tiles |
spawn |
List[Tuple[Integer, Integer]] | List of spawn X-Y-positions |
areas |
List[MapArea] | List of MapArea objects, see below |
gadgets |
List[MapGadget] | List of MapGadget objects, see below |
Currently the tile size is fixed to 32x32 pixels. This is a hard constraint, which might get removed in future versions.
Example file:
{
"version": 1.0,
"size": [60, 40],
"tileSize": [32, 32],
"collision": "AEACAAIAEAIA/*...*/AAAAAA",
"spawn": [ [26, 17], [27, 17], /*...*/ [33, 22] ],
"areas": [
/*...*/
],
"gadgets": [
{
"type": "jitsi",
"position": [50, 19],
"radius": 2,
"image": "gadget001.png",
"data": {
"domain": "meet.ffmuc.net",
"prefix": "waytale-"
}
}
]
}
Base64-encoding of bitmasks
The collision bitmap is encoded as follows:
- All tiles of the 2D grid are iterated starting with the top-left corner at position (0, 0).
- The iteration of tiles proceeds linewise and left-to-right.
- Each collision tile is translated into 0 or 1, where 1 means collision.
- Every set of eight 0s and 1s in the given order forms a byte.
- All positions are converted into an array of bytes, which gets encoded using base64.
- If there are insufficient tiles to form a full last byte, it may be right-padded with 0s.
MapArea objects
MapArea objects have the following properties.
| Key | Type | Description |
|---|---|---|
| (follows soon) |
Example snippet, as it may appear in a map.json file:
(follows soon)
MapGadget objects
MapGadget objects have the following properties.
| Key | Type | Description |
|---|---|---|
type |
String | Identifier of gadget type |
position |
Tuple[Integer, Integer] | X-Y-position of gadget |
radius |
Integer | Interaction distance (0 requires standing on same tile) |
image |
String | Filename in resources directory for visuals (should be 32x32 pixels) |
data |
Object | Gadget-specific information |
Example snippet, as it may appear in a map.json file:
{
"type": "jitsi",
"position": [50, 19],
"radius": 2,
"image": "gadget001.png",
"data": {
"domain": "meet.ffmuc.net",
"prefix": "waytale-"
}
}