1. In numbers
| Rust | about 49.6k lines of source and 2.7k of tests and benches (2026-10-06): client 32.7k (app.rs 4.5k, scene.rs 3.8k, gfx.rs 2.2k, sfx 4.9k), server 9.0k, protocol 5.8k, race 1.4k, props 0.7k, loadgen 0.2k |
| Content | 23 rooms (15 on the world grid: lobby, street, atrium, geode, central, skatepark, stadium, grid, court, spindizzy, bomber, tower, deck, skybar, roof; 8 behind portals: llm, lexicon, prairie, market, lab, bazaar, disco, basement), 48 object kinds, 52 looks, 59 sounds plus the SID and the disco's machine, 5 race tracks, 10 sceneries (Off included), 3 race themes, 16 bar menu items |
| Tests | about 215 #[test]s: client 84, server 66, protocol 47, race 9, props 9, loadgen 0. Also 3 benches, roomcheck, log_growth and two ignored tests that render the SID and the disco to WAV |
| History | 91 commits since 2026-09-30 |
2. What exists
Each line: what it does and where it lives. Solid means tested and used for a while. Working means it runs and was checked by hand or in a headless browser, but has thin tests. Fresh means built in the last day or two.
World and people
- Rooms as actors solid. One tokio task per room, a bounded inbox, an allocation-free move broadcast, a token bucket that also charges for path search, and A* with a budget.
server/src/room.rs,tests/alloc.rs. - World grid, seams and neighbours working. You see and walk across seams, with hand-offs, neighbour bands and light that reaches into neighbours.
server/src/world.rs,rooms/world.ron. No tests at all. - Floors, stairs, raised and sunken areas solid.
protocol::FloorPlanis shared by server and client.server/tests/floors.rshas 16 tests. - Residents and the bartender working. NPCs that wander and sit, and a bartender with a menu, servings and buzz effects.
room/residents.rs,room/bartender.rs,client/src/buzz.rs. - Props and balls solid. Deterministic shared physics, golden-hashed for native and wasm.
props/. - Builder editing and access keys working. An HMAC session cookie, a same-origin check, and edits gated per connection.
server/src/auth.rs. - Event log solid. DuckDB on a single writer thread, a separate loader, snapshots, and a Parquet archive.
server/src/eventlog.rs.
Games and things to do
- Race working. Server-authoritative ships with the same code predicting on the client, rivals drawn in the present, an adaptive input queue, weapons, AI, 5 tracks and 3 themes (press T).
race/,server/src/racing.rs,client/src/race_view.rs. - Disco working. Three stations each held by a player, notes made from the knobs on every client, dancing, speakers and eyes blown out by the kick. Since 2026-10-05/06: eight editable drum patterns, a bar, lights on the beat, and the music synthesised by the engine's machine with a DJ mixer and an 80s chain (fresh).
client/src/disco.rs,app/disco.rs,server/tests/deck.rs. - Book box working. Durable LIFO links, by drag and drop or
/drop.app/books.rs,server/tests/books.rs. - Half pipe fresh. A pad in front of a sunken pit, presses judged on the client and scored on the server, run after run with a durable board.
protocol/src/skate.rs,server/src/room/skate.rs,client/src/app/skate.rs,rooms/skatepark.ron. - Transfer game (fresh, 2026-10-04). Paradroid's transfer on Deck 1's floor, player against player: wiring from a seed, shots checked and the match settled on the server, the board drawn from seed and shots on every client, a durable winners' board and droid badges. Against residents, and transfers as a way to take things over (IDEAS.md), are not built.
protocol/src/transfer.rs,server/src/room/transfer.rs,client/src/app/transfer.rs,rooms/deck.ron. - Games on the floor fresh (2026-10-05/06). Football in the stadium, light cycles on the grid, breakout on the court (one player or two taking turns), Scramble on every arcade cabinet, Spindizzy's marble, Bomberman for one to four with predicted walking. Each one's rules in
protocol, played by its room, with a board.protocol/src/{football,cycles,court,dizzy,bomber}.rs,server/src/room/*.rs,client/src/app/*.rs,client/src/scramble.rs. - Commando fresh (2026-10-06). An endless lockstep battlefield on a sunken sand table in the basement: the room steps the same deterministic game from the runner's inputs, so it keeps the score; onlookers watch live; the table plays itself when idle.
protocol/src/commando.rs,server/src/room/commando.rs,client/src/commando_view.rs,scene/commando.rs. No server-side integration test yet. - Kobold fresh (2026-10-06). A coding game after EXAPUNKS in the boiler room under the basement: up to four at terminals write kobolds that walk a network of hosts on a sunken machine floor; eight jobs, a submission scored over 100 cases off the room task, the best cycles, size and activity on a
#koboldboard. Duels (Study B) in three arenas, RING, CROSS and LINE: spar against the house kobold, save a champion, challenge another nick's champion, or play a live duel after five minutes of writing; challenges and live duels are rated, Elo per nick and arena, on a#duelboard. Relay (Study C) on four production lines, from BAR TAB to THE POST: a station per seat, Save swaps a station in a few cycles ahead, three-minute shifts scored right minus wrong, each crew's best per line on a#relayboard. Live wire (Study D): a rig of 32 lamps over the floor that lights the room, beating to the disco's tempo; in free play each queued show plays a minute for everyone and the last runs on; three set pieces, PATTERN, CHASE and BINARY, tried in your own view only and checked by the room, the smallest solutions on a#showboard. All four studies are built.protocol/src/kobold.rs,server/src/room/kobold.rs,client/src/kobold_view.rs,scene/kobold.rs. - The lexicon fresh (2026-10-06). Every word said there that GloVe knows grows a tree, folded by the room's own principal axes.
server/src/words.rs,room/lexicon.rs,client/src/lexicon_view.rs. - The tower working (2026-10-04). A landmark skyscraper, a plaza, a lift corkscrewing up to the sky bar and the roof, a paternoster.
protocol/src/{tower,lift,paternoster}.rs. - Run mode fresh. Shift+click or a double click runs; every walk carries its pace.
protocol/src/walk.rs. - Model room working. A tiny transformer trained on the docs' trigrams, streaming tokens and its attention onto the wall.
server/src/llm.rs,client/src/llm_view.rs. - Keyword billboards working.
#latency,#server,#clients,#departures,#skate,#transfer, and since then#score,#cycles,#breakout,#dizzy,#bomber,#commando,#kobold,#duel,#relayand#show.latency_view.rs,server_view.rs. - Pings, emotes, a peer latency mesh and touch controls working.
- Usability pass (fresh, 2026-10-04):
- Settings as
key=value(client/src/saved.rs), which fixes FINDINGS APP-1 to APP-4. New settings: Text size, High contrast, Reduce motion. - A key cheat-sheet (
?); edit keys only in edit mode; Ctrl+Z undo; hover hints; a people menu and following; reading things up close. - Echoes, quiet rooms, groups, letters, paper planes, the world map (
N), teleporters and tubes, proximity voice (client/voice.js). - Touch context buttons; a shared status-line column; a fault banner with reload and copy; mentions; refusals and rate limits said out loud.
- The transfer opponent's cursor and spectator line; half pipe sounds of its own.
- Code:
server/src/room/social.rs,client/src/app/social.rs,app/voice.rs,app/undo.rs.
- Settings as
Look and sound
- Renderer solid core, many options. wgpu on WebGPU or WebGL2: beams and fills, six shader looks and 52 profiles in all, vertex, edge and face themes (10, 11, 12), line weights, a light volume, GI traced on WebGPU, shadows, reflections, phosphor, shafts, photo mode (lighter while moving, at its best when still, the whole world on request), boss mode, an Auto quality governor and ten sceneries. Dynamic fills since 2026-10-06, for the Commando battlefield and the Kobold floor.
client/src/scene.rs,gfx.rs,light.rs,look.rs,*.wgsl. - Characters working. Rigged templates with gestures and quirky parts (bobblehead, googly eyes, mittens).
- Sound working. The client's own wasm instantiated a second time inside an AudioWorklet, patches as
.sndtext, held voices, buses and ambience beds.client/src/sfx/,sfx-worklet.js. Pinned by voice goldens. Since 2026-10-06 two sources in code: a SID (sfx/sid.rs) and the disco's machine (sfx/machine.rs), each with its own tests (fresh).
Transport and operations
- WebSocket, then WebRTC data channels working. A reliable channel for the room and an unreliable one for the race, with barrier messages.
server/src/rtc.rs,client/src/app/rtc.rs. - Docs served at
/docsworking. The handbook, technical design, platform page, engine log and this waypoint. - Deploy configs working. Docker (built and smoke-tested), compose with Caddy TLS, helm and kustomize. The configs still carry no secrets; see §4.
- Linux working.
.gitattributeskeeps every text file LF. check.sh, dev.sh, shellcheck, the CDP scripts (Chromium, SwiftShader without a GPU) and the Python skill tools pass in arust:1.99-bookwormcontainer. - Tooling working.
scripts/check.sh(clippy for both targets, every test suite, every room throughroomcheck),scripts/dev.sh,loadgen,roomcheck, and theroom-from-imageandlook-from-imageskills.
3. Pitfalls: things that bite, and how
These are traps for whoever works on the code next, not bugs.
- Hand-mirrored layouts.
CameraUniform(304 bytes since the line weights),Line(64),Instance(80), anim codes, rig consts,GiParams,PhotoandGradelanes are all mirrored by hand between Rust and WGSL. Get one wrong and the geometry comes out scrambled with no error. Nothing asserts the sizes, and the comments disagree with each other (gfx.rs:10 and scene.wgsl:4 say 240, the HTML docs 272, CLAUDE.md both 48 and 64 forLine). Addconst _: () = assert!(size_of::<…>() == …)assfx/parse.rsdoes. - Lists of the same thing in several places. Object kinds live in
ObjectKind::ALL,props::height,light.rs(emits and solid),affects_lightin app.rs (drifted),sight.rslights (drifted),scene.rsdispatch,roomgen.pyKINDS(missing HalfPipe),preview.pyCOLOURS(missing 10 kinds) and the handbook's KINDS (missing 6). Every new kind touches about 15 files: the book box took 15 and the half pipe about 25. - Event kinds in SQL strings.
EDIT_KINDSandHISTORY_KINDSare hand-written, and no test ties them toEvent.skateis in neither, on purpose (the board reads it), so it is never archived and grows forever. - Shared timing needs both sides rebuilt together. Props, race physics, skate timing and disco notes change for everyone only once server and clients run the same build. Clients do not reconnect on their own (
app.rs:1019, "reload to rejoin"), so a deploy strands everyone until they reload. - Secure context. AudioWorklet, WebGPU and
crossOriginIsolatedneed https or localhost. Overhttp://<LAN IP>:8080WebGPU is gone, so WebGL2 runs without traced GI, and the sound engine runs on the page behind a ScriptProcessorNode (done: it used to be silent), where a long frame can stutter it. docs/deployment.md now says so. - Autoplay. Joining from a
?nick=link keeps audio suspended until the first click or key. The#sound-hintnow says so. - Windows builds. A running
server.exelocks the release binary: stop it beforecargo build/test --release.target/debuggot corrupted twice in one day ("can't find crate", "found staticlib std") when a disk filled and, it seems, when the IDE built into the same target directory at the same time. Give the IDE its ownCARGO_TARGET_DIR. - Disk. D: was at 100% today (22 GB free,
target/31 GB) and C: at 6.6 GB. A full disk truncates build artefacts, and on the server a failed DuckDB write exits the process, which then crash-loops (SEC-7). Update: C: hit 0 bytes again during the xtask work, from Docker's growth inside WSL and leaked temp files. The WSL distro now lives inD:\wsl\Ubuntu, which freed 35 GB on C:, and the tests and browser tools delete their temp files. - wasm-only code is invisible to host checks.
app.rsandgfx.rscompile only for wasm32, socargo checkon the host never warns about their dead code. Run clippy with--target wasm32-unknown-unknown, as check.sh does. - The steady-state move path must not allocate. Re-run
cargo test -p server --release --test allocafter touchingroom.rsor the protocol. The skate hooks inwalk()were checked and pass. - Headless verification needs a real click. A form submitted by script is not a user gesture, so audio stays suspended (
scripts/smoke.mjsclicks through CDP's input events for that reason). The other CDP scripts used this session (shot.mjs,audio.mjs,prof.mjs, a frame tap) live in a scratch directory, not in the repo.
4. Gaps
Functional
- Reconnect (done). The client rejoins its room with backoff after a drop or a restart, and reloads into it when a deploy changed the client bundle. A run on the half pipe or a race in progress is lost.
- Sound without a secure context (done). The page-thread fallback plays; latency is about 21 ms higher.
- Unused protocol surface.
NeighborEvent::Goneis never sent;Target::Player,Verb::Useand severalActcombinations are never built.InteractandAct{Use}behave differently: onlyInteractcancels a pending walk or a skate run (SRV-12). - Over-budget commands vanish silently (PERF_01 #10, done): the sender is told, at most every three seconds.
- Turntables placed at runtime create a deck nobody is told about (FINDINGS #9, not re-checked).
- Half pipe: no sound of its own beyond reused clicks, thuds and chimes. Spectators see a dropped air count as a clean landing until the count arrives. A run in progress is lost on leaving. The
#skatebillboard in the park faces away from the default camera.
Tests
None at all for world.rs (seams, hand-offs, caps), racing.rs (session lifecycle, retirement), rtc.rs, main.rs (auth endpoints, origin check, routing; no end-to-end WebSocket test), load.rs, protocol's codec and sanitisers, every client/src/app/*, gfx.rs, or sfx engine, bus, voice and parse beyond sfx/mod.rs. cargo xtask golden checks the wasm builds against the native hashes and cargo xtask smoke drives the real client in a browser; still, no unit tests run inside wasm.
Operations
- Docker image (done, BLD-1). It builds (the parallel stages also raced on a shared cargo cache, now locked), serves
/and/docs, 208 MB. - No TLS in the binary. That is fine behind Caddy or an ingress, but the cookie's
Secureflag trustsX-Forwarded-Protofrom any peer, and nothing refuses keys without TLS (SEC-9). - Deploy configs carry no secrets wiring (
MR_ACCESS_KEY,MR_BUILDER_KEY,MR_SESSION_SECRET), so a deployment is open and editable by default. - No health endpoint, no metrics, logs to stdout only, and no bare-metal or systemd guidance.
- Unbounded growth. Archive Parquet files are never pruned (41 in two days), every snapshot is kept, edits are never deleted after a snapshot, and
skaterows are never archived. The k8s PVC is 5 Gi. - Backups: "copy the file while stopped" only.
- Single replica. One DuckDB writer, so a rollout means downtime and a manual reload for everyone.
- loadgen cannot log in, so it gets a 401 against a server with an access key.
5. Status of the earlier audits
FINDINGS.md top 10
| # | Finding | Status |
|---|---|---|
| 1 | The settings string garbles looks 10–12 | open (app.rs:2043) |
| 2 | Docker build broken by .dockerignore | open |
| 3 | affects_light drifted from the light tables | open (app.rs:224) |
| 4 | Neighbour SPIN/WAVE centres absolute | not re-checked |
| 5 | Held RTC frames had no cap | fixed (MAX_HELD 256) |
| 6 | A race session without a Join never retires | not re-checked |
| 7 | Held voices lost before the worklet runs | fixed in ce468a7 |
| 8 | GPU struct sizes documented three ways, unasserted | open |
| 9 | Runtime turntables and the deck | not re-checked |
| 10 | Event kinds in hand-written SQL lists | open |
Also re-checked and still open: SRV-2, SRV-3, SRV-4, SRV-6, SRV-12, KIND-0, KIND-9, GFX-1, GFX-2, GFX-15 (Mesh::new unused), RACE-4, REPO-2. Its header says "nothing has been fixed", which is no longer true. Line numbers have drifted by 7–20 lines.
PERF_01.md top 12
#7 (race input two ticks late) is fixed: the queue target is adaptive, 1 to MAX_TARGET 4. The first-join freeze, measured separately, is fixed too: 61 ms instead of 2 s plus 1.7 s (a throwaway RTCPeerConnection and a warm-up frame, ce468a7). Everything else is open, the biggest first:
- A neighbour's edit rebakes the whole patch (21–25 ms frames).
- Joining and crossing a seam are one long frame.
- Every seat or door change rebuilds the static scene.
- The WebRTC driver costs about 10× the CPU of the WebSocket.
- DOM work dominates with crowds.
- GI is traced over every cell every frame.
SECURITY.md
The criticals are fixed. Still open: SEC-7 disk fill, SEC-8 fan-out amplification, SEC-9 TLS, SEC-10 book box abuse and sessions that cannot be revoked, SEC-13 to SEC-17 and the script CSP. SEC-16 says the Mermaid CDN page "is not served by the game", but /docs now serves it.
PERF_IMPROVEMENTS.md
None of it has been done yet: a SIMD light bake, sound voices without a per-sample match, the resident spot search, picking. Worth folding into PERF_01's list rather than keeping two.
6. Dead, obsolete and duplicated code
Superseded but still present
- The old 2D per-tile lamp bake (
sight::lightsandbake_light, app.rs:3070) is now only a fallback for Classic and before the volume bakes. Its light table (sight.rs:140) lacks 9 emitting kinds and its colours differ fromlight.rs. - The look byte in the settings string (byte 5) is written and read but always overwritten by the profile index. The doc comment at app.rs:1358 ("the look as a or c") is stale.
settings.v1–v3are never removed from localStorage.auth_status's fallback for "an old server without /auth" (app.rs:685) has no purpose: client and server ship together.custom_look: Option<usize>is alwaysSomeafter start-up; itsNonebranches are dead.Style::CorporateandStyle::Templeare used by no room since the atrium became Chinatown, yet they still carry palette, dressing and ambience code.ObjectKind::Pillaris in no room.
Dead or test-only
Mesh::new(scene.rs:174),LOOK_GRAPHIC(gfx.rs:264,allow(dead_code)),ST_HOLD(sfx/voice.rs:23,allow(dead_code)), and the rig constsUARM_R,LARM_R,THIGH_R,SHIN_R(mirrors only).NeighborEvent::Gone(handled, never sent) andTarget::Player(never built).POST /logoutis never called by the client.- Test hooks, intentional:
LogMsg::Archive,Room::step_props_now,Room::unthrottled. race::TICK_HZduplicatesprotocol::TICK_HZwith no assert;sfx::TICK_HZmeans something else under the same name.
Duplicated and drifting
- splitmix64 twice (disco.rs:92, scene.rs:141).
- xorshift four times (scene.rs:632, loadgen, residents.rs:35, race/game.rs:216, the last with different shifts).
- FNV-1a with two different bases (scene.rs:667, residents.rs:92), plus a fourth hash in race_view.rs:163.
HANDLES = 64twice (app/sound.rs:25, sfx/engine.rs:178).level_ofinlined again at app.rs:1766, and a third version with a different tolerance in light.rs:187.- Three copies of "nearest object" for
/portal,/boardand/screen(APP-8). - Scenery ring placement copied (GFX-3).
- The CDP harness copied (
scripts/looks.mjsand the skill'ssnap.mjs). - Interactable and keyword lists kept separately on client and server (KIND-6, KIND-7).
Repo hygiene
.idea/is tracked and dirty.- Five screenshots are referenced only by FINDINGS.md.
- The README caption still says "the temple atrium".
- Five working notes sit at the root (FINDINGS, PERF_01, PERF_IMPROVEMENTS, PLATFORM, IDEAS), and IDEAS.md is a compile input of the model room.
MR_LLM_URL,MR_LLM_KEYandMR_LLM_MODELare documented in props-npcs-audio.md but never read.
7. Docs that disagree with the code
There are 46 places. The ones people actually read come first.
docs/html/handbook.html
- The KINDS list lacks Speaker, Turntables, DrumMachine, BassSynth and BookBox, and marks Plant as blocking. (done 2026-10-06)
- It gives CameraUniform as 272 bytes; it is 288 (now 304). (done 2026-10-06)
- The replayed kinds leave out drop and take. (done 2026-10-06)
- The key map has no B, K or T, and lists a
/key that does not exist. (done 2026-10-06) - It says "anyone can edit any room". (done 2026-10-06)
- The config table lacks
MR_DOCSand the four auth variables. (done 2026-10-06) - The list of rooms that ship lacks disco. (done 2026-10-06)
docs/html/technical-design.html
- It gives CameraUniform as 272 bytes and the object cap as 4096 (it is 32,768). (done 2026-10-06)
- The byte-level wire examples predate
look,levelandat. (done 2026-10-06)
CLAUDE.md
Lineis both 48 and 64 bytes. It is 64.FLOOR_INDICESno longer exists; it is nowViewRanges.floorwithSTENCIL_FLOOR.- "Only place/remove/rotate/screen are replayed": portal, drop and take are too.
- History also includes
served.
docs/protocol.md
RaceInputis{ seq, recent: [u8; 6] }, notcontrols.- The RTC barrier messages are missing.
RaceFrame's field order (acklast) and its rate (every tick) are wrong.ObjectStatelacksShelf, and the list of walkable kinds is short by 8.- It says "all traffic is WebSocket".
docs/architecture.md
- It says rooms live for the life of the process; they retire after 5 idle minutes.
- It gives "4096 objects"; the cap is 32,768.
- It says the directory lock is taken on join only and is the only lock.
- It says the reader "does not decode"; it does.
docs/performance.md
- It says chat is allocation-free; chat allocates for its log row.
- It says loads run on the log thread; they run on a separate loader thread.
- It says
wasm-opt -Os; the build uses-O3. - It describes Diorama's cost as a 32-light loop, which is gone.
- The loadgen flags lack
--room.
docs/rendering.md
- It says 16 avatar lights; up to 32 are kept.
- It says lamps go into the light list; only avatars do.
- The edit-rebuild timings are stale.
- Sight is also blocked by Diagonal, Column and Billboard.
docs/rooms.md
- The lava lamp has 7 blobs, not 10.
- The lobby's "walled back room" is gone.
- The
Ballrow is missing. - "Anyone can edit" is out of date.
docs/deployment.md and README.md
docker buildis given as working; it is not.- "Anyone can edit" is out of date.
- "Room creation capped at 64": rooms without a file are capped at 16.
- The worst-case path search is 275 µs, not 75.
- The "temple atrium" caption is stale.
docs/persistence.md
- The schema comment leaves out
skate. - It says a corrupt payload "panics the room"; it panics the loader thread.
FINDINGS.md and PERF_01.md
- Both say "nothing fixed".
- Their line references have drifted.
8. The speculative docs
IDEAS.md: built but not marked
- The bartender (with the menu, servings and buzz).
- First person when sitting (a setting).
- A rewarding sound system (
sfx). - Photo mode.
roomcheck(it lints but does not render top-down).- The
/lookand/roomskills (aslook-from-imageandroom-from-image). - docker-compose with Caddy, kustomize and Helm (all written, all blocked by the Docker build).
Built in part:
- Race variants: three themes, but no time trial, ghosts or teams.
- Music back in: the disco makes music from knobs, but there is no
.kitor.midplayer. - Achievements as neon: the
#skateboard is the first one. - Light cycles: the Tron light-racer theme exists, but not on the dance floor.
Marked built already: Pings, the LLM room.
IDEAS.md: sensible next, by what already exists
- A window onto the race (M). Race frames are already decoded on the client, and the race view draws on any surface.
- Time trial with ghosts (S–M). The client already re-runs
ship::step, so a ghost is the same thing replayed. - Footprints that fade, and dust in the light (S). The dynamic-line plumbing exists (pings, disco eyes, skateboards).
- A world clock or a build radiator (S–M). Keyword billboards are the pattern; one more keyword means one function in
server_view.rs. - Quiz night at the bar (M). There is a bartender NPC and a chat path.
- A Prometheus
/metricsendpoint (S).load.rsalready samples. - CI (S). check.sh is already the whole pipeline.
The Lore quarter and proximity voice are large and have nothing underneath them yet. Paradroid's transfer game exists as a PvP match on Deck 1; taking things over with it does not.
PLATFORM.md
None of the platform layers is built. The skate park is one more data point for its §1.2. A new thing still costs code smeared across four crates:
- protocol: a kind, messages and a shared module;
- props: the ball height;
- server: eventlog, layout, room, roomcheck and tests;
- client: scene, app, latency, pings, server_view and index.html;
- rooms, world, street;
- six docs.
That is about 25 files against the book box's 15. The interesting logic, judging and scoring, is about 150 lines in protocol/src/skate.rs. The case for kits is stronger than when the page was written. The cheapest first step, deriving every per-kind table from one declaration, would have saved the drift listed in §3.
9. Clean-up, in order
Each step is small, independent and safe to do on its own.
- ~~Commit the skate park.~~ Done. Still to do: stop tracking
.idea/. - ~~Fix the Docker build.~~ Done. Still to do: wire the auth secrets into compose, helm and kustomize.
- Assert the GPU struct sizes with
const _: () = assert!(…), and fix the 240/272/48 comments and docs in the same change. - One per-kind table. Derive
affects_light, the sight lights, the light emits and solids, andprops::heightfrom one place, or at least test that they agree. Regenerateroomgen.py's KINDS,preview.py's COLOURS and the handbook's KINDS fromObjectKind::ALL, or add a check. - Fix the settings-string look bug (APP-1). Drop the dead look byte and clear
settings.v1–v3. - Remove the dead code:
Mesh::new,LOOK_GRAPHIC,ST_HOLD,NeighborEvent::Gone(or send it) andTarget::Player;- the old
/authfallback, and the 2D lamp bake if Classic can use the volume; Style::CorporateandStyle::Temple, unless a room is coming for them.
- Make
Act{Use}andInteractone path, or dropVerb::Use. - One small
randand hash module shared by client, server, race and loadgen, keeping race's own shifts if its goldens depend on them. - A test that ties
EDIT_KINDSandHISTORY_KINDStoEvent. Decide whetherskateis pruned. - Sweep the docs in §7. Two passes: the HTML pages people read, then the markdown. Rewrite the headers of FINDINGS.md and PERF_01.md with their fix status, or fold the still-open items into this file and archive them.
- Move the CDP scripts from the scratch directory into
scripts/, as a smoke test: join, click, meter audio, ride the half pipe.
10. What to do next
Ordered by value for effort. S is an afternoon, M a few days.
- ~~Sound everywhere.~~ Done (page-thread fallback).
- ~~Reconnect.~~ Done.
- ~~CI.~~ Done, as steps by hand.
cargo xtask(lint, test, rooms, client, server, golden, smoke, image, deploy-lint, bench) passes on Windows and, withcargo xtask linux, in Debian; see docs/deployment.md, "Checks". There is no CI server, by choice. Still open: the compose file is only checked where docker is on PATH, anddeploy-linton Windows needs helm and kubectl (or thelinuxform). - Deploy (S). The image works; add the secrets wiring, a
/healthzand archive pruning. - The frame-time top three from PERF_01 (M):
- rebake only the region of an edit;
- bake over several frames, or in a worker, on join;
- doors and seats in a dynamic layer instead of the static rebuild.
- Tests for
world.rsandracing.rslifecycles (S–M). These are the biggest untested server paths with state machines. - Half pipe polish (S):
- its own landing and bail sounds;
- a spectator chase camera;
- turn the billboard toward the camera;
- a short trick name in chat ("540!");
- time trial on the same board.
- First platform step (M). One per-kind declaration that the tables in §3 come from, before the next new object kind.