Commit Graph

13 Commits

Author SHA1 Message Date
type-two
34e08321fd TECHNIQUES: a skill page with no stat sticks on it
The last of P12, and the atlas was emphatic: "+5% score" nodes are
BANNED. A number that quietly improves is not a skill, it is an apology
for the last hour. So every one of these six is either a NEW VERB or a
FLOOR, and you can feel all of them inside one service:

KNIFE — THE PINCH GRIP: you hold the small board still with the heel of
your hand, so its wobble stops reaching your stroke. It still cannot
hold a diced onion; the catalogue is for that. → THE TOURNÉ: seven flat
sides on a barrel the size of your thumb. Nobody needs it. It appears on
the STAGE menu.

HEAT — THE SPARE HAND: you seat the mandoline guard in one movement, so
guarding stops costing handling time. Same safety, none of the fumbling.
→ THE STEADY SWEEP: the torch now leaves a faint ring where its cone
actually lands. It tells you nothing about the score — only about your
own hand, which is the only thing an info tool should ever do.

PALATE — THE PALATE: the tasting spoon stops guessing and the readout
sits still instead of wobbling. The pot is no easier; you are better at
reading it. → CONFIDENT BLIND: cook a whole service under the
Inspector's Shadow and the room tips for the nerve.

Points are earned, never bought: an S on a day, a gold or better in the
drills, and time served. Prerequisites are enforced and the page says
what is missing ("THE PINCH GRIP first") rather than greying out in
silence.

