The vehicle deck's cars and lorries and the cave cathedral's two speleothem columns are drawn but have no collision. The diver swims straight through all of them.
Blocked on a decision — see #119. How this gets fixed depends on which side of the WP-07 gameplay/presentation boundary props are classified on. Details at the bottom.
Reproduction
Driving the physics loop directly via window.gameAPI on main.
Cave cathedral columns
Both columns are features, neither appears in structures:
{kind:'caveColumn', x:88, dTop:56, dBottom:98, wTop:9, wBot:11, seed:5901},
{kind:'caveColumn', x:112, dTop:60, dBottom:95, wTop:6, wBot:8, seed:5902}
solidAt returns false across the entire footprint of column A — probed at every metre from x = 82 to x = 94 at d = 75, all open water. Swimming right from x = 80, the diver reaches x = 88.15 — dead centre of a column with an 11 m base — still reading solid: false.
This one is a documented choice rather than an oversight. src/sites.js:671-672:
// Neither introduces collision — solidAt() only tests the AABB
// structures list, and neither column is added there.
Wreck vehicle deck
12 cars and lorries at d: 39 (src/sites.js:455-466), none in structures. A probe grid over the car at x = 34 and the lorry at x = 54, sampled across d = 36.5 … 38.5, is entirely open water. Swimming right from x = 30, the diver passes through the car at x = 34 at t ≈ 8 s with no collision registered.
Probe placement matters here. Sampling at d = 39 reads solid, but that is the vehicle-deck floor slab ({x1:14, x2:78, dTop:39, dBottom:40, kind:'deck'}) — solidAt is inclusive on dTop. A probe at that depth cannot distinguish a car with collision from one without; it has to be taken at body height above the slab. (The .tmp/frontend-audit data records propProbeSolid: false at d = 39 — right conclusion, wrong probe point.)
Why this is blocked
WP-07 (#119) partitions site data into two documents:
gameplay.json — [id, maxDepth, hasOverhead, entry, boatX, floor, ceiling, structures, badAir, …]
presentation.json — [id, name, surfaceMarker, features, visualZones, atmosphereProfiles, decorationRules]
solidAt() reads structures (gameplay). Cars and columns are features (presentation). tests/unit/site-assets.test.ts:127 asserts presentation can never carry structures, so after that merges the gap is enforced by a passing test.
That is the PR working as intended — its goal is that an art edit cannot reach collision. But it does mean the fix location moves: giving a car a hitbox stops being a one-line edit next to the car and becomes a deliberate gameplay-side entry, either promoting specific prop hitboxes into structures or adding a gameplay field that references prop ids.
Worth settling that classification on #119 before it merges, since changing it afterwards is a data migration rather than an edit.
Scope note
If props do gain collision, #101 and #122 (centre-point collision) are both adjacent: a car-sized AABB is small enough that a point-test diver would clip visibly into it, so extent probably wants sorting first or alongside.
The vehicle deck's cars and lorries and the cave cathedral's two speleothem columns are drawn but have no collision. The diver swims straight through all of them.
Blocked on a decision — see #119. How this gets fixed depends on which side of the WP-07 gameplay/presentation boundary props are classified on. Details at the bottom.
Reproduction
Driving the physics loop directly via
window.gameAPIonmain.Cave cathedral columns
Both columns are
features, neither appears instructures:solidAtreturns false across the entire footprint of column A — probed at every metre fromx = 82tox = 94atd = 75, all open water. Swimming right fromx = 80, the diver reachesx = 88.15— dead centre of a column with an 11 m base — still readingsolid: false.This one is a documented choice rather than an oversight.
src/sites.js:671-672:Wreck vehicle deck
12 cars and lorries at
d: 39(src/sites.js:455-466), none instructures. A probe grid over the car atx = 34and the lorry atx = 54, sampled acrossd = 36.5 … 38.5, is entirely open water. Swimming right fromx = 30, the diver passes through the car atx = 34at t ≈ 8 s with no collision registered.Probe placement matters here. Sampling at
d = 39reads solid, but that is the vehicle-deck floor slab ({x1:14, x2:78, dTop:39, dBottom:40, kind:'deck'}) —solidAtis inclusive ondTop. A probe at that depth cannot distinguish a car with collision from one without; it has to be taken at body height above the slab. (The.tmp/frontend-auditdata recordspropProbeSolid: falseatd = 39— right conclusion, wrong probe point.)Why this is blocked
WP-07 (#119) partitions site data into two documents:
solidAt()readsstructures(gameplay). Cars and columns arefeatures(presentation).tests/unit/site-assets.test.ts:127asserts presentation can never carrystructures, so after that merges the gap is enforced by a passing test.That is the PR working as intended — its goal is that an art edit cannot reach collision. But it does mean the fix location moves: giving a car a hitbox stops being a one-line edit next to the car and becomes a deliberate gameplay-side entry, either promoting specific prop hitboxes into
structuresor adding a gameplay field that references prop ids.Worth settling that classification on #119 before it merges, since changing it afterwards is a data migration rather than an edit.
Scope note
If props do gain collision, #101 and #122 (centre-point collision) are both adjacent: a car-sized AABB is small enough that a point-test diver would clip visibly into it, so extent probably wants sorting first or alongside.