Skip to content

30c level design: three walkable example levels built from the kits (+ kit references, spawn point) - #247

Merged
AlexZ005 merged 2 commits into
feat/1.17from
feat/30c-level-templates
Sep 23, 2026
Merged

AlexZ005 merged 2 commits into
feat/1.17from
feat/30c-level-templates

Conversation

@AlexZ005

Copy link
Copy Markdown
Collaborator

Three walkable General-tab levels built from the round-3 kits — Castle Courtyard, Forest Clearing, Tavern Interior — plus the core they needed.

Commits

  • 508a89f [feat] p1: kit references (src/lib/packRefs.js), a scene spawn point (scenePhysics play.spawn + Configure
    Scene ▸ Physics ▸ Play mode ▸ Spawn point), and a scene load that ends the running simulation.
  • 43f95d5 [feat] p2: three walkable General-tab levels — scripts/level-templates.cjs + author-templates kit object
    type + seed: false.

Staged content

/home/deck/.code/theprototype-app/cloud-lane-30-staging/30c-levels (index.json + templates//{scene.tpscene,thumb.webp}

  • README.md): castle-courtyard 25,152 B · forest-clearing 23,260 B · tavern-interior 23,687 B (~120-200 kit pieces each).

Suites (final battery, fresh server, content re-authored from the committed defs)

suite result
level-templates (NEW) ALL PASS 42 — Templates-modal card load, all pieces refilled, spawn, sim-on-play, luminance castle 0.47 / forest 0.36 / tavern 0.33 (>= 0.25), no black quarter, walls hold, archway+stairs to the rampart, footbridge, hut doorway, balcony stairs, kitchen doorway
pack-refs (NEW) ALL PASS 30 — stub save (Duck 612 B vs 491 KB; kit wall 555 B vs 7,859,921 B), edited = full save, refill with recorded child uuids + shared textures, GLTF round trip stays pristine, unreachable pack keeps the stub, late joiner + live placement on a 2nd peer (ONE stub message on the wire)
templates-modal / author-kit / char-controller / object-sync / scene-physics-state (held) 45 / 59 / 55 / 12 / 37, all ALL PASS
vitest 233/233 (base 222; +levelTemplates 8, +scenePhysicsSpawn 3)
svelte-check 335 / 47 = base, list identical
npm run build green (server stopped)
Counterfactuals: fingerprint always-pristine → 3 red; spawn normalizer → unit red; scene-load sim stop removed → 2nd level
walked through walls/stairs (3 red, levels-run2.log); CF=arch → archway walk red; CF=spawn → spawn check red.
Evidence: ~/.code/lanes-30/after-30c/30c-level-design/ (card-.png, play-.png, final/.log, levels-.log, pack-refs-*.log).

