Skip to content

Instantly share code, notes, and snippets.

@NovaSquirrel
Last active March 25, 2023 20:22
Show Gist options
  • Save NovaSquirrel/f6bcb163579bee8f95b56c814cba8659 to your computer and use it in GitHub Desktop.
Save NovaSquirrel/f6bcb163579bee8f95b56c814cba8659 to your computer and use it in GitHub Desktop.
Tilemap Town simple binary protocol
------------------- General protocol information -------------------
cc-cc ll-ll [..]
Command, Length, Data
Command types would be represented with a 16-bit enum instead of the four character ASCII codes used here, but those codes could be shown for debug display purposes, or for talking about the protocol.
By default, this protocol can only work with 256 different kinds of tiles at a time. Most platforms this protocol is aimed at probably wouldn't fit more than that into video RAM anyway.
For instance, SNES background layers can only reference 1024 different 8x8 tiles, and 1024/4 = 256 16x16 tiles. Same for the GBA and DS, though the DS could use bitmap modes as a workaround.
Entity ID 0 is always the player's entity.
Maximum map size is 256x256, but a client may have a smaller limit.
------------------- Miscellaneous -------------------
--> CONN [param] 00 [value] 00 [param] 00 [value] ...
<-- CONN [param] 00 [value] 00 [param] 00 [value] ...
Connect to server
Parameters and values are sent with IDs and values in text form, separated with null bytes. Numbers are sent in hexadecimal.
Some parameters:
client_name
client_version
protocol_version
platform
Probably just for information purposes? But could imply other settings.
graphics_format
Options:
SNES
SNES 4bpp format
GBA
GBA (or DS) 4bpp format
MD
Sega Genesis 4bpp format
ABGR555
DS-compatible RGB
RGBA888
Generic RGB
ABGR888
3DS compatible RGB
Choosing a graphics format also chooses a palette format, or the lack of a palette entirely (for RGB modes)
tileset_size
Defaults to 256 but can be lower. If it's higher than 256, tile IDs in this protocol have to use 16-bit numbers instead.
bg_palette_count
Number of palettes that the client can dedicate to displaying the map. Probably 7 on SNES, but could go higher on something like the DS.
max_map_dimensions
Defaults to 128 (width) 128 (height).
max_entities
Number of entities the client can support.
max_entity_tiles
Number of 16x16 entity tiles the client can store.
<-- PING
--> PING
Server ping
<-- BATS
<-- BATE
Batch start, and Batch end.
Client holds onto messages received after a BATS until it receives a BATE and then it executes all of them together.
------------------- Movement -------------------
--> MOVE xx yy dd
Player has moved to a new place
--> BUMP xx yy mm
Bumped into something solid
The gateway will handle displaying messages when bumping into signs
<-- MOVE ee xx yy dd
Entity has moved
<-- WARP xx yy dd cc
Server moved the player to a new place
E = Entity ID
X = X position
Y = Y position
D = Direction (0-7)
C = If 01, instantly move camera to new position
M = Map ID
------------------- Text -------------------
--> CHAT [text]
Send public chat message
--> COMD [commandname] 20 [text]
Send command
<-- MESG ss [speaker] 00 [..]
S = Message style
--> PRIV [username] 00 [text]
Send private message to someone
<-- PRIV 00 [username] 00 [text]
Confirmation of private message you sent
<-- PRIV 01 [username] 00 [text]
Private message sent by someone else
<-- ERRO [text]
Error message
------------------- Map -------------------
--> TILE xx yy 00 ss
Delete a map tile
S = 01 Delete turf
S = 02 Delete objects
S = 03 Delete turf and objects
--> DELT xx yy ww hh ss
Delete rectangle with same meaning for S as TILE
--> TILE xx yy 01 tt
Put a map turf
--> TILE xx yy 02 tt
Put a map object
T = tile ID
<-- MAPR xx yy ww hh [turfs] [objects]
Map data rectangle
Map data is sent with a simple RLE system, with this format repeated until the entire rectangle has been covered:
RLLL LLLL
|+++-++++- How many tiles
+--------- If 0, L+1 tiles follow
If 1, one tile follows, and it's repeated L+1 times
Each tile is a byte in size.
<-- MAPI mm ww hh [map name] 00
Map info
M = Map ID. Not the actual ID, the server just sends a higher number every time MAPI is sent, in order to let commands like BUMP avoid race conditions.
W = Width
H = Height
------------------- Entities -------------------
<-- ENTL nn [ee xx yy dd pp ss [name] 00]*nn
Replace the entity list with a new one
N = count
<-- ENTU [ee xx yy dd pp ss [name] 00]
Add/update an entity
<-- ENTR ee
Remove an entity
<-- ENTN [old_id] [new_id]
Change an entity's ID
X = X position
Y = Y position
D = Direction
P = Picture number
S = Status
S = 00 Normal
S = 01 Away
S = 02 Busy
S = 03 Do not disturb
S = 04 In-character
S = 05 Interested in being in-character
S = FF Not actually a player; don't show in player lists
E = Entity ID
<-- EIMG bb cc [per-tile flags]*cc [16x16 tile]*cc
Upload entity images
B = First image to change
C = How many images to change
Tile flags are in this format:
TTTT PPPP
|||| ++++- Tile palette
++++------ Tile type
0 16x16 tile
1 32x32, use the next three tiles
2 32x32 with four directions
<-- EPAL bb cc [palette]*cc
Palette update for entities
B = First palette to change
C = How many palettes to change
------------------- Tileset -------------------
<-- TSET bb cc [per-tile flags]*cc [per-tile graphics]*cc
Tileset update
B = First tile to change
C = How many tiles to change, + 1
Tile flags are in this format:
BBBB PPPP
|||| ++++- Tile palette
++++------ Tile type/behavior:
0 Turf, not dense
1 Turf, dense
2 Object, not dense
3 Object, dense
4+ are reserved
<-- TPAL bb cc [palette]*cc
Palette update for tiles
B = First palette to change
C = How many palettes to change
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment