This guide documents the CRUD command suite that manages runtime world data in
MongoDB through transport-neutral services and repositories.
The separate web administration workspace
also manages stored configuration with its own web identity, explicit write
opt-in, concurrency checks and audit history. Its map is the effective stored
creation map, never a replacement for live BC observations. Live capture
(world map save) remains a bot-only operation.
The feature configuration catalog
lists all feature configuration owners, startup defaults, and command sequences.
Room-scoped runtime heartbeats expose actual consumer receipts in the web
recovery runtime panel, not an inferred consequence of an administrative save.
GameConfigRuntime.apply() reports the revision/time installed in the shared
cache only. It does not prove any game or session has adopted that revision.
Aliases are separately pending until the next alias/help lookup replaces their
lazy cache; validation errors report a fixed identifier and leave the prior
successful receipt visible while aliases fail closed.
The serialized room-template reload reports only after installing the new creation definition. Its revision remains unknown because this projection has no authoritative aggregate revision. It affects the next missing-room creation, never the existing room. A failure still disables creation; the last-loaded receipt remains historical. Watch/load errors use fixed identifiers rather than messages or configuration content. Running door/location replacements are reported separately by the door plugin, also without an invented aggregate revision. Casino, shop, Location Entry Behavior and shower also publish bounded feature receipts; their guides describe the exact interaction/session coverage. Truth/Dare, Hot Seat, Dilemma and Anonymous Whisperer report a dedicated configuration revision only after a new active session is successfully created. Those receipts do not infer that a revision came from defaults, or describe every active session. Appearance reports a validated itemset selected for an application attempt, without claiming that BC observed it; itemset revisions are not aggregated. A helper worker reports readiness only after identity preparation and settings load, but those settings have no revision or default provenance; supervisor task handling remains unknown. The runtime view compares only consumers using the same process-local shared-config revision. Casino and interaction-driven feature changes do not rewrite every existing session. Uninstrumented consumers remain unknown.
Older heartbeats without consumer receipts remain readable and report unknown. Process freshness is displayed independently; even recent successful receipts are not live BC observations.
LocationAdminService.Type and Fog), and manage map revisions/backups through
MapAdminService and MongoMapAdminRepository.GameConfigAdminService, MongoGameConfigRepository, and
GameConfigRuntime.prototypeRoomConfig
revisions. The Admin-Map Room settings wizard creates the initial
revision, edits settings, restores earlier revisions, and deletes the active
override by appending the legacy template as a new revision. History is
retained; the supervisor reconciles the latest version at startup through
ApplyRoomSettingsAction. This is separate from the world command suite,
stored map history, and the BC_ROOM environment setting.GuidedSessionManager without coupling to BC-specific payload types.Room admins also manage the opt-in shower feature’s room-scoped settings and song catalog. Runtime behavior and the dedicated-account qualification gate are documented in the shower system guide.
The BC adapter lives in
src/features/world/commands/world-admin-command-suite.ts; shared rules stay
in feature services so future channel adapters (for example Discord) can call
the same use cases with channel-specific authorization.
All commands require room-admin access and reply by private whisper. Permissions are checked again for every guided answer/control and before completion; revoking admin access cancels the active session without a write. Long replies are split into ordered whispers of at most 1,800 characters, preserving lines and Unicode characters where possible rather than failing BC’s message-length guard.
World command descriptors are included in shared help only for a current room
admin. Non-admins receive the same neutral private response for /bot world help
as for an unknown world scope; guided-session prompts and command execution
continue to enforce room-admin authorization independently.
world location listworld location show <key>world location createworld location edit <key>world location delete <key> confirmworld config showworld config set <key> <value>world config unset <key>world config show room <roomKey>world config set room <roomKey> <key> <JSON value>world config unset room <roomKey> <key>world shower showworld shower set <enabled|stepDelayMs|singDelayMs> <value>world shower song listworld shower song add <id> | <title> | <text>world shower song edit <id> | <title> | <text>world shower song enable <id>world shower song disable <id>world alias add <name> <target> [fixedArgs=<words>]world alias remove <name>world alias listworld config set (guided flow)world map showworld map save (snapshot the synchronized live BC map)world map revisions (newest 10)world map edit (guided flow for map type + fog)world map backup [note]world map backupsworld map restore <revision> (append a copy of that revision)world map restore-backup <backup-id> (the previous backup-restore operation)world answer <text>world backworld skipworld cancelUse native /bot <command> or bang-prefixed !<command>. For example:
/bot world config set
/bot world answer game.speed
/bot world answer 2
/bot world alias add spin casino slots fixedArgs=10
/bot world alias list
/bot world shower show
The shower feature starts disabled and has no seeded songs. Add only
administrator-provided original or public-domain text; song text is not shown
by world shower song list. A location must be an enabled point with type
shower. Runtime clothing changes require a positive BC wardrobe permission
result and accept matching BC room updates as sufficient observation, without
independent helper corroboration; see the
shower guide before enabling it.
Quote two-word alias names, for example
/bot world alias add "red bet" casino roulette bet. Alias targets must be
registered help command paths; sensitive targets are rejected. Admin-only
targets are allowed, but the target command still performs its normal permission
check. Invalid aliases receive a reply that identifies the rejected rule or
target. fixedArgs is inserted before the arguments supplied by the player.
Aliases can be invoked with either !<alias> or native /bot <alias> syntax.
The parser routes real command paths first, performs only one alias expansion,
and applies the target’s ordinary permissions, location checks, and rate limits.
The room-scoped command.aliases key is seeded with bet → casino roulette
bet, slots → casino slots, and balance → casino balance only when
absent. Updates are validated against the live help catalog, revision-checked,
and applied through the existing prototypeGameConfig change stream. Removing
the key disables aliases until the next startup re-seeds the starter set.
Scoped help lists shortcuts only beside currently visible target commands;
fixed argument values are not displayed. A target removed from the live command
catalog becomes unknown without disabling other aliases.
Each guided flow asks one question at a time. Reply with
/bot world answer <text>; the final answer saves automatically. world back
revisits the previous answer. world skip is available only for optional
steps: it keeps the current value when editing, or leaves an optional field
unset when creating. world cancel discards the session. Starting another
flow replaces the previous session; sessions expire after five minutes of
inactivity.
Location edits accept none to clear position, label, or description. Map fog
accepts yes (enable), no (disable), or clear (remove the setting).
Configuration keeps the existing global scope and adds explicit room scopes; a
room lookup never falls back to global settings. The singleton
prototypeGameConfig active document uses optimistic revision checks. Every
successful update after the initial write transactionally stores the replaced
revision as a backup:<revision> document in the same collection; a conflict or
failed backup leaves the active configuration unchanged. Backups have no
automatic pruning or TTL and are not included in the configuration-copy
allowlist. These writes require MongoDB transaction support (a replica set).
Each scope is limited to 200 keys; structured values are bounded JSON (16 KiB
per value, 256 KiB total document, depth 8, bounded arrays/objects). Plain text
remains limited to 500 bytes. Feature consumers validate their own strict,
versioned schemas before using a stored value. Never enter passwords, access
codes, or other secrets.
For example, create a point location with type game, then bind its key through
the casino rules value. The current guided location command does not create
region geometry; an enabled roulette region must be operator-defined in
veratownLocations before binding. The game remains unavailable unless the
main bot also observes the sender inside the enabled location:
/bot world config set room main casino.rules {"schemaVersion":1,"entryGrant":{"chips":20,"intervalMs":86400000},"locations":{"slots":[{"key":"casino-slots","shape":"point"}],"roulette":[{"key":"casino-floor","shape":"region"}]},"slots":{"symbols":["🍒","🍏","🍌","🍑","💎","7️⃣"],"weights":[35,25,18,12,8,2],"fourKindQuarterUnits":[4,4,4,4,400,2000],"threeKindQuarterUnits":[4,4,4,4,60,200],"twoPairsQuarterUnits":5,"pairQuarterUnits":4,"fourFruitQuarterUnits":4,"bettingWindowMs":10000,"resultWindowMs":5000,"renewalWindowMs":5000,"maxPlayers":20,"maxWager":100},"roulette":{"payouts":{"straightUp":36,"split":18,"street":12,"trio":12,"corner":9,"fourNumber":9,"sixLine":6,"evenMoney":2,"dozen":3,"column":3},"bettingWindowMs":45000,"resultWindowMs":10000,"renewalWindowMs":5000,"maxPlayers":20,"maxWagers":1000,"maxWager":100}}
/bot world config show room main
The write reply and subsequent show report the active document revision.
Casino-specific fields, supported games, payout ceilings, slot return, timing,
participant/wager limits, and location shapes are validated before an admin
write is persisted. An invalid
or global casino.rules write is rejected without changing the current
revision. Valid room config changes apply live; a started game round retains its
saved rules snapshot and revision.
MongoMapRepository.watchRuntimeConfiguration flow and applied live by the
running map plugin.GameConfigRuntime.apply, and
cross-process writes are observed via the prototypeGameConfig change stream.
The runtime exposes global values and explicit room-scoped values separately;
schema validation belongs to the consuming feature and is also applied to
supported admin writes. Keys affect behavior only when an implemented feature
consumes them.MongoRoomConfigRepository appends versioned settings
to prototypeRoomConfig. Admin-Map creates the first revision from the
legacy template, updates and restores by appending revisions, and deletes the
active override by appending that template as a new revision; no history is
physically deleted. If no revision exists, the supervisor imports the
synchronized room as the baseline so existing BC role/member lists are
preserved. Each supervisor process startup applies the latest revision with
ApplyRoomSettingsAction and requires a matching room sync. Admin-Map writes
do not update a live room immediately; the room-settings change stream
refreshes the missing-room creation template, and existing-room settings are
reconciled on the next supervisor startup. BC_ROOM and stored map data are
managed separately.veratownMap.
Startup and administration use the same reader, selecting the highest revision
for the room. Local writes await a creation-template refresh; the world plugin
watches veratownMap and veratownRooms for external changes, while the
composition root watches prototypeRoomConfig. Reloads are serialized and
watchers are closed at shutdown. Change streams require a MongoDB replica set;
stream errors are reported, not treated as successful refreshes.
The live BC room is unchanged. Only creation of a missing room uses the template;
rejoining an existing room never applies stored maps.
Plug-in startup rolls back the map watchers and game-config runtime if template
loading or command registration fails; reverse-order cleanup attempts every
disposer even if an earlier watcher fails.The shared mapDataSchema validates live saves, selected stored maps, revision
and backup reads/writes, configuration copies, and missing-room templates.
Its optional CellData field is a plain record with at most 1,600 entries:
x + y * 40); leading zeroes,
whitespace, signs, fractional/exponent forms, and prototype keys are invalid.{ Type: "Sign", Text: string } or a strict
Teleporter configuration described below. Unknown config types and extra
fields reject the entire operation.Signs survive save, metadata edit, backup, both restore forms, template refresh, and missing-room creation. These operations do not apply stored maps to an existing live room. Invalid selected heads, revisions, and backups fail explicitly; the reader never skips a corrupt head to use an older revision or legacy fallback. Validation replies expose bounded schema fields/cell indices only, never sign text. Sign configuration is authorized map data, not captured chat; do not log, journal, or echo its contents. There is no new sign-editing command or storage migration.
Before deploying, obtain separate approval for a read-only existing-sign audit. Report only counts and lengths, not content. Stop rollout for signs above the 150-code-unit policy and resolve the conflict explicitly. Live Unicode rendering, save/restore, room creation, door updates, and reconnect still require separately approved qualification on the actual BC version. Offline tests are not that evidence.
On 2026-10-15, the operator reported that all of these checks passed on R133Beta2 in test context “Personal Commit”: browser/server version, Unicode/newline sign rendering, live save and stored restore, missing-room creation, unrelated door updates, reconnect, and the existing-sign length audit. The exact build and room/environment were not supplied, and the assistant did not independently observe the run. This is not deployment approval or qualification of unrelated features. Confirm that the report applies to the intended build and target before release; the dated archived proposal retains the evidence and its limitations. The current source pin is R133; this historical report does not qualify the updated client behavior.
flowchart LR
BC["Pinned BC declarations + observed MapData"] --> Schema["Shared strict mapDataSchema"]
Admin["WorldAdminCommandSuite"] --> Service["MapAdminService"]
Service --> Schema
Service --> Repo["MongoMapAdminRepository"]
Repo --> Revisions[("Append-only map revisions")]
Repo --> Backups[("Map backups")]
Repo --> Reader["Validated effective-map reader"]
Reader --> Template["Missing-room creation template"]
Door["Guarded SetMapObjectAction"] --> BC
Door -. "preserves unrelated CellData" .-> BC
The schema treats sign CellData as validated configuration, not chat or live
state. Save validates the server-observed map before append; metadata edits and
restores carry the complete validated map forward. Door mutations preserve
unrelated map cells and observed state changes only on inbound room sync.
Older code can silently discard signs. Before rollback, suspend map save, edit, backup, and room recreation; retain the new documents unchanged. Previously discarded text cannot be recovered from those old revisions.
At source pin 51df6acc01f8fa185079d8deebf591fe3642a148 (still R133), map
CellData also accepts { Type: "Teleporter" } with optional:
Destination: strict { X, Y } integer tile coordinates, each 0-39.Color: hexadecimal string matching upstream CommonIsColor with alpha
enabled: #RGB or 6-8 hexadecimal digits after #, case preserved. The
seven-digit form is accepted because the pinned upstream validator accepts it.Shared: boolean; absence and explicit false are preserved unchanged.Destination absence is valid. No defaults, automatic pairing, destination walkability checks, or browser teleport callbacks are applied by the bot. Dormant cell configuration remains intact regardless of the object at that index. All entries must validate before saving, restoring, copying, or creating a room; invalid fields reject the entire operation with redacted diagnostics.
Sign and teleporter entries coexist and survive the same revision/backup and room-creation flow shown above. Guarded unrelated door updates preserve them. The bot does not infer a live move from a configured destination. Qualify pad appearance and native movement separately on the intended BC build; offline preservation tests do not certify the browser behavior.
Older sign-only validators reject teleporter-bearing documents. Before rollback, suspend map administration and room recreation, retain backups, and resolve compatibility explicitly rather than stripping pad configurations. See the 2026-10-22 source review.
The current source-pinned map catalog contains 372 objects and retains upstream
DeprecatedID replacement references, editor-only PaletteImage labels, and
the CanBeTetherPoint capability flag. These are catalog metadata only: the
bot does not migrate stored map cells, execute BC editor callbacks, or manage
tethers. Previous R133 category-specific Blank door
references remain valid and retain their former numeric IDs; the current map
catalog represents those cells as EmptySpace/Passable. See the
2026-11-03 source review.
The deprecated EmptySpace/Passable aliases all point to canonical map object
ID 100; style/type lookups select that canonical entry. Other ambiguous map
styles still require an explicit type or are rejected.
/bot world map save
/bot world map revisions
/bot world map show
/bot world map restore 1
save requires a connected, synchronized bot in its configured room. It clones
only the validated BC-observed MapData; stale/disconnected snapshots, another
room, missing maps, and malformed 40x40 maps are rejected without a database
fallback. Current objects include temporarily open doors: close doors before
saving if the stored creation map should show them closed.
The first save is revision 1. Every save/edit/restore inserts a new document with
a higher revision; existing documents are never overwritten. Restoring revision
1 when revision 3 is current creates revision 4 with restoredFromRevision: 1.
Backups still snapshot stored map data, not the live room; backup restore also
appends a revision. The old restore <backup-id> spelling now gives guidance to
use restore-backup; numeric restore arguments refer only to revision numbers.
Opening or cancelling an edit is read-only. Edit drafts retain the selected
revision: if another writer advances it before completion, nothing is written
and the admin is asked to restart the flow. A partial unique (roomKey, revision)
index excludes legacy documents and rejects concurrent revision allocation;
there are no blind retries. A lost insert response is reconciled by operation
identity before reporting success or conflict.
Without revision documents, legacy main, then current, then the room-template
map remains the fallback (main-room scope only). Legacy documents need no backfill
and are preserved. A corrupt/duplicate highest revision fails explicitly rather
than silently choosing an older revision. Failed template reloads disable
missing-room creation until a valid reload or restart; they never mutate the
observed room. If a write persisted but refresh failed, the reply distinguishes
that outcome and warns against repeating the save.
flowchart LR
BC[BcClient current-connection map observation] --> Service[MapAdminService]
Commands[WorldAdminCommandSuite] --> Service
Service --> Port[MapAdminRepository port]
Port --> Mongo[MongoMapAdminRepository append-only revisions]
Mongo --> Reader[Shared effective-map reader]
Reader --> Template[Missing-room creation template]
Mongo --> Watch[WorldAdminPlugin owns map/room watchers]
Watch --> Reader
LocationAPI[Core LocationAdministration API] --> Commands
Future Discord adapters reuse these services and transport-neutral actor IDs, but must independently check guild/role permissions. No Discord dependency or adapter is introduced here.
prototypeGameConfig: single revisioned document (_id = "main") with global
settings and optional room-scoped settings, plus immutable backup:<revision>
snapshots of replaced revisions. Backups are transactionally paired with the
active-document update and have no automatic pruning/TTL.prototypeMapBackups: stored-map snapshots for operator restore, optional
sourceRevision. No automatic pruning/TTL.prototypeRoomConfig: immutable room-scoped BC settings revisions with a
unique (roomKey, revision) index. No automatic pruning/TTL; Admin-Map shows
the newest 50 revisions and restores by appending another revision.veratownMap: legacy definitions plus append-only revision documents:
string _id, schemaVersion: 1, roomKey, positive safe-integer revision,
validated mapData, BSON Date createdAt, source (live_save,
metadata_edit, layout_edit, revision_restore, backup_restore, or
snapshot_restore), optional
{ transport, actorId } actor and restoredFromRevision.
Indexed selection and a partial unique revision index are initialized before use.
History has no automatic pruning/TTL; retention is operator-managed.The configuration-copy allowlist is unchanged. Revision documents are validated
before 1:1 upsert; IDs, room scope and revision numbers are not remapped.
Destination-only history remains intact; conflicting revisions fail against
the unique index. Review the dry run before --apply, especially when copying
between databases that already have independent histories.