Commit Graph

12 Commits

Author SHA1 Message Date
type-two
a3337e68e0 Build-out 3: mobile touch, progression + KANSEI, music, night shift
- Mobile: Scale.FIT letterboxing, 3 pointers, thumb GRIP button (touch only),
  drag-low = reach. Desktop input and all battery numbers unchanged.
- Progression: localStorage best-grade per day (game/progress.ts), red hanko
  trophy shelf on the title, KANSEI completion card after day 8 (all stamps,
  click restarts the week). Serve->save->shelf->kansei->day0 verified.
- Day-intro card each live day (name/layers/pressure, fades out).
- Music: seeded pentatonic plucks + taiko heartbeat on setInterval, starts at
  begin, stops dead at the string cut. sfx.chop() thunk on real cuts.
- Night shift: days 4-6 dusk / 7-8 night backdrops (MODELBEAST batch 3 — moon,
  bonsai, lanterns), guarded fallback to noon washi.
- Battery green: M1 87f/8.41u/10-10, M2 cv0 clean, M3 both, days SSSSSSSS,
  live serve@31f, disaster CUT, saved best {0:B} confirmed in localStorage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:30:27 +10:00
type-two
26921eb4ad Build-out 2: the playable loop — detection stacking, live serve, string picker, 8 days
- Sando is zone-DETECTION now: the stack = food bodies physically resting in
  the plate zone, bottom->top. Hand-stacked and harness-stacked sandos are
  judged identically (sando.kinds() is what the judge reads).
- The full live loop: Game.state + updateLive() — ticket clock with late-anger
  (1 bump/3s overdue), bow-dwell serve (hold still 0.5s over a matching
  standing sando -> scorecard), click -> next day; string cut -> ragdoll ->
  fail card -> click retries the same day with fresh strings. setupDay stages
  bread + fillings per order; sins fire live off cutter.onCut + offstage sweep.
- String unlockables: HEMP/RUBBER/CHAIN/SILK picker on the title (stiffness/
  damping multipliers, registry-persisted). Rubber visibly stretches.
- Days 6-8: Tamago (it rolls), Tofu (fragile), THE TOWER (5 layers) + tofu food.
- samurai_bow (same seed): an S serve swaps in the single approving nod.
- Battery: M1 87f/8.41u/10-10, M2 cv0 clean, M3 both, days SSSSSSSS, live
  serve commits at 31f (~0.5s), death->retry + serve->advance verified.
- Known: embedded preview pane never fires rAF (visibilityState hidden) — live
  loop freezes there by browser design; harness steps manually. Real tabs fine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:06:22 +10:00
type-two
4f4b31b914 Deploy to partly.party/sandoniette
- vite.config.ts: dev base '/', build base '/sandoniette/' (subpath deploy).
- Asset loads use import.meta.env.BASE_URL so paths resolve at the subpath
  regardless of trailing slash. vite-env.d.ts for the env types.
- deploy.sh: build -> rsync dist/ -> docker cp into forum-nginx web root
  /usr/share/nginx/html/sandoniette (matches the partly.party games pattern).
- Verified LIVE: index+JS 200, JS served as application/javascript (not the
  HTML-fallback failure), PNGs image/png, title screen renders in-browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:55:56 +10:00
type-two
506a57fa89 Polish: visible strings + control bar, cut-out faces, cleaver
- The soul of a marionette game: draw the 6 strings + the wooden control bar
  every frame (Marionette.stringSegments/barSegment, Stage.drawStrings). Gone
  once the strings are cut. It finally reads as a puppet on strings.
- Procedural cut-out faces: two eyes + a worried 'o' punched into each whole-food
  silhouette in the bright washi tone (backlit-hole look, fits the aesthetic).
  Pieces stay faceless. (The generated face PNGs were full-colour cartoons that
  clashed with the silhouettes — this replaces them.)
- Order ticket HUD (top-left) + a grabbable cleaver whose held edge drives the
  live cutter — swinging it chops food. __s.swingCleaver() proves the wiring:
  a held blade whipped through food cuts clean (tip speed ~150 >> threshold).
- All M1-M6 harness numbers unchanged; typecheck + npm run check + build pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:46:15 +10:00
type-two
077e970b16 M6: juice — title screen, Web Audio SFX (all 6 milestones ship)
- scenes/title.ts: sumi-brush title_art + サンドニエット + pulsing SHUBATTO!!
  SANDONIETTE!!! + click-to-begin. Launched as an overlay over the live stage
  so the harness is up from frame one; __s.startGame() dismisses it.
- game/audio.ts: 100% synthesized Web Audio SFX (gong / slash whoosh / wet
  splat / shamisen), lazy AudioContext, no-op when headless, unblocked on first
  click. Wired: slash+gong on the string cut, splat on squash, shamisen on start.
- Deferred (pre-authorized): food faces (generated art is full-colour cartoons
  that clash with the black-silhouette look — would need regen as cutouts);
  string unlockables (M5 lands fine without). Attract ragdoll -> pulsing title.
- Full M1-M6 battery green; typecheck + npm run check + production build pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:19:12 +10:00
type-two
cdde03bef4 M5: days + escalation — one new pressure per day
- DAYS table (game/game.ts): 5 days, each introduces exactly one pressure —
  basics / +1 ingredient / wetter (2x tomato) / a real cut (katsu) / patience
  ramp (maxSeconds 45->22, angerRamp 1.8). Game.setDay loads order + ramp.
