bzl

self-hosted ephemeral community engine
Log | Files | Refs | README | LICENSE

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`