From 0eb48b87e61021c0647b6ff33746f60d40e76007 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 17 Jul 2026 19:46:24 +1000 Subject: [PATCH] Build Brief 1: the puppet, the food, the samurai MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sandoniette (サンドニエット) — 2D shadow-puppet kitchen. Marionette chef on honest string physics, comical food with mass, the samurai as the toastsim judge wearing armor, SHUBATTO string-cut fail state. Milestones M0-M6 with harness-verified exit bars; steals toastsim's discipline (dev harness, pieceCV, judge line banks, verify-or-it-didn't-happen), not its code. Assets: MODELBEAST flux 2D only, shadow-theatre style token, seeds 301+. Co-Authored-By: Claude Fable 5 --- OPUS-BUILD-BRIEF.md | 202 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 OPUS-BUILD-BRIEF.md diff --git a/OPUS-BUILD-BRIEF.md b/OPUS-BUILD-BRIEF.md new file mode 100644 index 0000000..210c1a5 --- /dev/null +++ b/OPUS-BUILD-BRIEF.md @@ -0,0 +1,202 @@ +# サンドニエット SANDONIETTE — Build Brief 1: The Puppet, The Food, The Samurai + +*"SHUBATTO! SANDO-NI-ETTE!!!" — read this file and execute it. It is written to +work cold: a fresh session with no other context should be able to build this +game from here. Sibling project: `~/Documents/toastsim` — do NOT touch it, but +DO steal its discipline (this brief tells you exactly what to steal).* + +## 0. What this game is + +A 2D shadow-puppet kitchen. You are a **silhouette marionette chef** operated +by strings — and only by strings. You cut comical food, stack it into +sandwiches, carry the dish across the stage, and serve it to your one +customer: a giant, permanently unimpressed **samurai**, glaring down at the +kitchen like a health inspector from hell. Do badly — drop things, mangle the +cut, stack a leaning tower, serve late — and his katana unsheathes a little +more. At maximum: **SHUBATTO** — one lightning slash, your strings are cut, +and the chef collapses into a floppy ragdoll amid flying ingredients. Restart. + +The comedy IS the physics: puppeteer lag, pendulum swing, food with mass. +The difficulty is "cunty hard but fair" — Loot Cycle Inc. tension, not +Sekiro. Every failure must be readable as YOUR wobble, never RNG. + +Fictional inspiration stack (for taste, not code): Loot Cycle Inc. (physics +triage under a ticking fail-state), Ratatouille (tiny chef, big kitchen), +1997 bargain-bin PS1 import energy (Pepsi Man voice, broken-Engrish UI). + +## 1. The design law (inherited from TOASTSIM, adapted) + +1. **One game, not minigames in a trench coat.** Cut, carry, stack, serve are + all the same verb — *move a pendulum with intent* — scored by the same + judge. A new mechanic must ride the string sim or improve it for everyone. +2. **The judge is the voice.** The samurai is toastsim's judge generalized: + named criteria with bands, a line bank with 8+ lines per criterion, the + scorecard as the emotional payoff. He speaks subtitled Japanese barks with + deadpan Engrish translations — *"SANDO... ga... yugande iru."* ("The + sandwich. It leans.") +3. **Physics is the comedian, the sim is honest.** No canned animations for + gameplay outcomes — if the tower falls, it falls because the center of + mass left the base. Comedy from real consequences, always. +4. **Nothing ships unverified.** The dev harness drives REAL input + deterministically and every milestone commits with measured numbers. + This is toastsim's single most valuable organ. Transplant it first. +5. **Failure must be readable.** The player must be able to say what they did + wrong from the wreckage alone. If a fail reads as random, it's a bug in + the DESIGN even when the code is correct. + +## 2. Tech decisions (made — don't relitigate) + +- **Vite + TypeScript + Phaser 3 (Matter physics build)**. One engine + dependency; Matter gives joints/constraints for the marionette and food. + Same repo shape as toastsim: `src/sim/` pure logic, `src/scenes/` + presentation, `src/dev.ts` harness, `npm run typecheck` must stay clean. +- **The strings are Verlet-ish chains of small Matter bodies + pin + constraints** (stiffness < 1 so they stretch visibly under abuse). If + Matter's constraint jitter fights back, fall back to pure-math Verlet + ropes rendered as polylines with only the ENDS as Matter bodies — + pre-authorized judgment call. +- **Silhouettes that carry physics are procedural polygons** (flat black + vector shapes with visible pin-joints, like Balinese/Japanese shadow + puppets). Generated art is for backdrops, food faces, the samurai, title — + never for collision shapes. (Toastsim law: silhouettes are gameplay.) +- **Determinism**: fixed-dt stepping (`app.step(dt)` equivalent — Phaser's + `update` driven manually in harness mode), seeded RNG only. No `Date.now()` + in sim code. + +## 3. The bones to build (in order; each is a pure module + a scene + harness verbs) + +### 3.1 `sim/marionette.ts` — the puppet +Classic marionette rig: a **control bar** (the player's proxy) + strings to +head, two hands, two knees. Mouse position = bar position; mouse tilt comes +from horizontal velocity; hold LMB = lower the bar (crouch/reach), release = +lift; RMB or Space = the GRIP (both hands clamp). That's the whole control +surface — depth comes from the pendulum, not the input map. +- Puppet body: 9 segments (head, torso ×2, upper/lower arms, thighs/shins as + single limbs to start), pin joints with angular limits. +- **The lag is the game**: strings transmit force with ~0.15s of felt delay + (stiffness/damping tuned, not a literal buffer). Walk = rhythmic bar sway + that gets the legs swinging. It must feel like Getting Over It's honesty + with Octodad's dignity. +- Harness: `__s.bar(x,y)`, `__s.sway(freq, amp, secs)`, `__s.grip(on)`, + `__s.pose()` → joint angles, `__s.settle()` → frames-to-rest. +- **Exit bar (M1)**: pendulum settle time measured; a scripted sway walks the + puppet 6 stage-units without face-planting; grip picks a box off the floor + 10/10 times in harness. Feel: dangle a hand over a table edge — it should + make you smile before any food exists. + +### 3.2 `sim/food.ts` + cutting +Food = 2D convex-ish polygon bodies with mass, friction, a `face` sprite, +and toastsim-style material params: `skin.resistance`, `flesh.moisture` +(wet food SPLATS — a 2D mess decal + slippery floor patch), `wobble` +(jelly-class food jiggles as soft constraint clusters). +- **The cut**: cleaver in gripped hand; a cut commits when blade-edge speed × + angle-through-food crosses threshold (a slow push SQUASHES — moisture + splats, no cut). Pieces are real bodies with the parent's face split + across them. Cut quality = blade angle + speed + follow-through, scored as + **clean / ragged / crime** (crime = squashed). +- Harness: `__s.spawnFood(id, x)`, `__s.swing(from, to, secs)`, + `__s.cutStats()` → pieces, area CV (toastsim's pieceCV, straight port of + the idea), splat mass. +- **Exit bar (M2)**: a practiced harness swing produces 2 clean pieces with + area CV < 0.1; a slow push produces 0 pieces + splat > 0; a wild fast + swing sends a piece flying offstage (and that's CORRECT). + +### 3.3 `sim/stack.ts` — the sando +Sandwich = ordered layers stacked by carrying pieces onto a plate zone. +Stability is honest Matter stacking, but SCORED: center-of-mass drift per +layer, overhang, lean angle. The order ticket names the target +(bread-filling-bread minimum; later: the katsu sando, the "tower" specials). +- Harness: `__s.stack()` → layers, lean°, COM drift; `__s.nudge(force)` for + the earthquake test. +- **Exit bar (M3)**: 3-layer sando stands; lean° reported; nudge test + topples a bad stack and not a good one; toppled food splats/rolls. + +### 3.4 `sim/samurai.ts` — the judge + the fail state +The anger meter is toastsim's judge wearing armor. **Anger events**: drop +(+small), splat (+medium), crime-cut (+medium), served-wrong (+large), +served-late (+ramps), offstage food (+large). **Cooldown**: a clean serve +sheathes a little. Meter states = katana unsheath stages (0/25/50/75%: +eyebrow → hand-on-hilt → 10cm of blade → full glare, screen vignettes). +- **THE STRING CUT**: at 100% — freeze 300ms, slash line across the screen, + ALL string constraints deleted in one frame, ragdoll collapse, ingredients + launched with the impulse of the slash, gong. Score card over the wreckage. + It must be fast, unfair-FEELING but earned, and funny every single time. +- Serve = dish carried into the counter zone + a bow (hold still 0.5s — the + dwell commit, straight from toastsim). +- Scorecard groups: **THE CUT / THE SANDO / THE SERVICE / THE FLOOR** (the + floor = mess+drops; the bench criterion reborn). 8+ lines each, bilingual + bark + Engrish subtitle. Grade S–D; S = "…umai." and a single approving nod. +- **Exit bar (M4)**: full loop playable — order in, cut, stack, carry, serve, + scored; harness plays a clean run (B or better) and a disaster run (strings + cut) deterministically; numbers in the commit message. + +### 3.5 Orders, days, escalation (M5) +Ticket rail like toastsim's days: Day 1 = one open sando. Escalate +ingredient count, wetness (tomato before you've earned it is cruelty), +required cuts, and the samurai's patience ramp. **One new pressure per day, +never two.** Day N bar: each day introduces its thing and is beatable by the +harness with a scripted-but-honest run. + +### 3.6 The juice (M6) +Title screen: giant brush-stroke 「サンドニエット」, the voice line (text +crawl + gong if no audio yet: **SHUBATTO!! SANDONIETTE!!!**), attract-mode +ragdoll. Shamisen sting + slash whoosh + wet splats (Web Audio, synthesized +or CC0 — no paid assets). Unlockable strings as difficulty modifiers — +**rubber** (bouncy, +lag +comedy), **chain** (heavy, slow, precise), **silk** +(tighter, for cowards) — pre-authorized to defer if M5 lands better without. + +## 4. Assets — MODELBEAST, 2D ONLY (this game needs no meshes) + +Steal `scripts/gen-assets.sh` from toastsim as the template, keep only the +flux path (`run_flux` + `run_cutout`). **Machine facts current as of +2026-07-17** (verified the hard way): client lives at `~/MODELBEAST` (NOT +~/Documents), token is `MB_TOKEN` in `~/Documents/backnforth/.env`, export +`MB_HOST=http://100.89.131.57:8777` (m3ultra queue). Node m4's venvs are +dead — every stage retries up to 10× with 60s pauses until a healthy node +takes the job; keep that loop until told m4pro is healed. + +Style token (fix it, reuse it everywhere): +`"japanese shadow puppet theatre, flat black silhouette with cut-out +details, warm washi paper backdrop, edo period, high contrast, hand-crafted +paper texture"`. + +Batch 1 (fixed seeds, start at 301): washi/shoji stage backdrop, wooden +stage floor boards, the samurai in 5 anger states (SAME seed, expression +phrase varies — the toastsim judge-portrait trick), title brushwork art, +paper order tickets, food FACES (bread, tomato, cheese, katsu, egg — +comical, slightly alarmed), splat decals, the katana slash frame. +Fire asset jobs FIRST, build procedural while they render, `loadProp`-style +catch-fallbacks so the game never blocks on art. + +## 5. What to steal from toastsim, literally + +Open these files and port the PATTERN (not the code — different engine): +- `src/dev.ts` — the harness: real input driven deterministically, helpers + returning stats objects, `window.__s` installer. THE most important file. +- `src/sim/cutting.ts` — pieceCV and the cvWord ladder; material params. +- `src/game/judging.ts` + `lines.ts` — criteria bands, weighted groups, the + line bank shape and its voice discipline. +- `OPUS-BUILD-BRIEF-2.md §0` — the verify discipline and "known traps" habit: + keep a STATUS section at the top of THIS file updated as you go, so any + session can pick up cold. + +## 6. Milestone order and the bar + +M0 bootstrap (vite+ts+phaser+harness skeleton, typecheck green, a Matter box +drops onto the stage floor) → M1 puppet → M2 cutting → M3 stacking → M4 +samurai + full loop → M5 days → M6 juice. One commit per milestone, message += what you measured. Screenshots when visuals change. If a feel is wrong, +fixing feel beats advancing — the three feels that must be RIGHT: **the +dangle** (M1), **the clean chop** (M2), **the string cut** (M4). + +Pre-authorized judgment calls: all tuning constants; Verlet fallback (§2); +segment count on the puppet; deferring string unlockables; cutting a food +type that won't behave. Do NOT add: paid/cloud dependencies, accounts, +telemetry, or 3D. Do not touch `~/Documents/toastsim` or `~/MODELBEAST` +except through `mb`. + +The bet: toastsim proved the bones (harness, honest sim, judge voice, free +assets) make a game feel handmade and alive. Sandoniette bets the same bones +survive transplant into slapstick — that "verified physics comedy" is a +genre, and we can build it in milestones without ever shipping an unfunny +fall or an unfair death.