8.6 KiB
8.6 KiB
Protocol Notes
This is a behavior guide for packet semantics beyond raw schemas.
Direction
- Client packet schema lives in
server/app/models.py(ClientPacket). - Browser-side validation/parsing lives in
client/src/network/protocol.ts. - Keep these synchronized on every protocol change.
Client -> Server
auth_register: create account with username/password and optional email.auth_login: authenticate with username/password.auth_resume: resume prior session via stored session token.auth_logout: revoke current session and disconnect.admin_roles_list: request server role list (with user counts + permission sets).admin_role_create: create role.admin_role_update_permissions: replace one role permission set.admin_role_delete: delete role with replacement role reassignment.admin_users_list: request user list for admin actions (action:set_role | ban | unban).admin_user_set_role: set target user role.admin_user_ban/admin_user_unban: disable/enable user account.update_position: client movement intent; server enforces world bounds and movement rate policy.teleport_complete: client signals teleport landing; server rebroadcasts spatial landing cue.update_nickname: nickname change request (server enforces uniqueness).chat_message: player chat.ping: latency measurement.item_add,item_pickup,item_drop,item_delete,item_use,item_update: item actions.item_secondary_use: trigger type-specific secondary action when implemented.item_piano_note: realtime piano note on/off for active piano use mode.item_piano_recording: piano record/playback control (toggle_record,playback,stop_playback).
Server -> Client
auth_required: authentication challenge after websocket connect.auth_result: auth success/failure and session/account metadata.auth_permissions: server-pushed live role/permission refresh for current session.admin_roles_list: role list response payload.admin_users_list: user list response payload.admin_action_result: structured result for admin actions.welcome: initial snapshot with users/items plus server UI/world metadata.signal: forwarded WebRTC offer/answer/ICE.update_position,update_nickname,user_left: presence updates.teleport_complete: peer teleport landing event with spatial coordinates.chat_message: system and user chat stream.pong: ping response.nickname_result: accepted/rejected nickname result.item_upsert: full item replacement after mutation.item_remove: item deletion.item_action_result: action success/failure and user-facing message.item_use_sound: spatial one-shot sound on successful item use (ifuseSoundconfigured).item_clock_announce: ordered list of clock speech samples to play sequentially as spatial audio.item_piano_note: broadcast piano note on/off with resolved instrument/envelope/spatial params.item_piano_status: structured piano mode/record/playback state events for client runtime control.
Item Packet Behavior
item_upsertis full-state replacement for one item, not partial patch.item_upsert.item.displayis server-owned display text for readonly/system properties (for example:createdBy,updatedBy,createdAt,updatedAt,capabilities,useSound,emitSound).item_action_resultmessages are intended for direct screen-reader/user status feedback.- Successful
item_pickupanditem_dropalso emit system chat lines to other users in the room. - Piano runtime control no longer depends on parsing
item_action_result.messagetext. item_piano_statuscarries machine-readable piano events (use_mode_entered, record/playback transitions).item_use_soundcontains absolute item world coordinates (x,y) and sound path.- For carried items, source coordinates resolve to the carrier's current position.
item_clock_announcecontains:itemIdsounds: ordered sample URLs (EL640 phrase parts)- absolute source coordinates
x,y - generated by server for manual clock
use, top-of-hour auto announce, and alarm auto announce (when enabled)
teleport_completecontains absolute player world coordinates (x,y) at teleport landing.- Radio metadata (
params.stationName,params.nowPlaying) is server-managed and delivered through normalitem_upsertupdates. item_piano_notecontains:itemId,senderId,keyId,midi,on- resolved
instrument,voiceMode,octave,attack,decay,release,brightness,emitRange - absolute source coordinates
x,y
Welcome Metadata
welcome.auth: authenticated account identity:authenticateduserIdusernamerolepermissionspolicy(usernameMinLength,usernameMaxLength,passwordMinLength,passwordMaxLength)
auth_required.authPolicy: server auth limits advertised before login/register submit.auth_result.authPolicy: server auth limits echoed on auth success/failure responses.welcome.worldConfig.gridSize: server-authoritative grid size used by clients for bounds/drawing.welcome.worldConfig.movementTickMs: server movement-rate window used for client movement pacing.welcome.worldConfig.movementMaxStepsPerTick: max allowed grid steps per movement window.welcome.player: server-assigned spawn/current self position at connect time.welcome.serverInfo: server process identity/version metadata:instanceId: unique id generated at server startupversion: server package version (orunknownfallback)
welcome.uiDefinitions: server-provided item UI definitions:itemTypeOrder: add-item menu orderitemTypes[].tooltip: item-level tooltip/help textitemTypes[].capabilities: server-declared actions supported by the typeitemTypes[].editableProperties: editable property keys by item typeitemTypes[].propertyMetadata: property-level metadata (valueType, optionallabel, optionalrange, optionaltooltip, optionalmaxLength, optionaloptions, optionalvisibleWhen)itemTypes[].globalProperties: non-editable global values (useSound,emitSound,useCooldownMs,emitRange,directional,emitSoundSpeed,emitSoundTempo,emitLoopDelay)adminMenu.actions: server-authored admin root menu labels/ordering for the authenticated user.
- Client item UI requires this metadata from the server; there is no fallback item definition map.
- Client property help/type rendering is metadata-driven; it does not infer fallback types/tooltips from hardcoded key heuristics.
visibleWhensupports equality checks and string negation via!prefix (example:{"mediaEffect": "!off"}).
Validation Boundaries
- Server is authoritative for all action validation and normalization.
- Server is authoritative for movement acceptance (bounds + rate/delta checks).
- Server persists account state (last nickname + last position) and restores spawn from that state on auth login/resume.
- Server applies auth hardening before accepting login/register/resume:
- login/register PBKDF2 work runs off the event loop in bounded worker concurrency
- repeated auth failures are rate-limited by IP and IP+identity windows
- auth failures include small randomized response jitter to reduce high-resolution probing
- Client validates incoming packet shapes and applies runtime behavior.
- Server is authoritative for role/permission checks on every privileged packet.
voice.sendpermission changes are pushed at runtime viaauth_permissions.- Sound/media field normalization uses shared server policy helpers:
none/offnormalize to empty values- bare filenames normalize to
sounds/<name>for sound-reference fields - media URL-like fields are trimmed/validated consistently
- Client-side item edit validation is convenience only; server remains source of truth.
Heartbeat/Stale Recovery
- Client sends automatic heartbeat
pingpackets every 10 seconds while connected. - Heartbeat pings use negative
clientSentAtids and are internal (not user-visible ping status). - If websocket close is observed unexpectedly, client starts reconnect flow.
- If a heartbeat
pongis missed for one interval (10 seconds), client also starts reconnect flow. - Reconnect flow waits 5 seconds and retries up to 3 times before stopping.
- After reconnect, if
welcome.serverInfo.instanceIdchanged, client announcesServer restarted. - Client emits
Connected to server. Version <version>.on initialwelcomeandReconnected to server. Version <version>.after reconnect. - If
welcome.serverInfo.versiondiffers from running client version, client auto-reloads.