Removes operator-private material from the shipped tree, corrects documentation
that had drifted from the code, deletes dead code, and applies a consistent
prose style.
Private material moved out of the public tree (docs/private/, git-ignored):
- the wallet keyfile recovery runbook and its helper scripts, which together
published the mainnet wallet file path, the service account, backup snapshot
filenames, and the wallet RPC listener state. The helper duplicated the same
constants, so relocating the document alone would not have removed them.
- the stagenet parallel-candidate runbook and its fixtures.
- the dated production-state record, the internal remediation plan, and the
TODO list. None are reference documentation for an outside reader.
Redacted or genericised:
- operator home-directory paths in shipped scripts and units. The asset build
script now takes KENNEY_ASSETS_DIR instead of a hard-coded path.
- private LAN addresses in tests, env examples and deploy docs, replaced with
RFC 5737 documentation addresses.
- the default alert sender and the notification hub example.
- the Monero wallet unit now matches the Wownero one: a dedicated service
account and a config file, instead of the operator's login account with the
wallet password in argv where any local user can read it from /proc.
Ignore rules now cover every .env variant rather than the bare name, plus local
agent state. The deployment docs instruct operators to create .env.mainnet and
.env.stagenet, which the exact-name rule would have allowed to be committed.
Documentation corrected against the code: per-chain dungeon level counts, the
premium unlock rule, Tavern chat scope, backup retention, the chain-profile
fallback, the environment template location, and several sections describing
shipped work as pending.
Dead code removed: configPersistence, rpccalls, a duplicate vendored ROT.js
bundle, the unused tile-picker overlay, the unreachable legacy game-size path
and its vestigial parameter, spectator stubs that shadowed the real
SpectatorManager, and commented-out debugging. nip98 now imports the shared
nostr loader rather than duplicating it.
Prose style: em-dashes removed throughout in favour of colons, semicolons and
commas; comments restated as present-tense descriptions of the code rather than
narration of past changes.
127 suites / 1015 tests pass.
Two iso bugs from reusing the tavern renderer for the SP dungeon:
- Character always faced down/SW: sceneFromGameState hardcoded facing:"down", so the renderers
ignored their movement-inferred facing (truthy default won). Now facing defaults to null (SP
server sends none) so iso/3D infer it from movement; facingDelta(null)=down keeps tiled fine.
- "Copy of himself at the origin": the iso renderer drew EVERY entity via _charFrame, so the
entrance feature rendered as a male character at the start. Features/items now draw as pack tiles
(stairs/chest) or a glyph; monsters get a red tint so they do not read as a second player.
Explored-but-not-visible tiles rendered at a flat 0.25 brightness — a hard-edged grey block
that outlined the explored map (and its edge). Now explored memory dims AND fades toward black
with distance from the player, so the remembered area melts into the dark with no revealing
edge. Also set the render host background to pure #000 so the area beyond the map edge is the
SAME black as an unexplored in-bounds tile (previously #0a0c0f vs #000 — a shade seam that
traced the boundary). Currently-visible lighting unchanged.
Torches replace WALL cells adjacent to floor (dungeon.js), but the Tiled renderer based the
torch on a floor tile and drew only a procedural flame — so they read as flames floating on
the floor. Base the dungeon torch on `wall` and draw the pack torch sprite over it, then RK.fx
animates the flame/glow on top: a proper wall-mounted sconce. Fire fixtures now composite
base + sprite + flame (hazards keep base + pulse, no sprite).
- FOG: sceneFromGameState only emits exit/entrance/treasure/items once their cell is EXPLORED,
and the monster only while IN VIEW — no more exit stairs leaking through the fog.
- DESCEND FEEDBACK: reaching a non-final exit descends (multi-level) and used to silently dump the
player at a new entrance (read as a bug). Server now sends depth/maxDepth on game_event; the
client shows "Stairs down! Level N of M — keep going". Also lowered level counts (WOW 4->2,
BTC 8->3, XMR 2->1) — clearing 4-8 levels in one block was unwinnable; kept modest until proper
multi-level calibration + UX.
- CAMERA: the host filled the very-tall #game-display so centering put the player low; it's now a
bounded viewport (min(100%,78vh)) centered in #game-display, so the player stays on-screen-centered.
Suite 62/435 green.
The migration that makes the pack ladder pay off IN the dungeon, not just the tavern.
The SP game now draws via RK (Tiled/ASCII/Iso/3D + unlocked packs) instead of the
legacy ROT display.
- Adapter: sceneFromGameState now consumes the CLIENT state shape (sparse {y:{x:v}}
tile maps, not just server arrays) via maxDims(). Verified + unit-tested.
- Bug fix: RK.sceneFromGameState was never actually exposed (only RK.scene.*), so
matchClient + tavern spectator were silently no-op-ing. Aliased onto RK.
- Bridge (spGameRenderer.js, RK.SPGame): mounts an RK renderer in a dedicated host
inside #game-display, toggles the legacy ROT canvases, zoom-enabled. Game._draw
GameScreen prefers it and FALLS BACK to RenderEngine on any failure, so the live
game can never blank. ROT still draws the splash/win/lose text screens.
- Picker (spRenderPicker.js): homepage mode + pack selector, gated by entitlements
(free = Tiled/Original + ASCII; ladder unlocks Iso/3D/packs), rebuilds on identity.
- index.html loads the render-kit renderers + the bridge/picker.
Bundled with the catalog ladder (migration 028): free Original bare pack, ladder
1/5/10/20/40/50. Deploying makes the free tavern bare (by design) AND the dungeon
render-kit-ed. v1 renders the whole explored level + zoom (player-centered camera is
the next polish). Suite 62/435 green; adapter smoke-verified.
The shared "juice" layer, pure-canvas (CSP-safe, no WebGL/shaders), driven off a
clock so both renderers light a scene the same way:
- html/js/render/fxLayer.js (NEW): RK.fx — layered-sine flame flicker, additive
warm glow, a dancing two-layer canvas flame, and pulsing hazard overlays
(lava/poison/spikes) with a footprint-clip callback so it fits square cells
and iso diamonds alike.
- Tavern now has FIRE: 4 corner braziers + a hearth on the left wall throw real
flickering light. Placed along walls, clear of spawn/aisles/tables.
- Both renderers: torch/hearth/hazard tiles draw only their FLOOR base in the
static pass (no more solid amber block), then RK.fx paints the animated flame
/ hazard pulse in the live loop. Tiled caches emitter positions and draws them
over the vignette so light punches through the dark edges; iso adds them as
depth-sorted fx items and keeps its RAF alive while any fire/hazard is onscreen.
- Dungeon hazard zones wired end-to-end in the scene model (lava L / poison P /
spikes ^ chars -> pulsing tiles) — they render the moment the generator emits
them; no client-authoritative fakes.
- fxLayer.js included in tavern.html + match.html.
Suite 58/419 green; render files node --check clean.
The black boxes around furniture/windows were transparent object tiles drawn
straight onto the dark canvas. Fix at the pipeline level, not as a tavern one-off:
- tileRenderer: a tile kind whose legend declares `over` (the ground it sits on)
now draws that base tile FIRST, then the object on top — so the object's
transparent areas show the floor/wall. Works for any scene, atlas or flat-colour
fallback. Wall-grounding shadow strip now only applies to real walls, not objects.
- sceneModel TAVERN_LEGEND: declares over='floor' for bar/keg/shelf/table/chair/
barrel/crate/rug and over='wall' for windows.
- catSprites: the cat occupies ~40% of its 50x50 frame, so scale to ~2x the cell
and centre it — it now reads about tile-sized instead of tiny.
Client-only. Suite 57 suites / 413 tests green.
Used the sheet's hand-labelled roguelikeSheet_meta.json to pick the RIGHT tiles
instead of guessing:
- New tile kinds + coords (window, counter, keg/barrel, shelf, table, chair,
crate, rug, door) in sceneModel TAVERN_LEGEND/TILE_OF + assetPacks tileMap.
- tavernMap redesigned: windowed walls, a bar counter with a shelf of bottles
behind it and a keg (beer!) at each end, six tables each with a chair, a
central rug, corner barrels/crates, and a door. Chairs are walkable so standing
on one reads as sitting. Warm wood floor color (was a dark green in the fallback).
- Bartender now stands BEHIND the bar (spawn + roam confined to the row between
the top wall and the counter, sealed off by it).
Still TODO from feedback: a cat (no cat sprite on the sheet — needs an asset) and
richer bar bottles. Suite 57 suites / 413 tests green.
- tavernLife.js: client-side NPCs (bartender, patrons, cat) with autonomous
movement, random speech bubbles, and real-player chat bubbles
- T2b: spectator camera — watch live dungeon runs from inside the tavern
(game list, spectate_start/update, ESC to leave)
- R1: sceneFromGameState adapter — converts dungeon game state to render-kit
Scene with lighting grid and entity mapping
- R2: pre-populated Kenney roguelikeSheet tile defaults for the tiled renderer
- Dungeon renderer support: TileRenderer + AsciiRenderer handle lightGrid,
dungeon features/items/monster entities
- 3 new tests (242 total, 36 suites, all passing)