MAPS_PLUGIN_CURRENT_BEHAVIOR.md (4670B)
1 # Maps Plugin: Current Behavior (As Implemented) 2 3 Last updated: 2026-02-22 4 Source of truth: `plugins_dev/maps/plugin.json`, `plugins_dev/maps/server.js`, `plugins_dev/maps/client.js` 5 6 ## What it is 7 8 `maps` is a first-party plugin that adds: 9 - A **Maps panel** (rack mode) or Maps tab flow (legacy mode) 10 - Multi-user map rooms with avatar movement 11 - Local/global map chat 12 - Optional walkie (push-to-talk short audio clips) 13 - Optional TTRPG tooling (sprites, props/tokens, possession, polygon editors) 14 15 Manifest: `plugins_dev/maps/plugin.json` 16 17 ## Core data model 18 19 Maps come from: 20 1. Built-in demo map(s) in code (`BUILTIN_MAPS`) 21 2. Custom maps persisted to disk at: 22 - `data/plugin-data/maps.json` 23 24 Per-map fields include: 25 - `id`, `title`, `owner` 26 - `backgroundUrl`, `thumbUrl` (restricted to `/uploads/...` or `/assets/...`) 27 - `world`, `avatarSize`, `cameraZoom` 28 - `collisions`, `masks`, `exits`, `hiddenMasks`, `occluders`, `fallThroughs` 29 - `ttrpgEnabled`, `sprites`, `props`, `walkiesEnabled` 30 31 Runtime-only room state is in memory (not persisted): 32 - Active users/positions 33 - Global map chat buffer 34 - Pending walkie playback acknowledgements 35 36 ## Permissions (current) 37 38 Current checks in plugin server code: 39 - **Create map**: `owner` or `moderator` only 40 - **Update/delete map**: `owner`, `moderator`, or map `owner` 41 - **TTRPG edits** (sprites/props/toggles): same map-management path 42 - Built-in maps are not editable/deletable via `updateMap`/`deleteMap` 43 44 Note: this plugin currently checks `owner/moderator` directly and does not yet include the new `admin` role in those permission gates. 45 46 ## Networking / WS events 47 48 The plugin uses WS events under `plugin:maps:*`. 49 50 Main inbound actions: 51 - `list`, `createMap`, `updateMap`, `deleteMap` 52 - `join`, `leave`, `move` 53 - `chatSend`, `chatHistoryReq`, `say` 54 - `setInvisible` 55 - `walkieSend`, `walkiePlayed` 56 - TTRPG: `ttrpgSetEnabled`, `ttrpgSpriteAdd`, `ttrpgSpriteRemove`, `ttrpgPropAdd`, `ttrpgPropMove`, `ttrpgPropPatch`, `ttrpgPropRemove`, `ttrpgTokenPossess` 57 58 Main outbound messages: 59 - `plugin:maps:mapsList` 60 - `plugin:maps:joinOk`, `plugin:maps:left` 61 - `plugin:maps:roomState`, `plugin:maps:userMoved` 62 - `plugin:maps:chatMessage`, `plugin:maps:chatHistory` 63 - `plugin:maps:bubble` 64 - `plugin:maps:walkie` 65 - `plugin:maps:mapPatched`, `plugin:maps:ttrpgEnabled` 66 - TTRPG delta messages for sprite/prop add/move/patch/remove 67 68 ## Chat behavior 69 70 Map chat has two scopes: 71 - `local` (default): delivered only to users within a normalized radius 72 - `global`: delivered to everyone in the room 73 74 Current server constants: 75 - `MAP_CHAT_LOCAL_RADIUS` default: `0.12` (env override `MAP_CHAT_LOCAL_RADIUS`, clamped `0.01..1.0`) 76 - `MAP_CHAT_GLOBAL_MAX` default history window: `200` messages 77 78 Global chat history is in-memory only (clears on server/plugin restart). 79 80 ## Movement, collisions, exits 81 82 - Movement is client-driven, with periodic position sends (`move`) 83 - Coordinates are normalized (`0..1`) 84 - Collision polygons block movement 85 - Exit polygons can: 86 - return user to Maps list (`toMaps`) 87 - transfer user to another map (`toMap`, optional target exit name) 88 89 ## TTRPG mode (current) 90 91 When enabled per map: 92 - Sprite library (uploaded images as `prop` or `token`) 93 - Placeable props/tokens with transform and z-order 94 - Token metadata: nickname, HP current/max, controller 95 - Token possession flow (`controlledBy`) 96 - Overlay/polygon editing for: 97 - collisions 98 - y-sort masks 99 - exits 100 - hidden masks (fog areas) 101 - fall-through zones 102 - occluders 103 104 ## Walkie mode (current) 105 106 - Push-to-talk UX (`Backquote` / hold-to-talk) 107 - Client records short audio with `MediaRecorder`, uploads to `/uploads/...` 108 - Server relays playback event with sender position for spatial mix 109 - Cleanup model: 110 - each walkie clip tracks pending listeners 111 - deleted when all listeners ack (`walkiePlayed`) or timeout (~2 min) 112 - server attempts to delete fresh upload file after cleanup 113 114 ## UX integration notes 115 116 - In rack layout, plugin registers panel id `maps` 117 - In legacy mode, maps view toggles within the main workspace flow 118 - On mobile, Maps is usually treated as secondary/optional due to viewport constraints 119 120 ## Current limitations / known behavior 121 122 - No built-in turn/initiative/combat engine; tools are positioning + token control only 123 - Chat in map context is text+bubble (plus optional walkie clips), not full RTC voice rooms 124 - Global map chat and room presence are ephemeral in memory 125 - Permission model is still owner/mod oriented (not yet fully aligned with owner/admin/mod hierarchy) 126 127 ## Build & packaging 128 129 - Dev source: `plugins_dev/maps/` 130 - Build script: `scripts/build-maps-plugin.js` 131 - Zip output: `dist/plugins/maps.zip`