Verified the flags actually reach the benches rather than just sitting
in the save: with two branches learned, prep.pinchGrip and
spice.steadyPalate read true while mandoline.fastGuard and
brulee.showCone read FALSE, then both flipped true the moment their
nodes were learned. The tourné drill was hidden and appeared on unlock.
Carve 9.8, mandoline 9.6, curry 10.0, brûlée 7.5, chips 10.0, grill 9.4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 13:45:03 +10:00
type-two
fa6cbb1276 THE CATALOGUE: money, and the silence of nothing rolling off the edge
P12's core — the meta-layer John asked for on day one. Tips scale with
the grade because that is how it works: an S pays, a D pays in abuse,
and the scorecard says so ('They left you $18.' / 'No tip. He watched
them not leave one.'). The money is deliberately gentle. This is a
kitchen, not a roguelike economy.

And then the tier rule, which is the entire design: CHEAP GEAR ADDS
NOISE AND EVENTS, NEVER A FLAT SCORE TAX. The small board you start on
does not subtract points anywhere. It does two things:

- it SHIFTS under a sawing knife, as literal lateral noise added to the
  stroke, so the wedge and the CV it produces are earned by the hardware
  the way a thin pan's hot spots are;
- it cannot hold a whole diced onion, so past about eight pieces the
  outer ones are balanced on the rim and go on the floor.

Buy the big maple board off the catalogue and both simply stop. That is
the feel the atlas asked for and it is now measurable: the SAME drill,
the same cuts, went 10 of 12 with two on the floor and no medal on the
small board, and 12 of 12 with an S on the maple.

One bug that only existed because of this feature: the drill's short
verdict said 'Finish the cut before you stop the clock' — which is a
plain lie to a cook who DID finish and watched the board throw two
pieces away. It now names the floor when the floor is the reason.

Verified: an S tips $18; $42 buys the maple through the real catalogue
UI leaving $18; the board tier reaches both service prep and drills;
brûlée 7.5, mandoline 9.6, curry 10.0, chips 10.0, grill 9.4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 13:17:48 +10:00
type-two
26a49d26fb THE CURE: day 30 — the first thing you cannot finish today
P10's headline, and the only mechanic in this kitchen that reaches across
days. You pack a slab of salmon in salt and sugar — coverage and evenness,
with no way to take salt back off, the same dose grammar as everything
else — and then you put it on a shelf and LEAVE it. The scorecard judges
the pack and says 'On the shelf, then. 3 days. I will ask.'

Days later the title carries THE CURING SHELF: a jar per cure, counting
up, going green when it is ready. Open it and the verdict is mostly about
the waiting — 'You packed this 3 services ago and left it alone. It
shows. Good.' Open it the same day and it is a salty raw fish. And a bare
patch plus three days on a shelf is not an under-cure, it is a spoil,
which is why coverage is the heaviest row on the pack card.

Two real problems the verification turned up:

1. THE CLOCK WAS WRONG. I first hung cures off maxDay, copying THE
   MOTHER — but maxDay is a PENALTY clock, deliberately frozen when you
   replay old days so the starter cannot starve for it. A cure needs a
   PROGRESS clock, and on maxDay a cook sitting at day 45 replaying day
   30 could never age a jar at all. Added save.daysServed: monotonic,
   incremented by any completed service. Time passes by cooking, which
   is also just true.
2. The pack rate was measured, not guessed — twice. At 2.6 two thorough
   rasters covered the slab perfectly EVENLY at a mean of 0.33, which is
   uniformly below the covered threshold: a flawless pack reading as
   100% bare. 7.0 makes one pass not enough and two right.

Verified end to end on a clean save: pack 8.0 (covered corner to corner),
three real services elapse, shelf shows 'day 3 of 3 · OPEN IT' in green,
opening gives the good note and consumes the jar. Brûlée 7.5, mandoline
9.6, curry 10.0, chips 10.0, eggs 10.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 22:18:56 +10:00
type-two
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>
2026-07-26 20:45:19 +10:00
type-two
d998b74abc THE FACES: every regular gets a portrait, the jar gets three, the dish gets one
Twenty-two assets off the Cloudflare FLUX lane (scripts/gen-art-batch.sh
— idempotent, fixed seed per character, ~5s each, barely a dent in the
10k daily neurons):

- Thirteen regulars on their tickets, clipped into the corner like a
  loyalty card photo: Deidre's floral cardigan, Ray's flat cap, the
  child on tiptoes with a fistful of coins, the bloke from two doors
  down in his dressing gown, the delivery mid-yawn at 6am, the lunch
  rush as three impatient torsos, the pavlova order in her pearls. The
  inspector's ticket uses his own portrait; a name with no face made
  simply shows no frame (onerror removes it).
- THE MOTHER's jar rendered in all three states on the title button:
  bubbling over the rim, sulking under grey liquor, and dead with a
  tiny white surrender flag planted in the crust.
- Six dish heroes on the scorecard beside the ask: the skewers, the
  pan, the sliced rib eye, the whites bowl, the poached egg mid-drip,
  the benedict.

Verified live: pavlova portrait on day 20's ticket, benedict table on
21's, jar_sulking at gap 3, hero_eggs on the eggs scorecard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 02:37:15 +10:00
type-two
ef66e1aa7a THE MOTHER: a sourdough starter that lives in your save and holds a grudge
After five days survived, a jar appears on the title shelf. She wants
feeding — one click — every new day you reach, and the stamps are maxDay
based so replaying old days for the S never starves her. Fed within a
day, toaster-days earn +0.2 and the line 'The starter is lively — the
crumb held. (She did that, not you.)'. Three days forgotten and the jar
sulks, and the crumb knows. Five and she goes still: the button becomes
a funeral, and one click begins THE MOTHER (second of her name) — she
forgives, mostly. The deaths counter never resets. Station days (grill,
pan, cold, steak, eggs, poach) are honestly out of her reach.

Also hardened loadSave against non-finite numbers: NaN and Infinity
stringify to null, and one bad number was enough to rot every derived
stat downstream. Every numeric field now refuses them on the way in.

Verified live: jar born fed at maxDay, starved to a funeral, resurrected
as second-of-her-name (deaths=1 persisted), lively bonus fired on a
bruschetta (9.6 -> 9.8 with the line), sulk line at gap 3, save numbers
intact after the full arc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 01:45:44 +10:00
type-two
a8ae26f2d4 THE SHADOW: hard mode is him saying nothing
Once you have pulled a single S, the title offers THE INSPECTOR'S SHADOW:
arm it and the kitchen's words go dark for the whole run — no state
words, no wobble words, no browning gauge. The ticket still asks and the
controls hint survives, but the read is the face in the corner, the
sound of the pan, and the food itself. Every diegetic channel we built
was practice for playing without the subtitles.

Take an S with the words off and the ledger chip earns a star (S★), the
save remembers it (shadowed, per day, survives loadSave's corruption
filter — which was quietly dropping unknown fields; fixed), and he gives
you the only compliment he has: 'In the silence, too. I have nothing
left to teach you. ★'

Verified live: toggle arms, body.shadow hides the words (computed
visibility checked), S-in-silence writes shadowed.day20, star renders on
the chip after reload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:46:44 +10:00
type-two
c76b62dfa9 THE FOLEY: the kitchen narrates itself, and the bench radio only knows one station
Continuous beds join the one-shot synths: a bed is a looping noise voice a
scene FEEDS every frame, and it starves to silence on its own when the
feeding stops — no scene has to remember to turn sound off. The pan's
sizzle follows butter and heat (burnt butter dulls the voice, 5600Hz down
to 2400); the grill's follows the heat actually UNDER the meat, so the
cool side goes quiet; the pot rumbles up with the water and throws
bubbles — 0.15/s cold, 3/s in the shiver, 13/s at a rolling boil, each
one a little upward chirp because that is what a collapsing bubble does.
The sound IS the thermometer, same doctrine as the words.

And R, anywhere: the bench radio. 84 BPM, Am-F-C-G through a bandpass
shaped like a three-inch speaker, tape wow on every note, a hash-picked
pentatonic melody that never changes — the same tune every service, the
way a real kitchen radio only knows one station. Hiss included.

Verified: radio toggles with the word, pan/grill/poach days run clean
through the live bed paths with the context awake.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:36:13 +10:00
type-two
56389dabab THE DAILY DEAL + SHARE: one deal for everyone, a result you can paste
THE DAILY — a button on the title deals one shared order per real date:
the seed IS the date (FNV hash), so everyone on Earth gets the same deal
today, station and all. Scored into save.daily[date] (best-of), the
campaign day counter untouched — NEXT after a daily returns you to your
regular day. The title button becomes 'THE DAILY ✓ 9.9' once played.
Judge closes with 'The Daily. Same deal for everyone today — come back
tomorrow.'

SHARE — a button on every verdict copies a one-line result to the
clipboard: 'TOASTSIM daily 2026-07-20 — 🥚 S 9.9/10 · partly.party/
toastsim' (station emoji per order; campaign days read 'day N'). The
wordle-paste for toast.

Verified live: daily deals deterministically (same date → same order,
today's is a poach), played to S 9.9, best saved, share text exact,
NEXT preserved campaign day 20, title shows the checkmark.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 16:44:41 +10:00
type-two
64bf04c0b6 The endless mode uses the whole kitchen; the ledger makes days replayable
1) Station-mix procedural days: past day 19 the kitchen deals from every
station it taught — toast ~34%, then prep cuts (technique onion dice past
21), juice (better reamers + more pips later), the grill (4 pieces past
24), the pan (electric arrives 22, induction 26), the rib eye (random
grain, electric past 23), and the fridge delivery. Each with its own
ticket voice. Deals are seeded BY DAY: a reload re-deals the identical
order (no reroll-scumming) and the harness can reproduce any day.

2) THE LEDGER on the title: one chip per reached day with your best grade
stamped on it (S green through F red), click to replay. save.maxDay
tracks furthest-ever progress so replaying day 5 for the S never locks
day 19 away; old saves migrate (maxDay defaults to day).

