💾 Archived View for thingvellir.net › rutentoy › protocol.gmi captured on 2023-04-26 at 13:09:15. Gemini links have been rewritten to link to archived content
View Raw
More Information
⬅️ Previous capture (2023-04-19)
➡️ Next capture (2024-07-08)
-=-=-=-=-=-=-
Rutentoy Protocol
This is a work-in-progress net protocol spec for a yet-unimplemented video game.
The Rutentoy protocol can work over TCP, UDP, SCTP, or WebSocket.
The DNS SRV service name for this protocol is 'rutentoy'.
The opcode numbers before the packet names in this document are hexadecimal.
TCP packets may combine multiple game packets.
UDP packets must be sent individually and have a maximum size of 1050 bytes.
Types
All integers are two's-compliment when signed and are in big-endian byte order.
Text strings are encoded as UTF-8 without a BOM or null terminator.
Object positions are encoded as signed 24-8 fixed point.
Object rotations are encoded as unsigned 0-16 fixed point, representing fractions of one turn. 0-65536 should be scaled to 0-2π.
Structure fields are not aligned and do not contain padding. They are not intended to be read directly into program memory.
Structure fields named 'cookie' refer to ephemeral identifiers, not semi-permanent client data as the term is used for the Web. This document does not specify a specific algorithm for determining cookie values.
All packets are prefixed with a single opcode byte, followed by an unsigned 16 bit integer representing the length of the following packet data. This is to allow partial implementations and protocol extensions.
Over unreliable transports such as UDP, the packet is also prefixed with a monotonically increasing unsigned 64-bit integer, starting with zero and increasing for every sent packet. If a gap in this sequence is detected, a packet is known to have been dropped.
Server Info Sequence
- C: Opens socket
- C→S: Text (Client IPC) "INFO"
- S→C: Text (Client IPC) "INFO (number of total player slots);(number of occupied player slots);('public' or 'private');(protocol:hostname:port);(server-local timezone offset);(message-of-the-day text)"
- S: Closes socket
Login Sequence
- C: Opens socket
- C→S: Text (Client IPC) "LOGIN (username) [passkey, may contain spaces]"
- (Optional) C→S: Object Texture Chunk (eid 0)
- S→C: World Chunk
- S→C: Object Create (eid 0)
- S→C: Object Move (eid 0)
- C: Ready for Play
00 Disconnect
Sent by either the client or the server to announce the network socket is about to be closed. Usually prefixed with the "LEAVE ..." Client IPC message to describe why the disconnect happened. The server may optionally announce a client disconnecting by sending a 'player has left' message to the System channel.
struct 00_disconnect {}
sizeof(00_disconnect) = 0
01 Ping
Sent by the server to check for both the network latency and responsiveness of a client. The client should echo this packet back to the server when recieved.
struct 01_ping {
cookie: u32,
}
sizeof(01_ping) = 4
02 Object Create
Sent by the server to create a movable object on the client. How the server determines the value of the 'oid' field is implementation-defined.
The following list is a list of model IDs that a client must support rendering:
- 0:0, Humanoid: A biped with two arms and a head. The default appearance of this model should be generic, not visibly gendered, and should have a non-human skin tone such as gray, blue, or bright yellow. The client may optionally support utilising unused portions of the player model texture for implementation-specific extensions.
- 1:Varies, Block/Item: The object appears as a full-size block or item, separated from static world blocks.
- 2:Varies, Static Item: The object appears as a miniature block or item.
- 3:Varies, Interactive Item: The object appears as a miniature block or item and indicates that it is interactive in some way, such as spinning in the air or a shine effect.
struct 02_create {
oid: u32, // unique object id
model: u16, // model id
model_meta: u16, // extra metadata for the model
}
sizeof(02_create) = 8
03 Object Move
Sent by the client every 40 milliseconds with the entity field set to zero.
The server sends this to a client with the entity field set to zero to teleport them.
The server sends this to a client with the entity field set to a nonzero value to update the position and rotation of another object model.
struct 03_move {
oid: u32, // unique object id, see 02 Object Create
x: i32, // signed 26-6 position fixed-point
y: i32,
z: i32,
yaw: u16, // unsigned 0-16 angle fixed-point
pitch: u16,
}
sizeof(03_move) = 20
04 Object Delete
The server sends this to a client to remove an object model.
If sent with the entity field set to zero, the client displays an intermission screen until it is sent another 02 Object Create packet with the 'oid' field set to zero.
When a client receives this packet with the 'oid' field set to zero, world data and objects are cleared to avoid incongruencies with possible future data.
struct 04_delete {
oid: u32, // unique object id
}
sizeof(04_delete) = 4
04 Object Texture Chunk
Sent by the client to give the server a custom player-specified model texture.
The server or client must not abuse this packet to create animated textures.
The maximum texture size is 128x128. Textures must be have power-of-two dimensions. The image data is encoded as two unsigned, little-endian, 16 bit integers for the width and height of the image, followed by ARGB image data bytes.
struct 04_texture {
oid: u32, // unique object id
chunk_num: u16, // which chunk is being sent, in case of out-of-order
cookie: u32, // unique identifier for this specific texture
data_len: u16, // how many bytes in the 1024-byte chunk is used,
// 16th bit indicates final chunk
data: [1024]u8, // a 1024-byte chunk of data
}
sizeof(04_texture) = 1036
05 Object Metadata
Sent by the server to update an object's details.
Required Supported 'meta_type' Values
- 0, Color: The 'meta_data' field contains four bytes for an IRGB color tint and glow intensity, 0 being no glow and 255 being full brightness at all times.
- 1, Animate: The 'meta_data' field contains an animation ID. Some animations are temporary and some change a model's posture or animation mode.
- 2, Equipment: The 'meta_data' field contains an item or block ID, and a 4-bit number describing where the equipment should be shown on the model. An item/block ID of 0 removes the equipment from the specified area on the model. The client may send this to the server.
- 3, Health: The 'meta_data' field contains four bytes for the object's maximum health points, current health points, current armor points, and current air points.
Animation IDs
Some animation IDs will only work with certain models. Animations with (Overlay) next to their name should be layered on top of the current (Stance) animation.
- 0, Idle/Stand (Stance): The object stands normally and moves in a walking motion when moving. For non-humanoid models, the object does not move at all. This is the default animation.
- 1, Crouch (Stance): The object crouches down and moves in a walking motion when moving.
- 2, Punch Right (Overlay): The object swings its right arm in a punching motion.
- 3, Punch Left (Overlay): The object swings its left arm in a punching motion.
- 4, Swing Right (Overlay): The object swings its right arm as if swinging a weapon or tool.
- 5, Swing Left (Overlay): The object swings its left arm as if swinging a weapon or tool.
- 6, Death (Stance): The object falls down and optionally disappears.
- 7, Item (Stance): The object becomes smaller and either slowly shines or slowly spins floating above the ground. This is intended for use with the 1 Block/Item model, although the client may optionally support this on other models as well.
- 8, Aim Weapon Start (Overlay): The object holds its arms out as if holding a pulled bow or sling.
- 9, Aim Weapon End (Overlay): The 6 Aim Weapon Start animation ends.
- 10, Hurt (Overlay): The object moves as if it was just hit by an attack.
Model Equipment Slot IDs
- 0 Head
- 1 Chest
- 3 Legs
- 4 Boots
- 5 Right Hand
- 6 Left Hand
- 7 Left Hip
- 8 Right Hip
- 9 Back Holster 1
- A Back Holster 2
- B Backpack
- C-F Unused
struct 06_object_meta {
oid: u32, // unique object id
meta_data: u32, // 32 arbitrary bits of data, depends on meta_type
meta_type: u8, // what detail should be changed
}
sizeof(06_object_meta) = 9
07 Interact
Sent by the client to indicate the player is interacting with a block, item, or object.
When a player fully breaks a block with an effective tool, the block is immediately placed into their inventory. If no item slots are available in the player's inventory, the item appears at the center of the broken block's position.
Interaction Types
- 0 Use Object
- 1 Use Block
- 2 Use item in right hand
- 3 Use item in left hand
- 4 Use item in right hand, on object if oid is nonzero, otherwise on block
- 5 Use item in left hand, on object if oid is nonzero, otherwise on block
- 6 Attack with item in right hand
- 7 Attack with item in left hand
- 8 Reserved
- 9 Reserved
- A Reserved
- B Reserved
- C Begin breaking block with item
- E Complete breaking block with item
- F Cancel breaking block
struct 07_interact {
oid: u32, // targeted object, 0 if none
block_x: i32, // targeted block position
block_y: i32,
block_z: i32,
item: u16, // F000 interaction type, 0FFF used item ID
}
sizeof(07_interact) = 18
08 GUI Open
Sent by the server to open a GUI screen on the client. Sent by the client to notify a GUI screen being closed.
Modes
- 0 Close: Sent by the client or the server to close an open GUI.
- 1 Player: Sent by the client or the server. There is one 5x5 item field representing the player's inventory. There is two 1x4 item fields on the left and right for wearable items. Inbetween these two fields is a display of the player's appearance.
- 2 Cooking: Sent by the server. There is two 3x3 item fields on the left and right, for uncooked and cooked items respectively. There is a single item slot inbetween that is for fuel items.
- 3 8x8 Container: Sent by the server. A single 8x8 item field representing the contents of a container.
struct 08_gui_open {
mode: u16, // which gui to open
cookie: u16, // a client-unique identifier for the opened gui,
// set to 0 when using mode 1
}
sizeof(08_gui_open) = 4
09 GUI Interact
Sent by the client to move a container's items between slots or other containers.
Modes
- 0 Take, the player takes an item from a slot
- 1 Place, the player places a previously taken item into a slot
- 2 Swap, the player swaps the items between two slots
- 3 Throw, the player throws the item onto the floor
struct 09_gui_interact {
mode: u8,
send_slot: u8,
recv_slot: u8,
send_cookie: u16,
recv_cookie: u16,
}
sizeof(09_gui_interact) = 7
0A GUI Items
TODO
struct 0a_gui_items {}
sizeof(0a_gui_items) = ??
0B Text
A text message sent to the server, or a text message sent from the server to display on the client. The only ASCII control character allowed is 0A LINEFEED. Implementations must not assume that non-UTF-8 data will be transferred losslessly.
Minimal implementations may opt to only display ASCII or UTF-8 encoded Latin-1 characters.
Channels
The channel field describes where the message should be displayed.
The following is a list of defined values:
- 0 Chat: The normal chat area players can send messages to. This area has a history listing of recently sent messages. Messages sent to this channel may optionally be mirrored on other services such as IRC or Matrix.
- 1 Small Announcement: The top-right of the screen. May be used for player death messages or minor announcements.
- 2 Announcement: Above the center of the screen. Messages sent here disappear after 5 seconds.
- 3 Hotbar: The bottom-center of the screen, above the player's hotbar if it is visible. Messages sent here disappear after 5 seconds.
- 4 Timer: The top-center of the screen. The most recent message sent here displays permanently, until an empty or zero-length message is sent.
- 5 Client IPC: Used for transferring textual information between the server and client. This message type must never be relayed to other clients. This message area should be hidden by default.
- 6 Plugin IPC: Not visible to human players. Used by plugins and bot players to communicate with eachother and the server. This message channel should be used conservatively to avoid swamping clients with message packets.
- 7 System: Used for server maintenance/operator announcements or diagnostics. The client may also include its own diagnostic messages in this area.
- 8-127: These channels are implementation-defined. Clients should not display messages received in these channels by default.
struct 0b_message {
channel: u8, // 8th bit final chunk marker, 7 bits of msg channel
chunk_num: u16, // which chunk is being sent, in case of out-of-order
cookie: u24, // a unique identifier for the whole message
// so multiple message chunks can be sent in parallel
msg: [64]u8, // a chunk of plain utf-8 text, padded with
// 00 bytes if the chunk is < 64 bytes long
}
sizeof(0b_message) = 68
10 World Chunk
Sends the block data for a 8x8x8 world chunk. The data field contains an uncompressed block ID array and metadata array.
The lower metadata nibble contains a lightmap value for artificial lights. The upper metadata nibble contains the third nibble of the block ID.
The server can send this to replace an already loaded chunk rather than sending multiple 11 Set Block packets.
Clients may assume that unsent chunks are empty and filled with air.
struct 10_chunk {
x: i21, // chunk coordinate, these three fields are packed into 8 bytes
y: i19,
z: i21,
blocks: [512]u8,
meta: [512]u8,
}
sizeof(10_chunk) = 1030
11 Set Block
Sent by the client or the server to update a single block in a chunk.
The client should only directly send this packet if the server allows it with the 'Set Blocks Instantly' permission in the 20 Gamemode Settings packet.
struct 11_block {
x: i32,
y: i32,
z: i32,
block: u16, // only bits 1-12 are used
}
sizeof(11_block) = 14
12 World Effect
Sent by the server to create a special effect. Supporting this packet and its effects is optional. Clients not implementing this packet should still read this packet and ignore its contents.
Modes
- 0 Block Breaking Animation (data1,2,3 are block position, data4 is breaking progress from 1-8, 0 removes animation overlay)
- 1 Weather (see the 'Weather Effects' section below)
- 1 Block/Item Break (data1,2,3 are signed fixed point 24.8 object position, data4 is block/item ID)
- 2 Explosion (data1,2,3 are signed fixed point 24.8 object position, data4 is 24-bit RGB and a scale modifier)
- 3 Smoke (data1,2,3 are signed fixed point 24.8 object position, data4 is 24-bit RGB and a scale modifier)
- 4 Water Splash (data1,2,3 are signed fixed point 24.8 object position, data4 is 24-bit RGB and a scale modifier)
Weather Effects
- 0 Clear: Removes any currently active weather effects.
- 1 Start Day Cycle: The client starts automatically animating the sun moving through the sky. 'data2' is the time the client should start animating from. 'data2' is unsigned 0.32 fixed point, encoding fractions of one day rotation, starting and ending with the sun rising from the horizon.
- 2 Stop Day Cycle: The client stops moving the sun if it was already moving. 'data2' is the same as described in 1 Start Day Cycle.
- 3 Sky Color: 'data2' is an XRGB color for the daytime sky. 'data3' is an XRGB color for the nighttime sky. 'data4' is an ARGB color for dawn or dusk sky.
- 4 Light Color: 'data2' is an XRGB color for sunlight. 'data3' is an XRGB color for artificial lights. 'data4' is an XRGB ambient color for unlit areas.
- 5 Fog: 'data2' is an XRGB fog color. 'data3' is the fog density scale. 'data4' is an interpolation time, in 40 millisecond increments.
struct 12_world_effect {
mode: u8,
data1: u32, // may be signed or unsigned, depending on the value of 'mode'
data2: u32,
data3: u32,
data4: u32,
}
sizeof(12_world_effect) = 17
20 Gamemode Settings
Sent by the server to allow various cheats or gamemode tweaks on the client. The server should not implicitly assume the client will obey these settings.
Flags
- Bit 0: Invulnerable (also hides health/armor UI)
- Bit 1: Set Blocks Instantly
- Bit 2: Unlimited Items
- Bit 3: Allow Flight
- Bit 4: Allow No-clip (implies bit 1)
- Bit 5: Disallow Movement (gravity still applies unless bit 3 is set)
- Bit 6: Reserved
- Bit 7: Reserved
- Bit 8: Reserved
- Bit 9: Reserved
- Bit 10: Reserved
- Bit 11: Reserved
- Bit 12: Reserved
- Bit 13: Reserved
- Bit 14: Reserved
- Bit 15: Reserved
struct 20_gamemode {
flags: u16,
walk_speed: u16, // unsigned 8.8 fixed point multiplier
jump_height: u16, // ditto
gravity: u16, // ditto
}
sizeof(20_gamemode) = 8
Block IDs
A list of defined block IDs and their names. The IDs are written in hexadecimal. IDs not present on this list should be rendered on the client with a texture that makes it obvious the ID is unused.
This particular encoding for block IDs allows for better compression by storing two most significant nibbles of the block ID in one byte array, and the third least significant nibble and a lightmap value in a second byte array.
- 000 Empty/Air
- 010 Dirt
- 011 Grass-covered dirt
- 012 Leaves-covered dirt
- 013 Sand
- 014 Red Sand
- 015 Gravel
- 016 Mud
- 017 Clay
- 018 Mud Bricks
- 019 Clay Bricks
- 01A Tilled Dirt
- 020 Stone
- 021 Marble
- 022 Basalt
- 023 Obsidian
- 024 Iron, rendered as ore in-world and as an un-placeable iron lump item
- 025 Coal, rendered as ore in-world and as an un-placeable coal lump item
- 026 Ruby, rendered as ore in-world and as an un-placeable gemstone item
- 027 Olivine, rendered as ore in-world and as an un-placeable gemstone item
- 028 Sapphire, rendered as ore in-world and as an un-placeable gemstone item
- 029 Zircon, rendered as ore in-world and as an un-placeable gemstone item
- 030 Brown-barked Log, facing Y
- 031 Brown-barked Log, facing X
- 032 Brown-barked Log, facing Z
- 033 White-barked Log, facing Y
- 034 White-barked Log, facing X
- 035 White-barked Log, facing Z
- 036 Leaves
- 037 Leaves with Fruit
- 038 Vine
- 039 Grass Tuft
- 03A Small Bush
- 03B Brown-barked Sapling
- 03C White-barked Sapling
- 03D Dead Bush
- 03E Cactus
- 03F Water Lily
- 040 White Flower
- 041 Yellow Flower
- 042 Red Flower
- 043 Blue Flower
- 044 Red Berries
- 045 Black Berries
- 046 White Mushroom
- 047 Brown Mushroom
- 048 Orange Mushroom, attaches to the side of a block rather than the ground
- 049 Red Mushroom, poisonous
- 04A Dead Crops
- 04B Crops (04B-04F are height from 25% to 100%)
- 050 Freshwater (050-053 are height from 100% to 25%)
- 054 Swampwater (054-057 are height from 100% to 25%)
- 058 Seawater (058-05B are height from 100% to 25%)
- 05C Magma (05C-05F are height from 100% to 25%)
- 060 Wooden Planks
- 061 Wooden Fence
- 062 Wooden Planks Half-block, facing -Y
- 063 Wooden Planks Half-block, facing +Y
- 064 Wooden Planks Half-block, facing -X
- 065 Wooden Planks Half-block, facing +X
- 066 Wooden Planks Half-block, facing -Z
- 067 Wooden Planks Half-block, facing +Z
- 068 Pale Wooden Planks
- 069 Pale Wooden Fence
- 06A Pale Wooden Planks Half-block, facing -Y
- 06B Pale Wooden Planks Half-block, facing +Y
- 06C Pale Wooden Planks Half-block, facing -X
- 06D Pale Wooden Planks Half-block, facing +X
- 06E Pale Wooden Planks Half-block, facing -Z
- 06F Pale Wooden Planks Half-block, facing +Z
- 070 Rope, facing Y
- 071 Rope, facing X
- 072 Rope, facing Z
- 073 Chain, facing Y
- 074 Chain, facing X
- 075 Chain, facing Z
- 076 Ladder, facing -X
- 077 Ladder, facing +X
- 078 Ladder, facing -Y
- 079 Ladder, facing +Y
- 07A Ladder, facing -Z
- 07B Ladder, facing +Z
- 07C Unlit Firepit
- 07D Lit Firepit
Item IDs
A list of defined item IDs and their names. The ID is written in hexadecimal. Items that use the meta field will describe how they use it.
- 800 Stick, digs through dirt-like blocks slightly faster
- 801 Stone
- 802 Kindling
- 810 Sharpened Stone, meta is remaining sharpness; zero turns this item back into 801 Stone
- 811 Stone Axe, meta is remaining sharpness; zero makes tool slower
- 812 Flint Firelighter, requires kindling to start fire
- 813 Steel Knife, meta is remaining sharpness; zero makes tool slower and deal less combat damage