A POLAROID button on the scorecard re-renders the dish under the
spotlight, centre-crops it into a cream polaroid frame, and stamps the
day, the grade (coloured), the total, and the judge's line of the day
in italics — 'partly.party/toastsim' in the corner — then downloads as
toastsim-dayN-GRADE.png. The judge's lines are the most quotable thing
in the game; now they travel.
Verified: PNG downloads (real capture — frame cream, photo window lit,
not the black-buffer trap; explicit re-render before toDataURL).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
THE BENEDICT — the first toast+poach composition: day 22 toasts the
bread in the kitchen, then onPopped routes to the poach pot instead of
the drawer (the bruschetta's oven trick, generalized); judgeBenedict
reads THE BREAD off the slice (browning/evenness/char) and THE POACH off
the egg (white/wobble/form), and The Plate sogs BOTH if you serve the
egg undrained — 'You put a wet egg on good toast. Now it is neither.'
Also in the endless rotation (electric pot past day 28).
THE KITCHEN REMEMBERS — recordVerdict on every serve path:
- Streaks: consecutive S grades tracked in the save; the judge notices
at 3 ('I am beginning to suspect competence.'), 5 ('I have started a
file.'), every 5 after, and eulogizes a broken one ('It was 7. We do
not speak of it.').
- The regulars: per-customer visits/last/best in the save. Return
tickets read 'visit №3 — last time: S' (or '...F. they came BACK.'),
and the judge compares: worse-than-last-time and redemption both get
a line. Delivered via JudgeView.extraLines, one-shot per verdict.
Verified live: day 22 starts at the kitchen, poaches after the pop,
combined card 9.1/10 with the architecture line; streak 1->2->3 fires
the line at three; day-20 rebooking shows the visit note.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The near-game, treated with respect (masterplan P3). sim/poach.ts (pure,
rides the heat-source bone): the pot chases the knob on the fuel's lag
and the poach wants the SHIVER (5.8-7.4) — cooler rags the white on the
way in, a rolling boil (>8.2) tears it the whole time. The VORTEX is the
reamer-twist at pot scale: swirl builds it, it DECAYS (swirl then drop,
not swirl then admire), and the strength at the drop is the judged form.
Two-layer set: white first, the yolk only firms once the white is mostly
there — lift in the window (white >=0.85, yolk <=0.35) or you've boiled
an egg the long way. Then DRAIN on the slotted spoon. Stirring a dropped
egg is vandalism (rags it directly).
scenes/poach.ts: WHEEL flame, circular-drag swirl (real angular sweep),
SPACE drop, L lift, hold-to-drain, ENTER serves; vortex streaks that spin
and fade, shiver-vs-boil bubbles, the white gathering tighter as it sets,
a hard yolk going pale. judgePoach: THE POACH (White/Wobble/Form) + The
Drain; the wobble line is the dossier's: 'It should tremble. Like you,
right now.' Day 21 authored + poach in the endless rotation (electric
pot past day 27).
Verified with REAL input: shiver + 91% vortex + lift-at-tremble + drain
= 9.9/10 'it TREMBLES — perfect', 'one neat comet (vortex 91%)'; still
water into a rolling boil, overstayed, undrained = 3.6/10, 'a pot of
rags', 'it does not move at all'.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The egg dossier lands (atlas §1.5). sim/eggs.ts (pure): a carton of six,
each egg rolling freshness off the carton's age; the FLOAT TEST reads it
out (sinks flat / stands up / FLOATS) for free; the CRACK is a strength
window (soft = nothing, window = clean, hard = shell in the whites, fish
the bits out); SEPARATION passes the yolk shell-to-shell (fast breaks it,
old yolks are weaker — the float test also tells you how gently to pass);
a ROTTEN egg cracked blind ruins the bowl: green puff + a seed-varied
synth FART (audio.fart — pitch/length/wobble per egg, the tremolo loses
its nerve halfway). D dumps a ruined bowl; the dump clears the whites but
NOT the judge's memory (rottenCracked survives — no sin-laundering).
An old carton always has at least one liar in it (deterministic; the
glass finds it — floor, not lottery).
scenes/eggbench.ts: drag-to-glass float test, drag-to-rim + HOLD-SPACE
charge crack, alternate arrows to separate, click shell bits to fish.
judgeEggs: THE EGGS (Count/Shell/Whites) + The Nose; full line bank
('There is a GLASS OF WATER on the bench. It exists for exactly this.').
Day 20 authored (pavlova order) + eggs arm in the procedural rotation
(older cartons + need 4 past day 26).
Verified via REAL input: float-all + dodge + patient passes = 10.0/10;
blind rotten crack = the beat, dump recovers whites, The Nose remembers
= 6.3. Sim bars: crack window, float words, old-yolk weakness, fishing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wired steak.ts into a live day. scenes/steakboard.ts — the resting board:
the steak lands off the pan full of juice, DRAG across the grain (pale
fibre lines shown) to slice; cut it before it rests and a dark juice
puddle FLOODS the board. Day 19 routes pan-sear -> resting board -> judge
(pan's two seared faces carry the interior doneness). judgeSteak scores
THE STEAK (The Cook / The Rest / The Cut) + The Board, with a steakhouse-
grandfather line bank ('You cut it the second it left the pan. It bled out
on the board. I watched the whole thing.').
Verified live end-to-end: rested + across grain -> S (9.5); cut hot -> 'it
bled' -> 5.4; rested but along the grain -> 'chewy' -> 6.9. The three acts
each move the grade. Real-drag cutting confirmed (4 slices, flood 6.9).
Also fixed a latent crash: verdictLines could call fill() with an
undefined line when the best-scoring row (e.g. The Board) had no BANK
entry — now guarded.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wired coldchain.ts into a live day. scenes/fridge.ts — a front-view fridge
with zones (freezer drawer / cold back / mid shelves / warm door + glass
shelves), a delivery you drag in, items that recolour as they spoil. Day
17 'put it away': stock it right, ENTER shuts the door (3 days pass),
ENTER again and the inspector opens it. judgeFridge scores THE FRIDGE
(The Cold / Hygiene) + The Waste; hygiene-inspector line bank ('Raw
chicken dripping onto the salad. That is not a fridge, that is a crime
scene with a light in it.').
Sim fix: contamination drips across the whole fridge interior by shelf
height (raw-on-bottom is the real lesson), not just within one zone.
Verified live: day 17 routes to the fridge; good storage (raw low,
perishables cold, RTE high) grades S (10.0); bad storage (raw high in the
warm door, crammed) grades C (3.5) — 38% off, 38% dripped on, 3 wasted.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Routed the pan into a real order: day 16 'pan-sear the mushrooms on the
gas' — butter in, wait for the FOAM not the smoke, land the food, brown
both faces, baste in the noisette. judgePan scores THE SEAR / BOTH SIDES
/ THE BUTTER with a butter-snob line bank. New scorecard group THE PAN;
the cast-iron skillet GLB renders with a fuel-coloured flame.
Balance fix (the floor): food shields the butter once it lands, so a
clean cook keeps the butter at noisette instead of racing to burnt — a
full sear is now winnable. Emergent fuel character kept: induction sears
both sides dead-even (0.016), gas flares the first side so you turn it
early (0.085) — both under the 0.1 bar.
Verified live: day 16 routes to the pan, plays end to end, grades A;
judge nails it ('cooked in different postcodes... foamed not burnt, you
were watching'). Cast-iron pan + butter + searing mushroom on screen.
Heat brief M-H1..M-H6 + M-H4 all shipped and live.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Routed the grill into a real order: day 15 'chuck these on the barbie'
sends the whole day outdoors — bank the coals hot one side / cool the
other, sear each piece then move it to the lee before the fat flares,
serve. judgeGrill scores THE SEAR / THE CHAR / THE GRILL with a char-snob
line bank ('There is no char on this. There is a memory of char. A
rumour.'). New scorecard group THE GRILL + grill/bruschetta order headers.
Balance retune (the floor): RENDER_AT 0.62 lifted above the good-sear
window so a clean sear is reachable with NO flare — sear-then-pull is a
reliable win, only overcooking invites the flames.
Verified end-to-end in-browser: day 15 routes to the grill; careful
sear-and-pull grades S (9.4/10), 100% well-seared, no carbon, no flares;
leaving pieces over the coals chars to carbon (0.9/10, 31 flares). All
M-H6 sim bars still green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Absolute '/assets/...' paths 404 under the /toastsim/ subpath (and the
root /assets/ URL is another game's — returns 200 with wrong content,
the classic partly.party trap). assetUrl() prefixes BASE_URL inside
loadProp + the four direct loads (bench/backdrop textures, title art,
judge portraits). Verified live: JS application/javascript, toaster.glb
4.5MB binary, title_art image/png, title screen renders.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The multi-station order, on the proven bones. Cut the sourdough (M10) →
toast (M1) → roast the tomatoes (toaster generalized) → assemble (garlic rub,
topping point-set, sog clock) → serve. Judge groups The Bread / The Topping /
The Bench. Planning is the mechanic: the temperature clock drifts the two
cheeses on real service time.
What I built on top of the partial work (sims + judge criteria + lines were
already in place and good — kept them):
- Temperature clock WIRED (sim/tempclock.ts): TempClock armed on bruschetta
days, steps every tick while timing; a per-perishable fridge/bench toggle UI
(game.showTempToggle) that reads the judge's own readiness word live; a
toggle costs 8s service (reopening the fridge has teeth). Ticket hints:
"get the brie out now", "leave the parmesan in".
- Roast tomatoes WIRED: OvenView routed after the toast lands on bruschetta
orders (kitchen.onPopped branch → enterOven). Browning Field reused, blister
past 0.6, collapse to sauce past 0.9. oven_tray.glb is absent → loadProp
catch-fallback to the procedural tray (graceful, as designed).
- Assembly scene BUILT (scenes/assembly.ts, new): own toasted garlic-rubbed
slice; G rubs the clove (one-swipe coverage), 1/2/3 drop tomato/cheese/basil
as a point set; ENTER serves. Distribution scored by Clark-Evans (the rind
code, fed the topping list); balance by mass-per-area band.
- Sog clock: rate x wet-mass x moisture / thickness — the doorstop resists,
the thin slice surrenders; the judge presses a finger ("It bends. Toast
should not bend.").
- Day 14 order added; enterOven/enterAssembly/serveBruschetta follow the exact
runNextPrep/enterPrep/enterJuice machinery. Scorecard grouped
bread/topping/bench via judge()'s existing group path.
- Harness (src/dev.ts): t.roast(s,power), t.rub(passes), t.assemble({...}),
t.sogWait(s), t.tempToggle(id), and t.bruschetta() happy path returning the
full grouped stats.
Fixes to the partial work: judge.ts shadowed the `order` param with a local
`const order` (rename → groupRank; would not typecheck); oven.ts material
opacity access typed as Material|Material[] (cast once).
Tuning (measured headless — the pure sims run without three.js):
- assembly SOG_RATE 0.006 → 0.004: doorstop (0.31) under a normal wet load
(5 tomato ~2.1) served promptly (8s) stays CRISP (sog 0.21); dawdled 30s goes
soft (0.77); a thin slice (0.12) bends inside ~15s. The bakery loaf matters.
- assembly MASS_BAND [1.1,2.1] → [2.5,4.5]: the old band scored a normal build
(5t+4c+3b = 3.82 total mass) as an off-band 0; the band now sits around a
proper generous topping. Sparse ~1.3 reads bare, a heap ~6.6 slides off.
- roasting RATE 0.042 kept; comment corrected to the measured window (power 6:
stalls wet to ~26s, blisters 28-36s, collapses past ~40s).
- brie softensInSec 80 (from partial work) kept: out at order start, spreadable
by assembly.
VERIFY (dev build; run in the console):
t.start(); t.bruschetta()
Expected (headless sim + live path):
roast: {mean ~0.70, blister ~1.0, collapse 0, score ~1.0}
distribution: ~1.0 (Clark-Evans R ~1.25, evenly strewn)
balance: {mass ~3.82 in band [2.5,4.5], score ~1.0}
sog: {value ~0.21, word "crisp", score ~0.99}
rub: {coverage ~0.35-0.5, score ~1.0}
temp: {score 1.0 (brie taken out, parmesan left in)}
bench: ~1.0 (clean roast, no slump)
grade A/S, total ~9
Sub-mechanic checks (after t.bruschetta up to the oven, or standalone):
t.roast(26,6) → mean ~0.56, blister ~0 ("under-roasted")
t.roast(42,6) → collapse ~0.69 ("collapsing to sauce")
skip t.tempToggle('brie') → Temperature 0, worst "brie fridge-hard"
thin slice + t.sogWait(15) → sog ~1.0, "it bends"
typecheck clean (tsc --noEmit), vite build clean. node_modules is a symlink to
the main checkout and is deliberately NOT committed (dir-only .gitignore rule
misses the symlink; staged the 12 source files explicitly).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Code-complete and verified headless; NOT wired into a day yet (see brief §0.5).
The core, all reusing the M0-M10 bones:
- sim/ingredients.ts: the cast (tomato/orange/onion/garlic/parmesan/brie/
cucumber/avocado/roast_tomato) with shape, skin slip, flesh moisture+layers,
seeds, sting, temperature needs, gratability.
- sim/cutting.ts: CutSession = ingredient + knife + pattern (halve/slices/
wedges/dice), generalizing the M10 slicing sim. New physics: slip (press a
flat blade on slippery skin and it skates, the aim jumps, juice sprays) and
juice (moisture x speed, so deliberate leaks and frantic hoses).
- sim/mess.ts: the bench is judged. Field over the board UV + a solids list;
the wipe is the butter brush in reverse and mass-conserving, so one pass
smears and the second cleans.
- scenes/prep.ts: aim/bite/saw, deepening seams, pieces fan out, juice stain
texture, instanced solids, live 'bench: clean/smeared/a crime scene'.
- judging.ts: The Pieces (CV, w1.3) + The Bench (w0.9); clarkEvans extracted
for M15's toppings; criteria grouped by station and the card grouped with it.
- lines.ts: 8 lines each, in his voice.
Measured, not asserted:
- Even deliberate slices -> CV ~0, bench mass 0.51.
- Sloppy + frantic (0.3 u/frame) -> CV 0.72, mass 18.8, 16 solids, 'a crime scene'.
- Dinner knife pressed on a tomato without sawing -> skates, aim jumps 0 -> 0.12.
The Best Thing under the same press bites in 7 frames, 0 slips.
- Wipe two passes -> mass 0.51 -> 0.09.
Tuning found by playing: slice CV runs over piece WIDTHS not volumes (round
ingredients make end slices thin by geometry — a perfect cut scored 0.40, which
is a geometry lesson, not a skill test); juice coefficient 0.5 -> 0.1 (the first
tomato flooded the board before the second cut).
Assets: gen_3d retries once per stage, bakery seeds bumped, prep cast queued.
2D landed (bruschetta_hero, wonderslice_bag). 3D is BLOCKED: every bg_remove
fails because m4pro's disk is 100% full. Procedural stand-ins carry the bench.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The loop closes: ticket -> toast -> spread -> ENTER -> verdict -> next day.
- judging.ts: 9 weighted criteria, each reading the same fields the knife was
pushing around, so every line of the scorecard points at something real
("0.78 against 0.68 asked", "thick — thin asked", "28% burnt").
- lines.ts: ~45 lines keyed to whichever criterion actually decided the score,
so the verdict and the scorecard always agree — the verdict just has feelings
about it. MITEY has its own vocabulary.
- judge.ts: the toast turns on a pedestal under a spotlight, grade stamps in,
heatmap toggle for browning/spread. The generated inspector reacts by grade.
- orders.ts: seven handwritten days, then procedural. Day 1 is soft butter on
white; day 7 is a translucent film of MITEY on wet sourdough with fridge-hard
butter and a steak knife.
The find: every art colour was authored as sRGB and fed straight into a linear
lighting pipeline. Linear 0.14 encodes back out to sRGB ~0.4, so "near-black"
MITEY rendered as TAN and saturated butter washed to pale cream. This was the
root cause of the legibility fights in M0 and M2 — I'd been treating the symptom
by pushing the specular around. One line (albedo = pow(albedo, 2.2), mixing
stays in sRGB because that's the space the palette was picked in) and the whole
art direction landed: MITEY is genuinely black, butter is butter, the crust went
from cream to a rich golden brown.
Also: the specular lobe was far too broad. The slice is flat with the light and
camera both above it, so dot(N,H) ~0.98 everywhere and a wide lobe blankets the
whole slice in white. Tightened, so only ridges tilted into the light catch —
which is what a spread actually looks like.
The slice rolls its own lighting and ignores scene lights, so the judge's
spotlight did nothing to it; it now swaps its own rig for presentation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>