Reveal cells the party sees by torchlight in the player view (release 1.2.1)#28
Conversation
The dungeon viewport and automap render only the cells carried by the player-view projection, which equated "visible" with "explored" — the cells the party had physically stepped on. A lit torch therefore changed nothing: every open square around the party stayed a black void until a footstep marked it explored. The client cannot fix this itself; the projection deliberately withholds unexplored geometry, so it never has the walls or doors of the surrounding room to draw. Compute what the party actually sees by its own light at view-build time and fold those cells into the current level's projection: - `_light_reveal` floods outward from the party's cell through open passages (and open, non-secret doors), bounded by the light's radius in cells, and includes the whole keyed room the party stands in. Walls and shut or undiscovered doors stop it. - `_explored_levels` unions the seen cells into the current level so the client draws the room and lit corridors with no client change. This is sight, not exploration: seen cells never enter the persisted explored set, so movement cost (30 for a new cell, 10 for a walked one) and map persistence are untouched. Visibility recomputes every view, so lighting a torch while standing still reveals the room immediately. Adds TestLightReveal: reveal-ahead-without-moving, unlit-shows-only- footprints, light-stops-at-a-closed-door, and whole-room reveal. Claude-Session: https://claude.ai/code/session_016qNYjfiRqHJFxHYbwFEEX9
Two findings from an adversarial review of the torchlight reveal: - The *light* spell family stores its radius under `radius_feet`, while equipment and magic items use `light_radius_feet`. `_light_reveal` read only the latter, so a party lit by a 15-foot *light* spell fell back to the 30-foot default and over-revealed corridor geometry. Add `_light_radius_feet`, which reads whichever key the source carries. - The whole-room reveal unioned every cell of the party's keyed area unconditionally, bypassing the `_sight_passes` gate. No shipped content authors a room split by an internal door, but an alcove behind a closed or secret door would have leaked. Fold the room reveal into the sight-gated flood (admit a neighbour within the light's reach *or* in the party's own room, but only across an edge sight actually crosses), so a sealed-off alcove stays dark while the open room still lights whole. Adds regression tests: undiscovered secret door stays a wall under light, the *light*-spell radius reveals less than a torch, seeing a cell by light doesn't change its movement cost, the reveal doesn't bleed into another level, and it never enters the referee view. Claude-Session: https://claude.ai/code/session_016qNYjfiRqHJFxHYbwFEEX9
Adversarial review roundRan a rubber-duck (adversarial) review of the change. Two substantive findings, both now fixed in c8433b3:
Things the review tried and failed to break (verified safe): secret doors never leak and never render as anything but New regression tests cover all of the above. Full suite: 1544 passed, 58 skipped. |
Per the release process, a PR that changes user-visible behavior records its bullet under [Unreleased] in the same PR. Claude-Session: https://claude.ai/code/session_016qNYjfiRqHJFxHYbwFEEX9
Bump the version and cut the [1.2.1] changelog section (the torchlight reveal fix). Patch release: backward-compatible bug fix, public API surface and schema_version unchanged. Local dry run green: full gate, uv build, check_dist, and a fresh-venv install_smoke all pass for 1.2.1; goldens keep their engine stamp (no regeneration). Claude-Session: https://claude.ai/code/session_016qNYjfiRqHJFxHYbwFEEX9
Cut as release 1.2.1Made this the release PR (patch — backward-compatible bug fix; public API surface and
Local release dry run — all green for 1.2.1:
Remaining (post-merge, per AGENTS.md): after this merges, an annotated |
Problem
The dungeon viewport (and automap) render only the cells carried by the player-view projection, and that projection equated visible with explored — the cells the party had physically stepped on. A lit torch therefore changed nothing on screen: every open square around the party stayed a black "void" until a footstep marked it explored. The client can't fix this itself — the projection deliberately withholds unexplored geometry, so it never receives the walls/doors of the surrounding room to draw.
Reported against the
osr-webfront end as: "Light doesn't reveal open grid squares in the viewport; party must move to the open square to 'uncover' it even with a lit torch."Fix
Compute what the party actually sees by its own light at view-build time and fold those cells into the current level's projection (
src/osrlib/crawl/views.py):_light_revealfloods outward from the party's cell through open passages (and open, non-secret doors), bounded by the light's radius in cells (30 ft = 3 cells at the classic 10-ft square), and includes the whole keyed room the party stands in. Walls and shut/undiscovered doors stop it._explored_levelsunions the seen cells into the current level, so the client draws the lit room and corridors with no client change.This is sight, not exploration: revealed cells never enter the persisted
exploredset, so movement cost (30 for a new cell, 10 for a walked one) and map persistence are untouched. Visibility recomputes on every view, so lighting a torch while standing still reveals the room immediately.Tests
Adds
TestLightRevealintests/test_exploration.py:Full suite: 1539 passed, 58 skipped (goldens unaffected — this is projection-only). Verified end-to-end against the
osr-webapp: same seed and entrance, no movement — dark before lighting, full room after.https://claude.ai/code/session_016qNYjfiRqHJFxHYbwFEEX9