Verified live: 26-day sweep deals all 7 stations, deterministic re-deals;
chip click starts day 5; procedural day-26 steak (electric fuel ramp)
played end-to-end: rested, cut across a random grain, 9.1/10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 01:27:25 +10:00
type-two
db31273fc9 Deploy-base-aware asset URLs; live at partly.party/toastsim
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>
2026-07-18 15:58:18 +10:00
monster
16860cf5d6 M9: the fresh-eyes pass — played it cold, fixed what a stranger hits
Sat down with it like someone who'd never seen it. Five findings, all
reproduced before fixing, all verified after:

1. The kitchen panel was a cheat console. BREAD/SPREAD/TOOL/BUTTER are the
   order's facts, but the widgets stayed live — you could fetch a soup spoon
   and then quietly re-select the butter knife. Locked during play; the
   browning dial stays yours because it's a real control.

2. The drawer card printed the ANSWER under the silhouette. The entire
   "similar but not identical" puzzle, solved by a caption. The name is gone;
   after ten seconds of fumbling it fades in as a pity: "fine. it's the
   butter knife."

3. Lifting anything above the rim committed it instantly — but fishing means
   lifting blockers, so you could accidentally "choose" whatever you were
   moving aside. Commit now needs 0.45s of continuous hold above the rim,
   which doubles as a beat to compare what you're holding against the
   silhouette. Verified: a wobbly lift takes ~0.95s because dipping below
   the rim resets the clock, and that's correct.