- samurai.ramp scales every sin (sheathing unaffected) — day 5 the samurai
  runs out of patience faster.
- Exit-bar: __s.playAllDays() — every day beatable by a scripted-honest run
  (all S, standing). Ramp bites: day 1 = 7 crime-cuts to strike, day 5 = 4.
  Verified in-browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:12:22 +10:00
type-two
58285712ef M4: the samurai + the full loop — THE STRING CUT
- sim/samurai.ts: anger meter (0..1), events (drop/splat/crimeCut/servedWrong/
  offstage/cleanServe), 5 unsheath stages -> generated portraits, vignette.
- game/judging.ts: 4 groups (THE CUT/SANDO/SERVICE/FLOOR), banded scores,
  grade S-D. game/lines.ts: bilingual samurai barks, 8+/group, deterministic.
- game/game.ts: the run controller — order, serve+verdict, sins -> anger,
  onStrike -> the string cut.
- THE STRING CUT: Marionette.cutStrings() deletes all 6 strings in one frame ->
  ragdoll (pins survive); stage flings loose food with the slash impulse +
  white slash FX + synth gong. Restringable (reset rebuilds).
- Assets wired: bg_washi backdrop + samurai portrait HUD + anger bar. The stage
  now reads as the shadow-puppet theatre.
- Exit-bar: clean run grade S(10) standing; bad run grade D (judge discriminates);
  disaster run strings cut -> ragdoll falls ~180px, samurai fury. Verified
  in-browser (scorecard + string-cut shots) + full M1-M4 battery + npm run check.
- Traps: field 'game' collided with Phaser.Scene.game -> 'session'; walk
  faceplant was per-frame lean>45 (a stride recovers) -> now head-hit-floor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:08:37 +10:00
type-two
7116b71d17 M3: stacking — the sando, scored + earthquake nudge
- sim/stack.ts: ordered layers on a plate zone, honest Matter stacking scored
  by lean/COM-drift/overhang. standing = elevation (a toppled tower loses
  height), not lean angle — a short stack reads 30deg from a 24px step.
- nudge() earthquake discriminates: a centred sando survives (lean 0->2.4),
  a marginally-leaning one (lean 44) topples on the shake.
- Grip pickup fixed: was non-deterministic (trials shared puppet state) and
  unreliable (a sideways bar yank only stretches the arms — they hang from the
  shoulders). Now shiftBodyTo() walks the body over the crate first, and every
  trial resets to home -> a true, deterministic 10/10.
- Exit-bar (full battery): M1 dangle 97f / walk 8.78u upright / grip 10/10;
  M2 chop 2p cv0 clean / push splat 3.28 / wild offstage; M3 good survives,
  bad toppled-by-quake. Verified in-browser + npm run check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 20:52:05 +10:00
type-two
ea2c8c5089 M2: cutting — honest 2D polygon split, materials, splat
- sim/geom.ts: pure convex-polygon split by a line + pieceCV/cvWord ladder.
- sim/food.ts: convex polygon foods (bread/tomato/cheese/katsu/egg) with
  toastsim material params (skin.resistance, flesh.moisture, wobble).
- sim/cutting.ts: blade pass-through detection -> split food into 2 real Matter
  bodies along the chord; slow press on a wet food squashes into a splat decal
  instead. Cut quality clean/ragged/crime by peak speed x chord fraction.
- Two traps fixed: (1) cut line through a vertex made lopsided halves -> split
  now shares on-line verts (regression in geom.check.ts); (2) Matter setVelocity
  is px/STEP not px/s -> piece launch was 60x too fast, flung halves to y=26000.
- Exit-bar: chop -> 2 clean pieces CV 0 (<0.1); push -> 0 pieces + splat 3.28;
  wild swing -> piece offstage. Verified in-browser + npm run check (headless).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 20:38:27 +10:00
type-two
da840b531a M1: the marionette — dangle, walk, sticky grip
- sim/marionette.ts: control bar + 6 soft strings (head/back/2 hands/2 knees)
  over a 9-segment silhouette. Bar snaps to mouse; the felt lag is string
  stiffness<1 (worldConstraints), not an input buffer.
- Feet planted on floor + head+back strings keep the torso upright (no topple);
  earlier pure-pendulum rig spun past 360deg — the back string fixed it.
- Sticky grip: while gripped, any empty hand latches the nearest target on
  contact (puppet.update() each step). Reach = LMB drops the bar.
- Harness verbs: bar/sway/grip/pose/settle + dangle/walk/pickupTest + reset.
- Exit-bar measured: dangle settles 87 frames upright (lean 4.6); walk 8.84
  units upright (>6 req, lean 30<45); grip 10/10. Verified in-browser + shot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 20:18:56 +10:00
type-two
802f738a3d M0: vite+ts+phaser+Matter skeleton, harness, box drops flush
- Phaser 3.90 Matter, autoUpdate:false — deterministic stepSim(dt), harness-driven.
- Render contract: raw Matter body = truth, flat black silhouette follows.
- Rng (mulberry32) ported from toastsim; dev harness on window.__s.
- Exit-bar measured: box drops y=80 -> settles 68 frames -> rests y=608.05,
  gap -0.05px flush on floor, landed:true. Verified in-browser + screenshot.
- scripts/gen-assets.sh (2D-only flux via MODELBEAST) firing in background.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 20:02:27 +10:00
type-two
0eb48b87e6 Build Brief 1: the puppet, the food, the samurai
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 <noreply@anthropic.com>
2026-07-17 19:46:24 +10:00