The level the whole game started as, and the only one that isn't authored. robotmonster.party/store/ is assembled procedurally from Postgres (the wowplatter virtual_* schema, served by recordgod), and this game's sites are already data — so tools/import_store.py reads the live shop and emits assets/store/shop_floor.json: the actual 6.66 x 9.51 m floor, 35 racks across 21 archetypes, 278 bins carrying their real genre labels (HARD TRANCE, $12-$15 EURO/ITALO HOUSE), 21,159 records of stock. Levels.record_store() loads it; 'store' joins ORDER as the seventh site. The shop's schema IS the cascade. virtual_crate.rack_id already records which rack holds which bin, so bins arrive frozen and supported_by their rack and none of the structure is authored. To carry that, smashables gained two optional generic keys — 'id' and 'supported_by' — so any level can express support as data. Every existing level is unaffected. Two reconciliations, because a storefront is a renderer: - Mesh sizes are a lie: 21 archetypes share a few stand-in GLBs, so each piece carries 'fit' (the archetype's real dims from the shop's table) and _glb_piece scales the visual to it and builds the collider from it. Also fixed racks being flattened to the floor — pos_y is a piece's BOTTOM, which is what sit_on means, so the ceiling beams, aircon and wall shelves now stay up where they belong. - Nothing collides in a renderer: racks that sat inside each other for years get separated (weighted, so racks barely move and aisles keep their shape — 3 m of correction across 35), rack footprints inset 1.5 cm a side for the few genuinely wedged units, and the importer AUDITS ITS OWN OUTPUT with the same test probe_overlap runs. Bins are deliberately not separated from their rack: cargo inside a container is what the shop means, they spawn frozen, and the audit skips frozen bodies because a frozen body cannot be depenetrated across the room. dev/probe_store.gd: 22 racks hold bins, 255 labels survived, and smashing the rack carrying 22 bins releases exactly those 22 while the other 256 stay frozen. All gates green: smoke clean, 7/7 sites 0.00 m/s, overlap CLEAN, LANE9 probes pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.2 KiB
LANE 10 — SITE 7: MONSTER ROBOT PARTY
The level the whole game started as. Spec'd and executed by Fable, 2026-08-04.
The idea
Every other site is authored. This one is imported from the real shop. The live
storefront at robotmonster.party/store/ is procedurally assembled from Postgres rows
(virtual_rack, virtual_crate, virtual_rack_type*, virtual_crate_type — the
wowplatter schema, now served by recordgod/storegod), and the game's sites are already
data. So Site 7 is not hand-placed: a converter reads the shop and emits a level.
GET https://robotmonster.party/virtual/scene returns the shop floor:
| room | 6.66 m × 9.51 m, 2.89 m ceiling |
| racks | 35 placed, across 21 archetypes |
| crates | 302, every one on a rack |
| labels | real: HARD TRANCE, $12-$15 EURO/ITALO HOUSE, SOUND TRACKS, SPOKEN WORD & COMEDY |
| stock | 22,049 records across the bins (n_items) |
The rack archetype names (wooden-rack-type-long, white-tub-3x3, chiu-long) are the
same names as the GLBs in 3D-STORE/, because both were generated from the same table.
Why this is the best-fitting level in the game
The shop's schema is the cascade. virtual_crate.rack_id already says which rack
holds which bin, so rack.supports = [its crates] falls out of the data — knock a rack
and the real bins that really sit on it really go over. Nothing to author.
Deliverables
1. Generic data-driven cascade (Main.gd, small)
Extend the smashables spec entry with two optional keys so a level can express support
without code: "id" (a name other entries can refer to) and "supported_by" (the id of
the piece holding this one up). Main builds in order, keeps id -> Smashable, and wires
holder.supports.append(piece). Every existing level is unaffected.
2. tools/import_store.py — the converter
Fetches the live scene (--url, or --offline <file>), filters to the shop-floor space,
and emits game/assets/store/shop_floor.json:
- world-space rack positions, re-centred (the shop's origin is a corner; the game centres its bounds on 0)
- each crate placed by
rack_pos + rotate_y(crate_local, rack.rotation_y), carrying its reallabelandn_items - archetype → game GLB + material mapping (tubs are
plastic, timber rackswood, columns and airconsteel) - crates spawn frozen and supported by their rack: they don't jitter at spawn (the stillness gate stays green) and they go live exactly when the rack does
- a measured spawn point — a grid scan for open floor, because a 6.66 × 9.51 room holding 35 racks has very little of it, and spawning inside a rack is not a level
Re-runnable: when the real shop is rearranged, re-run it and the level changes.
3. Levels.record_store() — the site
Loads the JSON and returns a normal Floorplan spec. Timber floor, white walls, the
brand's pink as accent. Added to Levels.ORDER as the seventh site.
Gates
Headless smoke clean · probe_levels 7/7 at 0.00 m/s · probe_overlap CLEAN ·
the LANE9 probes still green. Plus dev/probe_store.gd: the site builds, the rack→crate
cascade is wired, and smashing one rack releases exactly its own bins.