cebff4bd69
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cebff4bd69 |
STAGE: culinary school — one board, one spec, one clock
The drills mode from P8, and the one John asked for by name. No customer, no ticket, no day: a spec, a board and a stopwatch. Three to start — brunoise the onion, bâtonnets off a bell pepper, twelve cucumber rounds — each with four medal tiers that must be earned on BOTH axes at once. You do not get gold for being fast and ragged, and you do not get gold for being immaculate and late, and the card names the single thing standing between this run and the next tier: "Even enough for gold. 6s too slow for it." A drill is a SPEC, not a separate game — it runs the real prep bench through the real cutting sim, and pieceCV was already sitting there doing exactly the measurement a spec needs. Sealed off from the campaign on purpose: no order, no streak, no starter, no regulars, no verdict. Checked rather than assumed — after a full drill run, save.day, save.total and save.streak were byte-identical and the ONLY thing written was the drill's own line in the medal book, which keeps your best (a better medal, or the same medal faster). Two things the build surfaced: - The prep bench only accepts ENTER when the pattern is COMPLETE, which is right for service (the order wants the whole cut) but made "7 of 16. Finish the cut before you stop the clock" a verdict nothing could ever reach. Drills now allow the panic-stop via an explicit allowEarlyServe flag; service explicitly sets it false, so an order can never be half-served. - The title was built in the constructor and nowhere else, so there was no way back from anything. Extracted showTitle(). Also: a recorded run with no medal was labelled "not attempted", which is a small lie about the worst runs. It says "attempted — no medal" now. Verified: S on the cucumber rounds books S·4s on the title; a short brunoise books no medal and says why; service prep still refuses an early ENTER; bruschetta 9.6, grill 9.4, eggs 10.0, curry 10.0, greens 10.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8f5641a57f |
Pieces render true to pattern: dice = chunk grid, wedges = exploded sectors
Dice show the criss-cross (drawn 1.6x true size — honest proportions vanish against the board at game camera distance); wedges explode 0.28 from center so gaps and uneven angles read. Slices keep the fan. Plus scripts/deploy.sh (partly.party/toastsim, cratewars pattern) — pending an ssh permission grant to run the final docker cp step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
e1e5ce823a |
M12 routed + M14 onions: the juice detour and the stop-line
Stage 2 Lane B. Two jobs, both riding the existing prep-bench machinery
(prepQueue drained through enterPrep/runNextPrep before enterToastFlow, results
folded into the judged scorecard) — extended, not rebuilt.
JOB 1 — the juice station is a real day now.
- orders.ts: PrepStep is a discriminated union; new 'juice' kind carries the
juicer tier + optional halve + fixed seed count. Day 12 (Deidre): "fresh
orange juice with the toast" — juicer comes from the ORDER (Pyramid Classic,
the starter, no seed moat), the halve is left clean (dead-centre) so the twist
is the whole test; the halve->juice chain stays M12's own later order. seeds
fixed at 5 so Pips is a skill row, not a lottery.
- game.ts: the Game owns a JuiceView (like PrepView). runNextPrep branches on
step kind; enterJuice mirrors enterPrep. The glass is scored on its own
criteria (juiceCriteria) folded into judge() via a new `extra` param; its
spray joins The Bench through the same prepResult path a cut order uses.
- lines.ts: JUICE_LINES merged into the verdict BANK; juicerRecognitionLine
wired off order.prep (the Juicernaut announces itself before the verdict).
- dev.ts: t.juice(revs, press) drives the REAL routed game.juiceView (not the
__tj sandbox); follow with t.handoff() to serve the glass.
JOB 2 — M14 onions, the technique test (brief section 6).
- The stop-line rides the existing cut sim with one additive hook: on the
onion dice's root-ward first pass, RELEASING the blade mid-saw commits a cut
that stops short of the root (liftKnife now commits + returns its frame).
finishCut is factored so a stopped cut and a through cut share the path.
Saw all the way (progress hits 1) and the root severs -> the layers scatter.
Gated behind pattern { kind:'dice', root:true } so day 10's plain dice
(M11-verified) is untouched. That is the "ending a cut deliberately short"
feel — restraint one cut at a time, not a menu choice.
- Sting clock: stingStep raises sting with open cut-surface x time x how much
you crushed rather than sliced (blunt/squashy = tear gas). Rendered as a
cheap full-screen DOM overlay (radial vignette + backdrop blur) that grows
with sting, plus an "eyes fine/watering/streaming" readout and a green
stop-line marker on the onion.
- Scored as two new rows (judging.ts): The Dice (stem discipline, w1.3) and
The Eyes (sting endured, w0.7). The Pieces (CV) stays the criss-cross
spacing, so the two skills are told apart. Lines for 'dice' and 'sting'.
- Day 13 (the inspector): dice the onion PROPERLY with The Best Thing.
- dev.ts: t.chop gains stopAt; t.diceOnion({stopAt|through}) drives both.
Constants and why:
- STOP_MIN 0.15 — a release shallower than this is a fumble, not a stop.
- STING_RATE 0.02 — a sharp, quick clean dice finishes ~0.05 (clear-eyed);
the same onion left open 10s floods to 1.0. Sharp+fast wins, dawdling blinds.
- stemDiscipline band: full marks 0.55..0.9 depth, graze 0.9..0.97, through
>=0.97 = confetti; undercut <0.55 = joined chunks.
- t.diceOnion default stopAt 0.8 -> commits ~0.85, level with the 0.82 marker.
Verified headless (deterministic; sim is pure):
Day 12 juice, t.day(12); t.juice(3, 0.7):
extracted 0.728, theoretical 1.0, yieldOfReachable 0.728, pips 4,
seedsCaught 0 (Classic has no moat -> serve the pips or fish them).
Criteria: The Juice score 0.631 (w1.3), Pips 0.200 (w1.1). t.handoff()
serves the glass; the toast half then runs as any non-loaf day, and the
scorecard shows THE PREP (The Juice, Pips, The Bench) beside THE TOAST/SPREAD.
Day 13 onion, t.day(13); t.diceOnion(): // proper dice, stop short
16 pieces, CV 0, rootThrough 0, stopDepths [0.85,0.85,0.85],
The Dice score 1.000, sting 0.052 -> The Eyes 0.939 ("clear-eyed").
t.day(13); t.diceOnion({ through: true }): // cut through the root
rootThrough 3, stopDepths [1,1,1], The Dice score 0.000 (confetti line
fires), CV still 0 -> the disaster reads on The Dice, not a lying CV.
Sting accumulation: after a proper dice, t.run(600) (10s idle) ->
sting 0.052 -> 1.000 ("blind"), The Eyes 0.939 -> 0.000. The cut onion
stings while it sits, exactly as it should.
Plain dice unaffected: onion { kind:'dice', n:4 } (no root) -> 16 pieces,
CV 0, rootThrough 0, phase done — M11's day 10 is byte-for-byte the same test.
typecheck clean, npm run build clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
ee1eb8ebc3 |
Mushrooms: three varieties for the prep bench, plus gen-assets machine fixes
- button_mushroom / portobello / king_oyster in the ingredient cast: slippery skins (0.55-0.8, the tomato treatment), soft flesh, portobello gills layered and weeping; new 'mushroom' cap-and-stem silhouette. - Verified via harness: dinner knife pressed on a button skates (1 slip, cut lands 0.157 off-aim; tomato baseline 2 slips / 0.218), The Best Thing bites clean through under the same press, sawing properly cuts center with zero slips. - gen-assets.sh: find MODELBEAST at ~/MODELBEAST, token from backnforth/.env, MB_HOST to the m3ultra queue; every mb stage retries 10x with 60s pause because m4pro's venvs are gone (ponytail-marked, remove when m4pro is healed). - launch.json: port 5273 (5173 taken by another session's server). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
faf196657e |
M11 WIP: the prep bench core — one board, and it remembers
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> |