guts/web/js/levels/L1_mouth.json
jing 1b5ec767cd [lane C] Round 1: schema v1, levels registry + selfcheck + pacing sim, L2 vertical slice
Data spine:
- Schema v1 ratified (TECH.md, C-owned). Additive over v0: schema/par/next, segment
  name, cross-section placement (theta/rho as a FRACTION of safe radius), spread, span,
  pickup+gate event types, hazard params. STUB_LEVEL synced (that const only, per
  ROUND1 §Lane C.1) — world.hash() unchanged (1bdf001), geometry provably untouched.
- levels/index.js: registry + loader (node+browser, no THREE), real schema selfcheck
  (qa's --selfcheck hook is now live) and a pacing simulator (--sim). Consumes the other
  lanes' contracts live rather than restating them: A's biomes.js for ids and
  wave.amp+breathe, A's SKIN, B's tuning.js hull radius, B's balance.js for scores.
- levels/enemies.js (fiction id -> archetype join table), levels/difficulty.js.

L2_esophagus — the vertical slice, complete: 3600 units, 7 beats, 47 events, 65 enemies,
10 checkpoints, 3 samples, reflux-surge finale. L1/L3 skeletons (shape only).
Anatomy is the level designer: the three real esophageal constrictions are the three
setpieces, and all three enemies are real esophageal pathology (bolus chunk, eosinophilic
esophagitis, candida esophagitis).

Measured (node web/js/levels/index.js --selfcheck|--sim; qa GREEN):
- selfcheck 3/3 valid, exit 0.
- pressure curve 0.27 -> 2.14 -> 4.35 -> 0.69 -> 4.53 -> 6.35 -> 4.40 (breather/pressure/
  spike/breather/pressure/peak/finale).
- par 3:30 vs measured 2:47 speedrun / 3:19 par-pace / 4:22 timid; par.score 9000 of a
  9400 kill budget (95%), computed from B's scores.
- all 10 checkpoint gaps within the <=30s death-cost law (max 28.8s); min clearance 2.73.

Two contract collisions found and resolved (LANE_C_NOTES):
- Biome ids: authored mouth/pharynx/cardia/pylorus; A's registry has six canonical ids and
  rejected all four. A is right — biome = look, segments[].name = anatomy. Conformed.
- Balance: my first enemies.js restated hp/size/speed/score that B owns in balance.js.
  Cut to a join table; index.js reads B's scores via scoreFor().

Caught live: A raised esophagus wave.amp 0.9 -> 1.4 mid-session, making the diaphragmatic
hiatus unflyable (2.33 vs the 2.5 floor). Widened 6.5 -> 6.8. The invariant also failed my
own aortic constriction's first draft (radius 7, symmetric squeeze) -> radius 9, directional.

No in-engine flythrough: ?stub=1&lvl= does not compose (snippet offered to F) and the stub
is single-segment, so it could only render beat 1. The pacing evidence is a kinematic model,
not a playtest — it proves L2 is flyable, paced and survivable, not that it feels good.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 08:53:34 +10:00

55 lines
3.1 KiB
JSON

{
"schema": 1,
"id": "L1_mouth",
"name": "Oral Cavity",
"tagline": "Learn to swim",
"seed": 20260701,
"par": { "time": 300, "score": 6000, "samples": 3 },
"next": "L2_esophagus",
"design": {
"owner": "Lane C",
"status": "SKELETON (round 1) - shape only: biomes, lengths, arenas, gate. Encounters, pickups, samples and tutorial beats are round 2+, after Lane B's arena-mode controller exists. Do not read the (near-empty) events list as a design.",
"identity": "The tutorial, and the only level that is mostly arena. Teaches move / shoot / coat in safety, then examines all three at the epiglottis.",
"anatomy": "Vestibule (outside the teeth) -> oral cavity proper (the arena, ringed by molars) -> oropharynx, narrowing to the epiglottis gate.",
"biome_note": "biome = tissue/look family (Lane A's registry), segments[].name = the anatomy. There is no 'pharynx' biome and there should not be: the oropharynx is deliberately given the ESOPHAGUS palette so the tube turns teal as you approach the epiglottis. The colour shift is the wayfinding - it tells you where you are going before the gate does.",
"scale": "Real oral cavity is ~8cm across; arena radius 90 units = 18cm diameter. Dilated ~2x - much less than L2's 14x, because arenas need room to fight in and the mouth is already a room.",
"round2_plan": "Molar crush-cycles as timed hazards on the arena rim, saliva tides as a periodic current that sweeps the arena, amylase droplets as the tutorial floater. The epiglottis gate is a timing exam: dive on the swallow. 3 samples: one behind the molars, one in a tonsillar crypt, one under the tongue."
},
"segments": [
{
"biome": "oral",
"name": "Vestibule",
"length": 120,
"radius": { "base": 14, "wobble": 0.1 },
"curviness": 0.1,
"flow": 2,
"note": "Injection point. Almost no current - the player's first 120 units are the only place in the game where nothing is pushing them anywhere."
},
{
"biome": "oral",
"name": "Oral Cavity",
"length": 400,
"radius": { "base": 30, "wobble": 0.2 },
"curviness": 0.15,
"flow": 2,
"note": "The arena (see arenas[0]). 6DOF unlocks here. Molar crush-cycles ring it; saliva tides sweep it."
},
{
"biome": "esophagus",
"name": "Oropharynx",
"length": 200,
"radius": { "base": 12, "wobble": 0.2 },
"curviness": 0.35,
"flow": 6,
"note": "The funnel. Mode returns to tube and the current starts to build - the game re-teaching flow just before the gate hands the player to L2. Wears the ESOPHAGUS palette on purpose (see design.biome_note): the walls go teal 200 units before the epiglottis, so the player reads the transition in colour before they read it in a HUD."
}
],
"arenas": [
{ "at": 320, "radius": 90, "biome": "oral", "note": "The oral cavity proper. Spans s 230-410 (sphere of radius 90 centred at s=320)." }
],
"events": [
{ "s": 20, "type": "checkpoint", "name": "Injection Point" },
{ "s": 700, "type": "gate", "id": "epiglottis", "to": "L2_esophagus", "note": "The exam: dive through on the swallow. Timing gate, not a boss." }
]
}