Findings / deviations

  1. A kit piece cannot ride a .tpscene as it is (7.9 MB per wall) → core KIT REFERENCES (QUESTIONS fork 1, taken a).
  2. Pre-existing: loading a scene while a simulation ran left the old world alive and sim-on-play skipped — fixed in
    applySession. NOT fixed (outside the lane): /clear all (the Blank template) mid-run has the same shape.
  3. Desktop play always started at the fixed (0,2,3) (modules DEVX [feat] selectable peer signaling server + public-cloud fallback #27) → play.spawn, omitted at default.
  4. The nature Footbridge walks along its LOCAL Z with a flat 0.85 m deck and no approach (kitbashed with squashed
    sandstone Ramps). The Arch opening is only 0.82 m (collider jambs sit 6 cm inside the stone).

Owed (hardware / people)

  • The look on a real display and the Quest browser (VR spawn is NOT wired: play.spawn is desktop play only).
  • Walking the three levels by hand with a real mouse/keyboard, and in a real two-person session (a joiner refills the
    kit pieces from the pack CDN — needs internet on both).
  • Performance of the castle (~180 pieces, ~350k tris) on a Quest.

For the integrator

  • Release ordering (QUESTIONS fork 2): the three rows need a core with packRefs AND the three pack PRs merged +
    packs@format-1 retagged. Publish the rows (staging folder above) into the scenes repo templates in that release.
  • CHANGELOG: "Three walkable example levels in Templates ▸ General (Castle Courtyard, Forest Clearing, Tavern Interior),
    built from the new kits." · "Kit pieces are saved as references to their pack: a level of 150 pieces is ~25 KB, and
    every copy shares its textures." · "Configure Scene ▸ Physics ▸ Play mode ▸ Spawn point." · "Fix: loading a scene
    while the simulation runs no longer leaves the old physics world behind."
  • CLAUDE.md architecture entry for src/lib/packRefs.js (the stub/refill/pristine-fingerprint contract; the four
    paths: save + wire use stubs, autosave GLTF and undo stay full) and a gotcha: "a template's toJSON of a GLB import
    writes PNG data URLs, one per top-level child — 7.9 MB per kit wall".
  • Docs page draft: ~/.code/lanes-30/after-30c/30c-level-design/level-design.md (docs site, beside the kits' pages).
  • Known limits recorded in packRefs.js: a fresh Explorer placement parses its own copy (sharing starts after a
    save/reopen); an older build reading a stub gets an empty group.

🤖 Generated with Claude Code

AlexZ005 and others added 2 commits September 23, 2026 21:25
…e load that ends the run

- packRefs.js (new leaf): a piece placed from a pack carries userData.packRef
  {pack, item, path, hash, kids}; a save (buildSessionPayload / buildSelectionPayload),
  a session-load broadcast, a late joiner's sync and a live placement write a PRISTINE
  piece as a hollow STUB; the loader and every peer refill it from PACKS_BASE/<path>,
  parsed once per piece, textures shared across every copy (and across pieces whose
  images are byte-identical). Pristine is MEASURED: a fingerprint of the descendants
  (structure, local matrices, geometry checksums, material params, an 8x8 sample of every
  texture) against the parsed file; an edited piece saves in full as before. An
  unreachable pack keeps the stub and saves it back (never silently dropped).
- Measured: one kit wall was 7,859,921 B as a toJSON element (PNG data URLs, one
  toJSON per top-level child) and is 555 B as a stub; a level of ~180 pieces is ~25 KB.
- Placement stamps the reference (Explorer double-click + viewport drop -> importFile
  opts.packRef, before addImported replicates); the wire sends the stub (sendObjects
  null-peer branch + sendObject; countObjects does not count refilled children).
- scenePhysics play.spawn {pos, yaw} (OMITTED at default, so saves are byte-identical);
  PointerLockControls puts the player there on entering play (no dungeon);
  Configure Scene > Physics > Play mode > Spawn point: Set to the view's focus / Clear.
- applySession stops a running LOCAL simulation before it wipes the scene (quietly, the
  yielded way): the old world kept bodies for the wiped objects and none for the new
  ones, and sim-on-play skipped the start because a sim was "already running" — so the
  second level played in a session was walked THROUGH (levels-run2.log).
- App.svelte debug hook tails 215/215/215 (+packRefs); startPackRefs beside
  startShadowDefaults.

Suites: pack-refs (NEW) 30/30 (single page + a late joiner + a live placement to a
second peer + a real kit wall when the build serves the kit). Unit scenePhysicsSpawn
3/3; vitest 233/233 (base 222).
Counterfactuals: sameFingerprint -> always true: 3 red (colour, in-place vertex, moved
child all saved as stubs); spawnOf spread removed: unit red; the scene-load stop removed:
the second level's walls/stairs walked through (level suite, 3 red).
svelte-check 335/47 = base (list identical); build green (server stopped).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e kits

- scripts/level-templates.cjs: Castle Courtyard (curtain walls, a gate between pillars,
  two three-storey round towers, a rampart terrace reached by stairs through an archway,
  a paved avenue to a well, a market stall, trees; a lit afternoon sky), Forest Clearing
  (a stone path, a footbridge over a pond neck kitbashed with sandstone ramps, a 4 x 4 m
  plaster hut from the architecture kit, a walkable mound, a cliff, two rings of trees;
  late-morning sky, fog that closes in past the tree line), Tavern Interior (a
  double-height hall with a balcony, a kitchen behind a partition doorway with a loft
  above it, oak stairs, a bar, furniture; warm lamps + a warm hemisphere).
  Every level: a spawn point, sim-on-play, ONE walk-mode Character Controller node,
  dynamic props, and colliders that match the pieces — custom compound shapes for the
  archway/doorways (jambs + lintel), stairs and ramps (wedges), trees (trunks, MEASURED
  off-centre), the footbridge (deck + rails) and the mound (a measured hull that runs out
  past its 0.37 m lip); grass, flowers, rugs, water are sensors.
- author-templates.cjs: a `kit` object type (a pack item as a REFERENCE stub, resolved
  through the pack's own default.json on PACKS_BASE, refilled and awaited before the card
  renders — the run refuses a level whose pack is unreachable), `seed: false` (kit levels
  stay out of the offline seed), and a kit level's card CLONES the scene instead of the
  toJSON round trip (which is the 7.9 MB-per-wall cost). Every other def is unchanged.
- Measurements that shaped the layouts: the Arch opening is +/-0.408 m (the collider's
  jambs sit 6 cm inside the stone: a grazing walk stopped 1 run in 2); the Footbridge
  walks along its LOCAL Z with a flat 0.85 m deck and no approach.

Suites: level-templates (NEW) ALL PASS 42 (all three levels: loads from the Templates
modal, every piece refilled, spawn + sim-on-play, centre luminance castle 0.47 / forest
0.36 / tavern 0.33 >= 0.25, no black quarter, walls hold, archway/stairs/rampart,
footbridge, hut doorway, balcony stairs, kitchen doorway pass); castle x2 green after
the arch fix. Unit levelTemplates 8/8.
Counterfactuals: CF=arch (the arch's custom collider removed): the archway walk red;
CF=spawn (the spawn cleared): the spawn check red.
svelte-check 335/47 = base; build green. Staged content:
/home/deck/.code/theprototype-app/cloud-lane-30-staging/30c-levels.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 merged commit 46b48ed into feat/1.17 Sep 23, 2026
4 checks passed
@AlexZ005
AlexZ005 deleted the feat/30c-level-templates branch September 23, 2026 22:38
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