Round 3 orders, all six. The validator move landed in 4803b6a (swept into
LANE-SCREEN's commit by the shared index); this is the rest.
- heat retune: round 2's numbers were below the sim's always-on cooling, so
nothing could ever warm up. Decoder now 100 gen at 0.0033 heat / 0.001 cool
-> throttles 10.2s, scrams 14.5s, 23.9s cycle, 25.8/s average (1.29x the
ASIC). Verified against LANE-SIM's real sim, not just arithmetic.
- powerGen had to move: the scram/restart hysteresis forces ~30% duty, so at
55 gen the decoder averaged worse than a steady ASIC and nobody would build
one.
- two new tests refuse decorative heat (per-tick and per-craft). They caught a
fresh instance of the same bug in chart-stco-map before it shipped.
- bufferCap 240 -> 300: one tank now covers exactly one decoder scram.
- ASIC COOLER spec'd (aura deferred to M4, no contract field requested yet);
THE MUXER + moov brain sub-lines; reel + broadcast era tech.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12 KiB
CANON-DELTA — everything in data/ that isn't in the codex yet
LANE-DATA owns this file. ../../docs/FKTRY_LORE.md is canon; this is the ledger of
where the data has run ahead of it. The orchestrator absorbs these into the lore doc in
one pass later. Until then, this is the single place canon-drift is allowed to live.
Rule for adding an entry: the codex was silent, I invented in its voice, and I wrote down why it is consistent with the codex — not just what I did. If a future lore pass disagrees, the codex wins and the data changes.
Canonized in round 1 (orchestrator: "CANONIZED", round 2 review)
| Thing | Kind | Why it fits |
|---|---|---|
press-anchor-slab |
recipe (dct-press) | The press run backwards is an IDCT, and an IDCT is a complete picture. §4 already runs the field loom and the telecine puller in reverse, so reversibility is established machine behaviour. This is where I-frames come from. |
color-plate |
item | §4 demosaicer literally outputs "a smooth colour sheet"; it needed an id. |
v-hold-roll |
item | §1 Broadcast Shelf has "v-hold faults that make whole regions periodically roll upward". Bottling one gives the ANALOG PACK's "combing + v-hold roll + static" triptych three real ingredients. |
artifact-bottler |
machine | §2 calls the science packs "a bottled artifact triptych" but names no bottling plant. Something has to hold the bottle. |
lane-splitter |
machine | The contract has kind: 'splitter' and belts need routing, but §4 only ever calls the DEMUXER "the first splitter" — which is a refinery, not a junction. |
Added in round 2
The container line (unblocks stream-hex-splicing)
§2 names the CONTAINER PACK's contents ("moov shard + offset ribbon + sync key") and §7 names the moov brain's parts, but nothing said where they come from. The chain now mirrors what the parts actually are in a real container:
| Thing | Kind | Why it fits |
|---|---|---|
moov-shard |
item | The index, not the payload. |
offset-ribbon |
item | The stco map — a ribbon of byte offsets. |
sync-key |
item | The stss table lists which frames are keyframes, i.e. I-frames. |
demux-container |
recipe (demuxer) | The demuxer is the machine that separates index from payload. 8 ore → 2 shards: the index is a rounding error next to the mdat, which is the joke and also the truth. |
spool-offset-ribbon |
recipe (gop-assembler) | The assembler is the only machine that knows where each frame starts, because it put them there. |
cut-sync-key |
recipe (artifact-bottler) | Cut from an anchor slab, because stss is a list of anchors. |
bottle-container-pack |
recipe | Assembles the §2 triptych. |
Chicken-and-egg check: §4 says the hex splicer "Requires CONTAINER PACK research", so the container line deliberately does not route through the splicer. It is demuxer → assembler → bottler, all machines you already own.
The bloom line
§3 sells bloom "by intensity grade; grade-5 bloom visibly tries to escape its canister in
one direction" — five grades, one item each, bloom-grade-1..5.
bloom-concentrateis kept and redefined as the raw, ungraded draw-off from a loop (tap-bloom). It was not deleted because LANE-SCREEN hardcodes it insrc/screen/corruptionMap.ts:54and its test — deleting it would have broken another lane's suite mid-round. Grading now consumes it.- The recipe id
bloom-grade-3survives from round 1 but now produces the itembloom-grade-3, so the id finally means what it says.tap-bloomis the renamed round-1bloom-grade-3recipe. Deprecation notice: no recipe id was retired, butbloom-grade-3changed its inputs/outputs entirely. Nothing outsidedata/referenced it (checked: only my owntech.json). - Escalation is in delta wafers, not exotic inputs — a grade-5 canister is 2 raw bloom + 18 wafers of compounding, which is §4's "contents compound each lap" priced honestly.
Added in round 3
THE MUXER and the moov brain (§7, data-first — mechanics are M4's)
§7 names the parts and says each is "its own late-game production line", but never said what makes them. Each part is now made by the machine that already owns that knowledge, which is the whole joke: the container is assembled by the factory that made the mess.
| Thing | Made by | Why that machine |
|---|---|---|
stsz-ledger |
gop-assembler | The sample-size table. The assembler packed the crates, so it knows how big each one was. |
stco-map |
hex-splicer | The chunk-offset map — byte offsets are the splicer's entire domain. It nudges them for a living; here it writes them down honestly, under protest. |
stts-metronome |
telecine-puller | Time-to-sample is a cadence, and the puller is the cadence machine. Built from judder cams, so the metronome ticks 3:2. |
stss-keyring |
artifact-bottler | The sync-sample table is a list of I-frames, so it is literally forged from anchor slabs. |
ftyp-seal |
artifact-bottler | §7 names the ftyp seal as part of the container; it needed a source. |
moov-brain |
muxer | The four converge. 300 ticks. |
megaglitch |
muxer | mux-container: brain + seal + 500 mdat ore + 100 melt, 900 ticks. §7's "colossal composited corruption" priced like one. |
muxer is kind: 'crafter', not 'shipper' — it builds the megaglitch, and you still
have to ship the thing. 5×5, the biggest footprint in the game, per "hero structure".
ASIC COOLER (spec'd, deliberately not yet mechanical)
§2 HEAT says heat is "Vented by ASIC coolers" — a machine the codex names and never
specifies. Authored now so the data is ready; the mechanic is deferred to M4, when
SIM builds auras. Gated behind broadcast-asic-cooling so it can't appear early.
- Intended mechanic (SIM, when auras exist): an adjacency aura — every machine whose
footprint touches the cooler's 2×2 gets the cooler's
coolPerTick(0.02) instead of its own. That turns the software decoder from a 30%-duty throb into something you can engineer around: ring your decoders with coolers and pay for it in floor space and build cost. This needs a contract change (coolRadius?, or akind: 'cooler') — not requesting it until SIM is ready to build it, since a contract field nobody reads is the same decorative trap heat just fell into. - Authored as
kind: 'power'withpowerGen: 5because there is no cooler kind and a lie is worse than a stretch: it is an ASIC, ASICs decode, decoding makes bandwidth. It vents far more than it earns. Ifkind: 'cooler'ever lands, this moves. - Its own
coolPerTick: 0.02is inert today (nothing heats it) and is there to state the intended aura strength in data rather than in prose.
The numbers, and the arithmetic behind them
The reference M1 chain (measured, not guessed)
Computed from data/*.json against the machine list in SIM's meltChain()
(src/sim/sim.test.ts), with the two recipes that test hand-dials applied:
idle draw (every machine's powerDraw) 57 /s
+ active recipe draw at full tilt 39 /s
= peak draw 96 /s
- compression paid back (quantize -6, 4:2:2 -4, 4:2:0 -8) 18 /s
= net peak demand 78 /s
Units (RULED round 3): gen/draw are bandwidth per second; stored and
bufferCap are bandwidth-seconds. My round-2 assumption held.
Round 2's heat was decorative — what went wrong
Worth writing down, because it's a trap anyone can fall into. I sized round 2's
heatPerTick: 0.0025 against no cooling. SIM then implemented heat with cooling shed
every tick, active or not (HEAT_DISSIPATION = 0.004). So the decoder shed 0.004 and
banked 0.0025: net −0.0015/tick. It could never warm up. The number looked like a
mechanic and was a comment.
The lesson is now a test (every heat source out-heats its own cooling), and it caught a
second instance immediately: chart-stco-map banked 0.06 heat over 90 ticks while the
splicer shed 0.09 — I'd authored a fresh decorative number in this very round.
Anything with a heat number must beat its own machine's cooling, or it isn't a mechanic. The validator now refuses both forms (per-tick machine heat, per-craft recipe heat).
The software decoder: powerGen 55 → 100, heatPerTick 0.0033, coolPerTick 0.001
Net while running = 0.0033 − 0.001 = 0.0023/tick. Against SIM's curve (throttle 0.7, scram 1.0, restart 0.5):
throttle, from cold 0.7 / 0.0023 / 30 = 10.1 s (target ~10 s)
scram, from cold 1.0 / 0.0023 / 30 = 14.5 s (target 13-15 s)
steady cycle, up 0.5 / 0.0023 / 30 = 7.25 s (heat 0.5 -> 1.0)
steady cycle, down 0.5 / 0.001 / 30 = 16.67 s (cools 1.0 -> restart 0.5)
period 23.9 s (target ~25 s)
duty 30.3 %
Why the decoder cools slowly (0.001, vs the sim's 0.004 default): it is an overclocked tower PC held together with zip ties and prayer (§4). It is the worst-cooled object in the factory. The ASIC has "a huge heatsink afro" and no heat source at all.
Why powerGen had to nearly double. SIM's hysteresis (scram at 1.0, restart at 0.5) means any machine that throttles at ~10 s spends ~70% of its life cooling. At round 2's 55 gen that's an average of ~14/s — strictly worse than the ASIC's steady 20, so nobody would ever build one and "burst gen" would be a lie. Averaged properly (generation is throttled linearly 1.0 → 0.5 across the throttle window, and zero while scrammed):
un-throttled 0.2 / 0.0023 = 87.0 ticks at 100/s
throttled 0.3 / 0.0023 = 130.4 ticks at avg 75/s
energy per cycle = 100 x (87.0 + 130.4 x 0.75) = 18480 bandwidth-ticks
average = 18480 / 717 ticks = 25.8 /s
| peak | duty | average | failure mode | |
|---|---|---|---|---|
| DECODE ASIC | 20 /s | 100% | 20 /s | none, forever |
| SOFTWARE DECODER | 100 /s | 30% | 25.8 /s | total blackout, 16.7 s at a time |
Five ASICs at full song, one third of the time, in one 2×2 footprint. 29% more average power for a supply that vanishes on a schedule you don't control — a real choice, and the answer to "does anyone dare run two side by side" is still no, not naked: identical decoders heat in lockstep and therefore black out in lockstep.
bufferCap: 240 → 300
Re-derived against the retuned cycle, since the order was "one tank should cover one decoder scram" and the scram window changed:
reference chain: peak draw 96 /s, compression pays back 18 /s -> net demand 78 /s
balanced plant: 3 ASIC (60/s steady) + 1 software decoder (25.8/s avg) = 85.8 /s ✓
decoder scrams: supply = 60 + 18 = 78 /s vs draw 96 /s -> deficit 18 /s
18 /s x 16.67 s = 300 bandwidth-seconds
bufferCap = 300 -> one tank rides out exactly one scram.
And it refills in time to do it again: while the decoder is up the plant makes 67/s more than it spends, recharging 300 in 4.5 s of the 7.25 s up-phase. That is the M2 sentence — a buffer tank is what makes software decoders survivable — and it now closes.
heat on the hex splicer: coolPerTick 0.001, 0.08 per splice
Net 0.035 per craft after the 45 ticks of cooling → 28.6 crafts → 42.9 s of continuous
splicing before it scrams (chart-stco-map: 50 s). A lesser fever than the decoder's
14.5 s, exactly as ordered. §4: "Requires ... a steady buffer feed or it splices itself"
— left running unattended, it stops itself.
Open / deferred
- The ASIC cooler's aura is spec'd, not built (above). Until SIM has auras, heat is survivable only by duty-cycling or by leaning on ASICs. Deliberate.
cinema-pack,mosquito-swarm,gibbs-wraithremain forward canon (no recipe). The validator's FORWARD_CANON allowlist is the enforcement, and it has a companion test asserting nothing sits on the list once it is producible. Round 3 retiredcontainer-pack's slot (round 2) and added none.- Dials-as-recipes (quantizer Q, subsampler grades, GOP cadence) stays, per round-2 review.
- The heat constants in
data/validate.test.tsare mirrored fromsrc/sim/index.ts(throttle 0.7, restart 0.5, dissipation default 0.004, 30 tps). They are not exported, so my arithmetic tests can't import them. If SIM retunes the curve, my tests go stale silently — they'd still pass while the feel drifts. Re-check on any heat round. A cheap fix if SIM likes: export the constants. - The muxer, moov brain and megaglitch are data-only; no lane implements a victory
condition yet. The tech gate (
fortress-the-muxer) keeps them out of reach meanwhile.