4. Coverage scored 20% on a slice a player had visibly covered corner to
   corner. Root cause: the "covered" floor scaled with the ASKED amount, so
   Coverage and Amount both punished thinness — double jeopardy. Coverage now
   asks its own question (are there bare patches? floor = 0.06 absolute) and
   the same conscientious play scores 84%.

5. Nothing told you how much was on the toast until the verdict. New live
   readout, computed by the judge's own functions: "on the toast: thin —
   normal asked · 84% covered". Watching it, a played-well day 1 went
   8.8 -> 9.0, and the missing 0.2 is named on the card (stripes), not hidden.

Also: the drawer holds 11 pieces dropped down a tighter column (a heap you
rummage in, not an exploded diagram — padded with extra teaspoons, like every
real drawer), it sits on a bench instead of floating in a void, Service is
sim-time rather than wall-clock, and the title mentions the drawer exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 15:42:09 +10:00
monster
5b09f23c7e M5+M6: content, generated assets, title, sound, perf
Content (verified — same dial, same 18s, four breads that disagree):

  bread        4s     9s     18s    char
  white        0.22   0.54   1.08   93%
  multigrain   0.20   0.52   1.06   92%
  raisin       0.30   0.76   1.14   99.8%
  sourdough    0.11   0.33   0.74   14%

Sourdough stalls at half the rate then accelerates hardest (x3.0 vs white's
x2.45) as its water boils off; raisin browns 40% faster and is essentially
carbon by 18s. Seven handwritten days then procedural, day persisted.

Assets, all generated on-device and free, all reproducible from fixed seeds:
- the judge's five expressions (one seed, one description, only the expression
  phrase varying — he stays the same man while his face falls)
- title art, wooden bench, blurred kitchen backdrop
- butter dish / peanut butter / MITEY jars as GLBs, normalised on load
  (recentre, scale to fit, sit on y=0) rather than hand-fixed, so regenerating
  them doesn't mean re-fixing them

The toaster stays procedural: the generated one is prettier but this one has a
lever we can drive and a dial that turns. Judgment call, per the brief.

Sound is synthesised, no samples: clatter is driven by real Rapier contact-force
events and scaled by force, which is the only way a drawer of cutlery can sound
like one. Plus lever clunk, knife scrape pitched by pressure, and the stamp.

Perf, measured (16.7ms is the 60fps budget):
  kitchen 0.99ms/step · drawer 0.12ms · drawer while dragging 0.21ms

Production build: 2.87MB / 1.0MB gzipped, mostly Rapier's inlined wasm + three.

Textures carry colorSpace = SRGBColorSpace explicitly — same class of bug as the
albedo gamma fix in M3, and it washes them out silently if you forget.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:21:06 +10:00