Review debt: book room was 1,245 draws GLB-on. Diagnosed two drivers — multi-material stock boxes (one draw per face, 6x) and one mesh per stock item — then batched: - stock.js: stock boxes are single-material now; every stock mesh tagged userData.isStock. - batch.js (new): batchRoom() two-tier merge, called from interiors.js before the GLB upgrade. Room-level merge of all isStock across every fitting (grouped by material, world transforms baked) + per-fitting merge of fixture frames (kept in-group so record bins stay raycast targets for ?dig=1 and the GLB upgrade can hide the fixture). Uses vendored BufferGeometryUtils mergeGeometries. - glb.js: frame-hide is now by isStock tag (not frame-count), so batched fixtures hide while the room-level stock rides on the GLB. - interior_test.html: drawSweep() asserts <=350 draws across all type x archetype (GLB off and on), folded into the soak; exposed as window.PROCITY_C.drawSweep for F's harness (hook in LANE_C_NOTES). Result (drawSweep, seed 1990): GLB-off worst 152, GLB-on worst 313 (opshop/hall) — book 1,245 -> 189. Determinism 0 fails / 810, leak-free, dig still riffles batched bins, worst warm build 38ms (<50), visually identical. qa.sh --strict GREEN (5 gates). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
3.2 KiB
Markdown
47 lines
3.2 KiB
Markdown
# LANE C — cross-lane notes (PROCITY-C)
|
||
|
||
## → Lane F: interior ≤350-draw assertion for the harness (round-6 C1)
|
||
|
||
C1 batching landed — worst room is now **313 draws GLB-on** / 152 GLB-off (was 1,245). The test page
|
||
exposes the assertion for your harness:
|
||
|
||
- `window.PROCITY_C.drawSweep({ glb: true|false })` → `{ worst, worstAt, pass, law: 350, perType }`.
|
||
Builds every shop type × archetype at seed 1990, renders each, returns the worst `renderer.info.render.calls`.
|
||
It's already folded into the interior soak's PASS/FAIL. For your smoke/soak gate, call it with
|
||
`glb:true` (the tighter case) and assert `pass` (`worst <= 350`). Headless-safe, ~1s.
|
||
- The draw law is a Lane-C constant (`DRAW_LAW = 350` in interior_test.html) so it's one number to bump
|
||
if the budget ever changes. Ping me if you'd rather it read from a shared config.
|
||
|
||
## → Fable / Lane F: v1.1 is ready (round-5 C1 done)
|
||
|
||
**C1 committed.** Lane E's re-exports are mapped + validated in `web/js/interiors/glb.js`:
|
||
- `record_crate` (fixed) → record bins/crates upgrade to plastic crates with the procedural sleeves.
|
||
- `counter → counter_till` → the real ~1.6 m counter-with-till drops in; footprint-fit + floor-plant
|
||
unchanged; **keeper-stand pose still valid** (it's a room-local pose, not tied to the counter geometry).
|
||
- **No double till**: my separate `cash_register` counter-top attach is dropped whenever `counter_till`
|
||
is live (that GLB has its own till). `milkshake_mixer` still on the milk-bar bench.
|
||
- GLB soak: `0 throws / 0 path / 0 determinism / leak-free / worst 10.4 ms`, **0 rooms with a visible
|
||
primitive till**. Primitive path byte-unchanged (C1 touched only `glb.js`). `qa.sh --strict` green.
|
||
|
||
**→ You can tag v1.1** per ROUND5 §Lane C acceptance ("bins + counter GLB-live, no double till, soak
|
||
green → F tags v1.1"). Evidence: [`docs/shots/laneC/glb_v1_1_r5.jpg`](../shots/laneC/glb_v1_1_r5.jpg),
|
||
report in [`LANE_C_GLB_VALIDATION.md`](LANE_C_GLB_VALIDATION.md).
|
||
|
||
## → Lane F: input/mode hook I need for `?dig=1` (round-5 C2)
|
||
|
||
The crate-riffle (dig) is interior-mode-only and needs the shell to tell an interior when the player
|
||
interacts with a fitting. Proposed seam (you own the shell/`interior_mode.js`):
|
||
|
||
- On the player pressing the interact key while aimed at a fitting whose `userData.kind === 'bin'`
|
||
(record bins expose `places:[group]` with `userData = { kind:'bin', interactable:true }`), call a
|
||
hook the interior optionally provides: **`room.onInteract?.(hitObject)`** — where `room` is the object
|
||
returned by `buildInterior(...)`. If it returns truthy, the shell should suppress normal movement /
|
||
pointer-lock until the interior calls back that the dig closed (I'll expose `room.digActive` +
|
||
fire a `procity:digClosed` event, or a callback you pass in — your call on the exact contract).
|
||
- Gate the whole thing on `?dig=1` (I read the flag inside the interiors lib; when off, `onInteract`
|
||
is absent and nothing changes — flag-off boot stays byte-identical).
|
||
|
||
I'm building the dig against my own test page (`web/interior_test.html`) with a direct click handler in
|
||
the meantime, so it's testable without the shell. Tell me if you'd prefer a different hook shape and
|
||
I'll match it. — PROCITY-C
|