Commit Graph

3 Commits

Author SHA1 Message Date
monster
ff006e65db M8: crunchy vs smooth, and the jar that separates
Natural peanut butter stratifies while it sits. The jar carries the state:
strat 0..1, set per order (smooth 0.75, crunchy 0.9 — chunks sink). The first
unstirred dip takes the oil slick off the top; the ones after it dig into what
the oil left behind. Verified dip trace, no stirring: 0.875, 0.669, 0.462,
0.256. Swirl the knife in the jar (~2.5 circles of angular sweep; holding still
stirs nothing) and every dip is 0.5. Stirring costs time, and time costs toast
warmth — the mechanic pays the same tax as everything else.

Consistency pushes back through the physics that already exist: an oily load
multiplies the yield down (glides at any angle, goes on thin), a dry one
multiplies it up (fights like cold butter, tears). The shader shows it — slick
is dark and shiny, grout is pale and matte.

The judge reads what LANDED, not what the jar was: every deposit remembers the
oil it landed at, and the criterion scores the mass-weighted mean AND stdev.
The stdev is the design catch, found by verification: a slick strip and a grout
strip average to 0.54 — "just right" — and the first cut scored the lazy play
as if the jar had been stirred. Nobody eats the average:

  never stirred, strips   oil 0.54 ±0.23  "slick here, grout there"  C
  one slick dip, whole    oil 0.87 ±0.00  "a slick"
  stirred first           oil 0.50 ±0.00  "just right"

Crunchy reuses the particle system wholesale — chunks ride the knife, shed per
stroke-distance, get judged with the same Clark–Evans index ("Peanut chunks —
21 bits, evenly strewn (R 1.20)"), and the rind line bank is genericised via a
{bits} placeholder so he complains correctly about either.

Day 6 is crunchy now ("the PROPER kind"), the ticket warns when a jar has been
sitting, and the JAR bar shows how mixed it is. Five new judge lines, including
"You did not stir the jar. The jar knows. I know."

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:03:57 +10:00
monster
70922bd855 M7: marmalade — rind, and a judge who scores its distribution
A particulate spread. The jelly is ordinary rheology; the rind is discrete
solids that ride the knife and drop off per unit of stroke DISTANCE, not per
second — a dabbing knife makes a pile, a moving knife lays a trail, and since
the shed rate scales with what's left on the blade, one dip cannot cover the
slice. Even rind takes several dips placed with intent. Scraping picks bits
back up (60% survive the blade), so a clump can be argued with.

The judge scores the scatter with the Clark–Evans nearest-neighbour index over
the bread's own area, and quotes it: R near 0 is one clump, 1 is random, above
1 is deliberate. Verified end to end on day 8:

  dab in a corner      8 bits   "one clump (R 0.24)"        drags grade to B
  three placed dips    24 bits  "evenly strewn (R 1.17)"    A, 8.9/10

First cut shed per-second; even careful strokes dumped the whole load in the
first half-second and scored "clumped (R 0.50)". Distance-based shedding is
what makes evenness the reward for technique rather than luck.

Rind renders as instanced chunks parented to the slice mesh, so it rides the
pop, the landing, and the pedestal turn. Points, not a field: the judge wants
nearest-neighbour statistics, and those want points.

Same sRGB trap as M3, new spot: the instanced material's colour was passed as
raw floats, which the renderer reads as linear — candied orange rendered as
pale butter. setRGB(..., SRGBColorSpace).

New content: day 8 handwritten (Deidre wants a piece in every bite), marmalade
in the procedural pool, five rind-district lines for the judge, and a marmalade
jar GLB generated on-device like everything else, with a plain-glass fallback
while it loads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:45:57 +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