Skip to content

Guarantee a floor can be walked, after shipping one that could not - #207

Merged
0xward merged 1 commit into
mainfrom
claude/nullstate-onchain-text-q6g2a3
Jul 30, 2026
Merged

Guarantee a floor can be walked, after shipping one that could not#207
0xward merged 1 commit into
mainfrom
claude/nullstate-onchain-text-q6g2a3

Conversation

@0xward

@0xward 0xward commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Owner played on MiniPay, entered Bunker 1 floor 1, and could not move out of the spawn area — could not test anything else at all.

Reproduced

Flood-filled from the spawn across generated floors, using the engine's own wall test and its own NS_solidDecorAt footprint:

Floors with the lift unreachable
crate 44×44 — as I shipped it in #197 5 in 60
crate 34×34 — as it was before 2 in 60
no decor at all 0 in 100

So this is partly mine. Widening the crate to 44 to match its new art also widened its collision footprint — decorSolidAt reads def.w directly — and that took a latent bug from uncommon to hit-on-first-play.

But shrinking it back would only hide it

A corridor is one tile (TILE = 40) and the player's radius is 14, so anything with a solid footprint over 12px seals one — which is every prop in the game. spawnDecorInto keeps props off doorways and hugging room walls, yet a room with a narrow exit, or two props landing either side of a gap, still closes the last opening.

The fix is a guarantee, not a size

_ensureFloorTraversable runs at the end of ensureFloor: walk the floor from the spawn, and if the lift cannot be reached, delete whichever props sit on the frontier of the reachable region, then walk it again. That is the minimal set that can be responsible, so it settles in a pass or two and rarely drops more than one prop.

Vault doors and sealed/premium caches are never removed — they are content, and they sit inside rooms rather than in doorways.

The footprint test is now one function used by both the live collision check and the generation-time guarantee, so the two cannot drift on what counts as blocking.

Result: 0 in 150, across every depth. Kept as npm run test:traversable so this cannot come back the next time a prop is resized.

Two measurement mistakes worth recording

Both produced confident wrong answers on the way here:

  1. The first check demanded the player reach the lift's exact pixel, which is usually wall-adjacent and unreachable for a 14px body — it called walkable floors sealed.
  2. The first fix probed only a blocked cell's centre when deciding which prop was guilty, while the walk had probed the body's edges too. It kept concluding there was nothing to remove on 2 floors in 100.

Verification

tsc --noEmit clean · engine parses and minifies · audit passes · npm run test:traversable 0 sealed in 150.

Not verified: that this specific floor the owner got stuck on is now walkable — the floor was procedurally generated and is gone. What is verified is that 150 fresh ones at every depth all are.


Generated by Claude Code

Owner played on MiniPay, entered Bunker 1 floor 1, and could not move out
of the spawn area — could not test anything else at all.

Reproduced by flood-filling from the spawn across generated floors, using
the engine's own wall test and its own NS_solidDecorAt footprint:

  crate 44x44, as I shipped it in #197 .... 5 sealed in 60
  crate 34x34, as it was before ........... 2 sealed in 60
  no decor at all ......................... 0 in 100

So this is partly mine. Widening the crate to 44 to match its new art also
widened its collision footprint — decorSolidAt reads def.w directly — and
that took a latent bug from uncommon to hit-on-first-play.

But shrinking it again would only hide it. A corridor is one tile (40) and
the player's radius is 14, so anything with a solid footprint over 12px
seals one, which is every prop in the game. spawnDecorInto keeps props off
doorways and hugging room walls, yet a room with a narrow exit, or two
props either side of a gap, still closes the last opening.

Hence a guarantee instead of a size. _ensureFloorTraversable runs at the
end of ensureFloor: walk the floor from the spawn, and if the lift cannot
be reached, delete whichever props sit on the frontier of the reachable
region and walk it again. That is the minimal set that can be responsible,
so it settles in a pass or two and rarely drops more than one prop. Vault
doors and sealed/premium caches are never removed — they are content, and
they sit inside rooms rather than in doorways.

The footprint test is now one function used by both the live collision
check and the generation-time guarantee, so the two cannot drift on what
counts as blocking.

Two measurement mistakes worth recording, because both produced confident
wrong answers on the way here. The first check demanded the player reach
the lift's exact pixel, which is usually wall-adjacent and unreachable for
a 14px body, so it called walkable floors sealed. And the first fix probed
only a blocked cell's centre when deciding which prop was guilty, while the
walk had probed the body's edges too — it kept concluding there was nothing
to remove on 2 floors in 100.

0 in 150 after the fix, across every depth. Kept as npm run
test:traversable so this cannot come back the next time a prop is resized.
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nullstate Building Building Preview Jul 30, 2026 7:16pm

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@0xward
0xward merged commit b0112ab into main Jul 30, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant