BREEDING

Other Systems › Breeding

Breeding is a continuous pen, not a transaction. A pair is placed in a pen and the pen starts on its own; from then on it eats Ichor minute by minute and fills a progress bar. When the bar completes, an egg drops into the inventory and the pen keeps going. Ichor is the limiter — its only other outlet is the Shadow Trader, who buys it.

The pen grid

Six pens, shown as a 2×3 grid. Pen 1 is unlocked from the start. Pens 2–3 are bought with Ichor; pens 4–6 are premium, 5 / 10 / 15 Wraithgold (D ruling 2026-08-13; the July 2026 all-Ichor table is retired). They unlock in order. Costs are authored in codex/pen_unlocks.csv — never hardcoded; if that table cannot load the game halts rather than guess a price. Every priced pen, Ichor or Wraithgold, is bought at the server’s unlock door (since 0.90): the server checks what you hold against the price, books one permanent unlock row and writes the pen into the stored save, so a second click or a refresh never charges twice and the pen survives a reload. The save may never claim more pens than that ledger records.

PenUnlock
1Free — available from the first hatch
212,000 Ichor — roughly 7h of endgame kill income
360,000 Ichor — ~34h
45 Wraithgold — premium (was 180,000 Ichor)
510 Wraithgold — premium (was 450,000 Ichor)
615 Wraithgold — premium (was 1,000,000 Ichor)
What extra pens actually buy. Not throughput — Ichor income caps that regardless of pen count. Extra pens buy parallelism: several different pairs, types, and grade-ladders running at once, and no idle time while you swap partners. A player with six pens and a player with two pens hatch the same number of Void eggs per hour; the six-pen player is also climbing five other lines while they do it.

What decides an egg’s grade

The parents’ LEVEL does not matter. Their GRADE does, and nothing else does. A level 100 Worn pair and a level 1 Worn pair lay exactly the same eggs. Level is read for experience and for combat; it is never read anywhere on the breeding path.

What the server does, in order:

  1. Takes each parent’s grade from its own item ledger — never from the client’s note and never from the uploaded save.
  2. Floors the average of the two: P = max(1, floor((gradeIndex(♂) + gradeIndex(♀)) / 2)). An Epic × Worn pair is floor((5+1)/2) = 3 — an Uncommon pen. A mismatched pair always averages down, so two parents of the same grade is the efficient pairing.
  3. Uses that pen grade to pick one row of codex/egg_hatch_weights.csv. The egg’s grade is then random within that row — the row sets the odds, not the result. A Void pen lays a Void egg 35.7% of the time and can still lay a Worn one at 0.1% (the 2026-10-23 nerf; it was 78.1%).

The same pen grade also sets the wait and the cost out of codex/breeding.csv. The grade is re-derived every time the pen is written, not remembered, so correcting a parent’s grade heals the pen without restarting the timer. Full odds table under Egg grade output; the rates are under Rates.

Choosing a pair

The pen has two sockets, ♂ and ♀. Clicking a socket opens a full-screen roster picker — it leaves the pen grid rather than crowding it, so the 2×3 grid stays intact.

RuleDetail
GenderOne male, one female. Gender is a flat 50/50 roll at hatch and never changes.
Shared typeThe two parents must share at least one type. All three type slots count (primary, secondary, tertiary) — an overlap anywhere is enough.
Progressive filterThe first socket lists every creature of that gender. Once one parent is chosen, the second picker filters to compatible partners only: opposite gender, sharing a type, not already in another pen.
Sort orderGrade descending, best first (Void → Worn), with level then name as tiebreaks. The picker previously listed candidates in bag insertion order, so a Divine sat wherever it happened to have been hatched. Grade is the lever this screen turns — pairP() floors the average of the two parents’ grades — so the best available parent belongs at the top. LIVE on release since 2026-08-05 (0.32).
ExclusivityA creature can sit in only one pen at a time.
Battle lockoutA creature in a pen cannot be in the battle party. Breeding your best fighters means fighting without them.
Same lineAllowed.
Type scarcity is the real gate. Across the roster of 312, the median creature has about 45 type-compatible species and the tightest has 11. The four three-creature types — Celestial, Demon, Chimera, Aberration — are a single line each, so they can only breed within their own line. Breeding rewards a broad collection, not a strong one.

What the egg contains

The egg carries one of the two parents' lines, rolled 50/50 at the moment it is laid — never a third species. It hatches that line's Stage 1, like every other egg in the game. The shared type is the gate on which pairs may breed; it does not decide what comes out, so pairing a Thornback with a Dusthound returns a Bristle or a Whelp and nothing else. The egg's shell art follows the rolled species' first type, and its grade is rolled separately from the pair grade (below).

The line is fixed when the egg is laid, not when it hatches, so an egg sitting in the inventory already knows what it is.

Pair grade

Every rate in the system keys off one number: pair grade P.

P = floor( (grade of parent A + grade of parent B) / 2 )

Mismatched parents are punished by the floor: a Void paired with a Rare breeds as Abyssal (P = 7), not as Void. Climbing the grade ladder means lifting both parents.

Where the server gets the two grades. The start note names only the two parent ids. The server looks each one up in its own item ledger and reads the grade there — never from the note and never from the uploaded save — then floors the average exactly as above. Three rules follow: a ledgered parent whose grade is not one of the ten legal grades records nothing (the start is unverifiable, and a claim on a pen with no record is refused); a pair re-announced unchanged never restarts its wait, but its recorded grade is re-derived on every note, so a wrong record cannot outlive the next battle; and the recorded grade is what the claim uses for the wait, the weights and the settled cost. Gate: tools/probe_breedgrade.mjs 7/7 — it reads the recorded grade back through the claim door's remaining wait (Void 110, Abyssal 50, Common 18 minutes), which is the one place a sandbox can see it.

The loop

StateBehaviour
Pair placedA pen holding a compatible pair is breeding — there is no start button and no toggle (0.76). The pen drains Ichor_Per_Min(P) every minute and fills its meter. P is locked in when the pair lands.
Bar fullAn egg is sent to the inventory, the bar resets to zero, and the pen continues automatically as long as Ichor and inventory space remain.
Egg inventory fullDrain stops, the bar freezes at its current fill. Nothing is consumed and nothing is lost. Clear an egg and it resumes.
Ichor hits zeroSame as above: drain stops, bar freezes, pen resumes the moment Ichor arrives.
Removing a parentResets that pen's meter to zero. This is what stops a player filling a bar on a cheap Worn pair and swapping in two Voids at 99%.
ClockSession time only, and session means the tab is alive — not that it is in front of you. A pen advances on wall-clock elapsed time whenever the client is loaded, including while the window sits unfocused or behind another tab. It does not advance while the game is closed: no offline accrual, ever.

How the meter actually advances

Rates — drain, duration, cost

Authored per pair grade in codex/breeding.csv. Higher grades are slower and hungrier, so cost per egg rises steeply while the pen's own throughput falls.

Pair gradeIchor / minMinutes / eggIchor / eggDrain per hour
Worn31545180
Common51890300
Uncommon722154420
Rare926234540
Epic1232384720
Legendary1540600900
Abyssal18509001,080
Divine21651,3651,260
Primordial24852,0401,440
Void261102,8601,560

Ichor income

Ichor comes from combat, and scales with what you killed — level and rarity both. Per defeated enemy:

Ichor = round( 2 × (1 + enemyLevel / 100) × RarityMult )

RarityMult:   C 1.0   UC 1.1   R 1.2   SR 1.35   SSR 1.5

The #772 rebalance (D, 2026-09-10): level term /100 (was /20), ladder in tables.json food_rarity_mult. Enemy level caps at 100, so the Void Apex pays the floor-100 rate.

A three-enemy battle at the encounter weights in codex/encounter_weights.csv therefore yields:

FloorCUCRSRSSRExpected / battleIchor / hour
1222336.2~670
25333349.1~990
513344510.4~1,130
754445512.7~1,390
994455614.1~1,540
1194455616.3~1,780

Kill Ichor only (egg and gear dismantles are on the Shadow Trader page). Hourly figures at 109 battles/h (dfmc-client tools/sim_econ.mjs BATTLES_PER_HOUR), rounded to 10. Deep floors still pay more — higher levels and a richer rarity mix — but the ramp is flat: floor 119 pays 2.7× floor 1. Generated by tools/codex_tables.py from encounter_weights.csv and tables.json food_rarity_mult.

Egg dismantling

Unwanted eggs dismantle back into Ichor, keyed to the egg's grade (not the pair that made it).

Egg gradeWornCommonUncommonRareEpicLegendaryAbyssalDivinePrimordialVoid
Ichor152545704672108164244344
No breed-and-dismantle loop. Yields are tuned against the hatch-weight matrix so that the expected dismantle value of an egg is always 27–30% of what the pen spent making it — at every rung of the ladder, including the up-rolls. Breeding for Ichor is always a loss; dismantling is a refund on a bad roll, never an engine.

Egg grade output

The pen does not need a new matrix. The pair grade P indexes the existing row in codex/egg_hatch_weights.csv — the same matrix that later rolls the hatchling's grade from the egg's grade. Two Void parents roll a Void egg 35.7% of the time (20% Primordial, 9% Divine, 10% Abyssal, 19% Legendary, and a tail below), and that Void egg then rolls a Void creature 35.7% of the time: ~13% Void end-to-end (it was ~61% before the 2026-10-23 nerf, see the changelog), with a real chance of falling short at either step. The Hatchery grade-boost upgrade shifts the second roll upward.

Throughput ceiling

Ichor income — not pen count — is the hard cap on egg production.

Scenario (endgame, floor 119, ~1,780 Ichor/h from kills)Result
Void pair, any number of pens~0.6 eggs / hour, ceiling
Epic pairs~4.6 eggs / hour
Six pens, all Void9,360 Ichor/h demanded — runs at a ~19% duty cycle, starving and resuming
Six pens, Worn through Legendary3,060 Ichor/h demanded — ~58% duty cycle

A single Void pen alone (1,560 Ichor/h) eats about nine-tenths of a maxed player's entire kill income; a second Void pen is already past it. That is the intended shape: the top of the ladder is slow by construction, and no amount of pens buys past it.

Where breeding happens — anchor and claim

The server is called once, at the end. Starting a pen costs no request of its own and no tick is ever reported. The client attaches two fields — the pen index and its grade — to whatever call it was already making, and the server anchors the pen. The egg claim is POST /api/roll with kind egg and the pen index — the only breeding request in the system (/api/breed/claim was retired on 2026-10-22 and answers 410).

StepWhat happens
StartThe client rides {p, g, s} on an existing request — pen, grade, and the moment it started. Because the note is queued, the pen really did start before the server heard about it, so that time is credited rather than discarded — but it is clamped: start = clamp(claimed, floor = last contact, ceiling = now). The floor falls out of the offline rule: nothing happens offline, so a pen cannot have started before the last moment the account was talking to the server. A false claim is therefore worth at most the gap since the client's previous call, which the client's own traffic already bounds, and a backdate to 1970 buys nothing at all. The floor is read from writes the account already makes (the battle chain's last flush, the stored save's timestamp), so proving last contact costs no extra write. With no claim, or a nonsense one, the anchor falls back to now().
RunningNothing. No tick, no heartbeat, no request. The pen is a row with a grade and a timestamp, and it survives a worker restart because it lives in the account's SQL.
Re-announcedIgnored. A re-sent note does not restart a running pen — otherwise a client could re-announce forever and hold an egg at 99%.
ClaimThe server compares elapsed time on its own clock against Minutes_Per_Egg for the recorded grade, with a clock-skew band of the greater of 90 s and 3% of the pen (anchor drift and device clocks, measured 2026-08-29 and widened 2026-09-02). Earlier than that, or with no record, no rate, or a recorded parent no longer in the pen, it refuses (409 breed_claim_bad, flagged with the reason) and grants nothing; the client pauses its pens and asks again later. Ready, it re-derives the pair grade from the two recorded parents’ ledger grades (a record that disagrees is corrected and flagged breed_pair_corrected), draws the grade off that row, names the species off a recorded parent’s line, mints the egg’s uid, books Ichor_Per_Egg, and re-arms the pen by exactly one wait so one wait can never pay twice. The answer always carries the egg (species, crId, grade, uid); an egg the server cannot name is refused, never laid unnamed.
Every number comes from breeding.csv — minutes per egg, ichor per minute, ichor per egg, dismantle value. Nothing is hardcoded, and a grade the file does not author grants nothing at all rather than falling back to a default.

The egg's grade and its line are the server's

LIVE on release since 2026-08-08 (0.42). Server-side rolls items 2 and 3, and they are one ask, because they are one decision made at one instant. Split into two calls, a client could keep a grade it liked and re-ask for the line.

D's breeding ruling is unchanged: “Server only needs to be called when breeding ends for the result. Starting breeding and the ticks can be queued.” So the per-second tick still runs locally and still meters Ichor in whole units. Only the laying waits.

A due egg is a paid entitlement, and the pen stops

Breeding charges as it goes, so by the time progress reaches 1 the Ichor is already spent. The egg cannot simply be dropped if the server is unreachable, and it must not be laid blind either. So the pen banks due and stops: it spends no more Ichor and accrues no second entitlement. That is what keeps this out of outbox territory — a stopped pen credits nothing, and what is owed is one egg, not a growing queue. It reuses the rule breeding already has: a full soul bag pauses a pen, it never discards.

layEgg() is idempotent against its own entitlement, so an answer arriving twice cannot lay twice, and it re-checks the soul cap — the bag can fill between the entitlement being banked and the answer landing.

What the server decides

FactSource
Egg gradeegg_hatch_weights.csv, the row for the pair's grade. The ladder is the CSV's own column set, never restated in code — re-author the grades and the weights move with them.
Parent line50/50 between the two parents, drawn on a second HMAC lane. The client is told which parent and only resolves it to a line id.
Species, origin record, toastClient. None of it is a chance.

Also deleted: rollHatchGrade(), dead since the hatch path became server-decided. No call site remained, and a live Math.random() grade roller sitting beside the door that replaced it is an invitation to wire the wrong one back up. hatchWeights() stays — the mass-hatch screen reads it to show the odds, which is display, not a draw.

Probe. tools/probe_eggroll.py — BEFORE 1/8, AFTER 8/8 over three runs, on the full stack. Test 5 aborts /api/roll and proves the pen stops dead; test 6 restores it and proves the egg lands exactly once. Test 2 reads the authored weights out of the CSV rather than restating them, and test 4 bounds the 50/50 at three standard deviations of the sample the roll rate cap actually permits.

Adam and Eve — the soul-bag pair keeper (reports #99 + #100)

Status: on release. An option in the soul-bag dismantle menu, offered in the SOUL BAG ONLY because it is meaningless where there is no line and no gender. It keeps the highest-grade MALE and the highest-grade FEMALE of every advancement line and dismantles the rest. Two keepers per line, not one — a breeding pair needs both, which is the whole point of the name.

What it refuses to touch, each a deliberate refusal rather than an omission:

Ties are broken by level, then by stage, and the confirmation window says so. A tie means the two are interchangeable, but only one survives, so the choice is made on the numbers rather than on bag order.

The confirmation window explains what it does, which is part of the spec rather than a nicety: it names the rule, how many survive across how many lines, how many are being dismantled, and every creature it is leaving alone and why. Without that last part a player reads “keeps the best of each line”, finds four Phantoms still in the bag, and files it as a bug.

Measured on a real account before shipping: 87 creatures down to 47, exactly the 40 on the kill list, no creature dismantled while a worse one of its own line and gender survived, a second run finding nothing left to do, and the item census changing creature rows only. Client: adamEveSplit(), dismTargets mode adameve, dismAdamEve in play/app.js.

Changelog

2026-11-03 — codex review (dfmc-client lane codexreview-a; D 2026-11-03 “review the codex, clean it up, update whatever needs updating”). WIKI ONLY. The pen-grid text still said Ichor pens were debited by the client and that Ichor had no other use; every priced pen has gone through the server’s unlock door since 0.90 (ichor-doors, below) and the Shadow Trader buys Ichor. The six pen prices now bind to pen_unlocks.csv Cost instead of being pasted. The throughput-ceiling table still ran on the pre-#772 income (~490 Ichor/h at floor 119); it is recomputed against the ~1,780 Ichor/h the Ichor-income table above already shows (Void ceiling ~0.6 eggs/h, six Void pens ~19% duty). Roster count 300 → 312 (creatures.csv). No game code or csv changed.

2026-10-23 — a pen parent's uid is the server's (R6 "the server mints every identity", dfmc-client lane r6-pen-uids). SHIPPED IN 0.90. A creature sitting in a breeding pen (pens[i].m / .f) with no uid - a legacy or restored save - used to get a uid invented by the client, on boot and again after every server answer, so a pen action named an id the ledger never issued. The v2 save door now names it once (penUidMint in src/worker.js, beside the bag's bagUidMint): a uid fixed by the creature and its pen and side, an items row with origin pen_mint and its birth, flag pen_uid_minted, srv.penMinted on the answer. The client's ensureUids leaves the pens to the server once the server-authoritative save is on; the legacy path still stamps. Breeding itself is unchanged. Gate: tools/probe_pen_uids.py 5/10 → 10/10.

2026-10-23 — C17 part 3 (dfmc-client lane c17-gen-2): the rates, Ichor-income and egg-dismantle tables are generated. WIKI ONLY; no game code changed. The egg-dismantle row binds to breeding.csv Egg_Dismantle_Ichor; it still showed the pre-rebalance ladder from Epic up (Epic 115 → 46, Void 860 → 344). The Ichor-income table is the kill credit over encounter_weights.csv (floor 25 7.9 → 9.1 per battle), and the hourly column is at 109 battles/h (tools/sim_econ.mjs), not ~30. Drain per hour is Ichor/min × 60, computed.

2026-10-23 — a breeding pen names what it spends, on hover (screen review #9, dfmc-client lane screen-fixes-2). SHIPPED IN 0.90. The spinning circle on a breeding pen's gate already carried the egg grade in its title (#879 moved it there when D removed the pen's rate text). Its title now also names the cost: Breeding · Common egg · 90 Ichor per egg, every 18 min, from breeding.csv Ichor_Per_Egg and Minutes_Per_Egg, the same per-egg ask the server takes. No visible text is added to the pen (#879 stands). Display only. Gate tools/probe_b9_pencost.py.

2026-10-23 — the Ichor pens, the breed screen's egg dismantle and the breed meter go through the server (lane ichor-doors). SHIPPED IN 0.90. Since the wallet became the ledger's sum (2026-10-23, system-networking), three Ichor flows that moved only on the client undid themselves at the next save answer. Pens 2-3 are now bought at the same server door as the Wraithgold pens: the price is pen_unlocks.csv's, the server checks the balance (refusing with what you hold and what it costs), books one permanent unlock row and writes the pen into the stored save - a second click or a refresh never charges twice, and the pen survives a reload. After the wipe line only pen 1 (price 0) is free; a priced pen is owned by its ledger row. Dismantling an egg on the breed screen calls the dismantle door at the click (the server prices it from breeding.csv Egg_Dismantle_Ichor), with the next save as its fallback, never both. The breed meter no longer draws Ichor out of the shown wallet second by second: the egg's cost (Ichor_Per_Egg) is booked by the server when the egg is laid, and the meter only measures progress against what the wallet can still cover. Probe: tools/probe_ichor_doors.py 5/11 → 11/11.

2026-10-23 — each parent's name sits on a wooden sign nailed to the pen gate (C14, the one piece of #879 left unbuilt). SHIPPED IN 0.90. A filled parent slot prints its name on a plank (img/breed/sign.webp, cut by tools/make_breed_sign.py from the gate set's own rail, lifted so it reads as a sign on the gate rather than another rail), in front of the gate, with the grade line beneath it. Display only - nothing about breeding changes. The sign is warmed with the barn and the gates; the first-open art is 637 KB of the 700 KB budget.

2026-10-23 — breeding odds nerfed at the top: the Abyssal, Divine, Primordial and Void rows of the hatch matrix hold far less of their own grade (INDEX § 3 Economy, D 2026-10-22 “breeding chances reviewed and nerfed, especially higher grades”; C3). SHIPPED IN 0.90. codex/egg_hatch_weights.csv only — no server or client constant, no new column, breeding.csv durations unchanged. A bred egg reads the matrix twice (the pair grade’s row picks the egg grade, the egg grade’s row picks the creature), so a row’s own-grade weight compounded: a Void pair bred a Void creature 61.6% of the time, Divine 53.5%, and a breeder penning only their best tenth went from all-Legendary to 92% Divine+ in five generations. Those four rows are reachable only by breeding (wild eggs stop at the Legendary cap), so they move and nothing else does: own-grade weight Abyssal 57.4→38, Divine 63.8→37, Primordial 70.5→37, Void 78.1→35.7; the step-up weights shrink (Void column: 0.4/1/4 → 0.1/0.3/1.9) and the freed mass falls mostly to Legendary rather than one grade down, so breeding does not become the main source of Divine. Worn through Legendary — the rows a wild egg hatches on — are untouched. Model (tools/statmodel.py breed, 40 fresh endgame collections at floor 119, 3 pens, every Ichor to the pens): a pair’s child is its own grade or better Abyssal 49.9→22.4%, Divine 53.5→17.2%, Primordial 57.5→15.9%, Void 61.6→13.2%; first Void at a median 19.5→63.5 active hours; Void creatures made 63→13 per 100 active hours; the best-tenth curve tops out at 25% Divine+ instead of 92%; bred share of Divine 37→35%. Gate: dfmc-client tools/probe_breed_odds.py 10/10 (4/10 on the old weights) — the server’s own pair-grade, egg and hatch code extracted from src/worker.js over 200k pairs matches the model, and the targets hold. Review: dfmc-client docs/breeding-odds-2026-10.md. Reaches the game on the next DATA_PIN advance and bake.

2026-10-22 — the egg claim refuses what the pen record cannot account for, the pair grade is the parents’, the type rule is server-checked, and the ×60 dev clock is gone (server-authority run § 3 item 6; F134, F140, F144, F175; T47-2). LIVE on release since 2026-10-23 (0.89). Watch-first ended on the roll door’s egg branch: a claim with no pen record, before the authored wait on the server clock, with a recorded parent gone, or for a grade the tables do not author is refused (409 breed_claim_bad, still flagged) and nothing is drawn, minted or booked — the idem is not spent, so the honest claim that follows is answered. The client’s pair is ignored: the pair grade is re-derived at the claim from the two recorded parents’ ledger grades (the breedfix rule, moved into the door; a stale record is corrected and flagged breed_pair_corrected). The pen start now checks the shared-type rule server-side, off the ledger rows’ species names and creatures.csv: no type in common refuses the start (breed_start_bad no-shared-type); a name the table does not hold is unverifiable and records nothing. The answer always carries the egg — species, crId, grade, uid — and the client adopts it; the client-side stage1OfLine fallback that named an unnamed egg from its own copy of the parents is gone, and an egg the server cannot name is refused (breed_species_unresolved). /api/breed/claim, routed but with no caller, is retired (410) and its object handler deleted. The ops breedfix door looks hatch records up by the hatch door’s own uid:index key, so a regranted egg that hatched is not redelivered. The ×60 development pen clock is deleted end to end (template, release override, save key, tick, Settings toggle and markup): one pen-minute is one real minute on every build. Gate: tools/probe_sa_roll_breed.py 24/24 on the local rig (red 12/24 on the pre-fix tree).

2026-10-01 — the pens tick no longer repaints every screen (0.89 carry-over s4.3, PREP_PERFORMANCE § 1.4). LIVE on release since 2026-10-23 (0.89). While any pen was on, the client's once-a-second pen tick pushed the new pen state, wallet and egg entitlements through a full repaint of the whole screen, whatever screen was open - the floor, a fight, the inventory - for a readout only the Breeding window shows. The pen state is saved state, so nothing about it changes: the tick keeps its one-second cadence, its integer-metered Ichor draw, its progress and its due-egg entitlements, and the save carries exactly the same fields with the same values. What changes is only the painting: with the Breeding window closed the tick writes the pen state without repainting, and the next real paint (or the next save) sees it; with the Breeding window open every tick still repaints, and a wallet change still repaints while the Crafting window is open, because its rail shows the Ichor count. Measured by the client's tools/probe_perf_3.py: on the floor with a pen running, 5 full repaints per 5 s before, 0 after; with the Crafting window open, 6 before, 3 after (one per wallet change); the Breeding window keeps its 6; the save's shape is identical before and after and the three screens are pixel-identical.

2026-09-30 — a hatched egg keeps its hatch record while its row exists, and the gender door answers a creature's stored sex (review lane U, F143, F135). ON DEV. The hatch door limits an egg by counting its hatch records, and those were purged after 30 days whatever the egg's own ledger row said. Every egg hatched before 2026-09-30 still has an unspent row (still in the bag, or marked gone by a save sync, which the hatch door accepts), so once its record aged out the same egg could hatch a second time and mint a second creature. A hatch record is now purged only once no ledger row for that egg remains; the row's own 30-day tombstone prune releases it, and an egg id with no row is refused. So the replay now holds for as long as the egg exists, not 30 days. The gender door (/api/roll kind=sex) used its own draw and never read the sex the hatch or the breed claim stored for a creature, so a hatched creature whose gender was stripped from the save could come back the other gender about half the time. A creature the server already sexed now answers that sex; keys with no sexed row (the starters) still draw 50/50, so no odds change. Release (main) has the same purge and in addition hatches any egg id without a ledger check (F132, fixed on dev only). Gate tools/probe_hatchpurge.mjs 4/7 -> 7/7.

2026-09-30 — the pen start checks creatures and genders, and a claim checks the pen is yours (review lane Q, F134, F353, F143). ON DEV. The server’s start check tested distinct uids, not-busy and a legal grade. It now also records nothing when either parent’s ledger row is not a creature, or both carry the same server-rolled sex. An empty field is our gap, not the player’s, so it is not held against the start. The shared-type rule is still checked only on the client: the object holds no species types. The dormant /api/breed/claim door refuses a pen index past the pens this account owns. NOTE (F143): the hatch record that makes a hatch answer the same way on a retry is purged after 30 days, so that replay guarantee lasts 30 days, not forever. Gate tools/probe_laneq.mjs 0/15 → 15/15.

2026-09-30 — review P6 F6-050. ON DEV. The egg claim (/api/roll kind egg with its pen) read the lazily created pens table without creating it, so on a player object where no start note had ever landed the request failed with a server error and the ready egg could never be claimed. It now creates the table first (the same statement the start note uses), and a pen with no record takes the watch-first no-record path: paid off the claim and flagged, as the ledger rule says.

2026-09-30 — review P6 F6-037. WIKI ONLY. The claim row said an early claim grants nothing; the server has paid a claim up to the greater of 90 s and 3% of Minutes_Per_Egg early since 2026-09-02 (60 s / 2% from 2026-08-29) — a deliberate band for anchor drift and device clock skew, measured on real anomaly rows, that still flags anything further out. The row now states the band. No rule changed.

2026-09-30 — review drift fixes: F138, F142. WIKI ONLY. Ichor income, its per-floor table, the pen-price hours and the Throughput ceiling are restated on the #772 curve the server pays (level/100, ladder 1/1.1/1.2/1.35/1.5); they were still the pre-09-10 numbers (~3,040/h at floor 99, now ~420). The loop table dropped its Toggle ON/OFF rows: since 0.76 a pen with a compatible pair always runs, and the only stop is removing a parent, which zeroes the meter. DESCRIPTIVE ONLY.

2026-09-30 — premium pens are only ever what the ledger paid for (F136, F327, full project review). ON DEV. Two ways past the Wraithgold price are closed. The save carried pensUnlocked as a number that could only grow, with no ceiling: a save claiming six pens was stored, and both the unlock door and the pen note then took that number as ownership, so pens 4–6 came free. The save door now caps the claim at what the server can vouch for — the Ichor pens (1–3, still debited by the client), the highest pen the permanent unlock ledger records as bought, or the count the account already held (a pen owned before the ruling is never taken back) — and flags anything above it (pen_unpaid). A pen note for a pen the account does not own is refused (pen_unowned). On the client, a lost pen_unlocks.csv used to fall back to the old all-Ichor table and sell pens 4–6 for Ichor on the spot; the boot now halts on it like every other core table, and with no price table no pen is for sale. The pen price table above is corrected to the 2026-08-13 ruling. Server: penEntitled, penNote, the save door in src/worker.js; client: loadPenCsv, penPrice, unlockPen in play/app.js. Gate: tools/probe_f136_penentitle.py.

2026-09-30 — a hatch opens the egg the server holds, and the creature remembers it (F132, F133, full project review). ON DEV. The server already drew every hatch, but it drew it off the grade the request named and never asked whether the egg was one the account held, so the draw could be pointed at any grade. It now resolves the egg by its own row in the item ledger: the grade the draw uses is that row’s grade, never the request’s; an egg the ledger holds no live Egg row for hatches nothing and is flagged hatch_unledgered; and the egg row is marked spent (gone_src=hatch) the moment it hatches, so one egg is one creature. Every legitimate egg already carries a row — drops and bred eggs are written at the grant and the save door adopts every held item on each save — so no held egg is refused. The same lookup fixes the lineage: hatch ids travel as uid:index and the birth record searched the whole id, found nothing, and wrote every hatched creature with no egg name, no parents and no pen. It now reads the egg’s row, so a bred egg’s parents and pen reach the creature as the 2026-08-26 entry promised. A replayed id still answers the same creature. Worker: hatchOne in src/worker.js; gate tools/probe_hatchledger.mjs.

2026-09-17 — CHOOSE PARENT clears the pen door, and the circle stands on it (#949 D, #954). ON DEV (0.84). The text. D: “the first row of the breeding pen ‘choose a parent’ text is cut off by the breeding pen door graphic. expected to be like second row where text is above pen doors.” Both rows were in fact placed identically: an empty slot’s sigil and label were centred on a box that is the whole pen bay, while the door is an overlay that box knows nothing about — so every one of the six bays put the label on the door line. What differed was the door art. The six gate plates are all 912 wide but 222 to 242 tall, so the row-one plates rise above the label and eat it while the row-two plates sit under it and clear it; nudging row one would have been fixing the symptom. The label is now centred in the stall above the door, from a single measurement sized to clear the tallest plate rather than the average, so all six bays read alike and no future door can put one back on its own rail. It is lifted well clear, and bold, both as D asked. The circle. The alchemical circle leaves the top strip the 2026-09-16 entry put it in and stands on the middle of that bay’s door. It keeps the egg’s grade colour and the tooltip naming that grade, and it gains a dark backing — the door is lit timber in the same tonal range as the lower grades and the rune vanished into the grain, and since #879 took the BREEDING word away this circle is the pen’s only running-or-stopped readout. The strip stays behind it, empty unless the pen is paused, so the parents below are not resized. Gate tools/probe_pentext.py 0/10 → 10/10 red-first, measured at 1920×911 and 1423×687; probe_breedbarn 29/29, its circle check re-aimed from the top strip to the gate and named for #954.

2026-09-16 (c) — a locked pen no longer prints its number (#879, D). ON DEV (0.81). The first #879 pass took PEN # out of the open pens and left it on the boarded ones — padlock, “PEN n”, the unlock button, the tagline. Asked whether the window title counts, D ruled: “I am talking about what is in each pen, not the title of the page.” So the “PEN n” line under the padlock is gone, and its producer went with it. The window title BREEDING stays. The unlock button keeps its label (UNLOCK PEN n FIRST, or UNLOCK · the price) — it names what the button unlocks, it is not the pen describing itself — and the PEN n IS NOT NEXT and PEN n UNLOCKED messages are messages, not pen content. Gate tools/probe_879b.py 6/7 → 7/7 red-first; probe_breedbarn 29/29 unchanged.

2026-09-16 (b) — the EGGS HATCHED card shows who hatched (#912, D). ON DEV (0.81). Under each grade row of the Hatch All summary there is now one thumbnail per distinct creature hatched at that grade — the Floor Map completion list’s 72px tile, drawn from the same codex art, never the full-size icon. The same species, sex and grade hatched more than once is one thumbnail wearing a ×n badge, not a repeat; a mutant is its own thumbnail on its recolour. The grade sits top-left as the alchemical circle in the grade colour (there is no grade icon asset, so the circle is the treatment the running pen already uses) and the gender sigil top-right tells a species’ two sexes apart. The rows column scrolls past 560px so a many-grade hatch cannot push CLOSE off the stage. Gate tools/probe_hatchcard.py 9/9 on the real Hatch All path.

2026-09-16 — the pen header is the circle alone (#879, D). ON DEV (0.81). PEN #, PAIR GRADE, the BREEDING word and the Ichor/min · min/egg · Ichor/egg line are gone from every pen, and the level no longer prints beside a parent’s grade. The alchemical circle is centred in the pen’s top strip at 52px (it was 22px in a corner); the strip keeps the height the two text rows had, so the parents are not resized. The circle still takes the egg’s grade colour, and its tooltip now names that grade (“Breeding · Rare egg”) since the readout that printed it is gone. A paused pen keeps its reason beside the dim circle — SOUL BAG FULL and LAYING are calls to action. The producers went with the text (num, status, pair grade, rate line, recLevel). Still owed: D asked for a wooden sign behind each parent’s name, in front of the pen gate — that is new art (a plank roughly the width of the parent slot, about 34px tall, sitting above the gate and below the name in the stack) and is promoted rather than placeholdered. Gate tools/probe_breedbarn.py 22/29 → 29/29 red-first.

2026-09-14 (b) — the pen header fits, and the Ichor count is legible (#849, D). LIVE on release since 2026-09-14 (0.80). The soul bag button was carrying the 120px plate every full-size nav button uses inside a 65px header — measured at 22px below the strip and 23px above it — and comes to 48px, the header minus its own padding, keeping its 850/344 aspect. The Ichor readout was a 12px flat purple square (a placeholder from before the currency icons were generated) beside a 16px number; it is the real icon and 26px in a fixed 110px slot now, through the same rule every other currency readout uses, because this count ticks every pen-minute.

2026-09-14 — a creature alone in a pen does not play the pair animation (#888, D). LIVE on release since 2026-09-14 (0.80). Both animations were hardcoded infinite in the markup and bound to nothing, so a creature by itself lunged at a partner who was not there and the recoil fired at an empty pen on its own beat. They are a PAIR animation and they ask whether there is a pair. Breathing is deliberately untouched — being alone is not being dead — and the gate fails if a later pass stills it.

2026-09-11 — the pens become a barn, and breeding runs itself (D). LIVE on release since 2026-09-11 (0.76). The pen grid is painted over a two-storey timber barn: each of the six bays is a pen, so the card frame, the slot boxes, the status chip and the readability scrim are gone. A gate hangs in front of both parents, a pen that is not unlocked is boarded shut, and the grade a creature carries now reads as a coloured aura behind it rather than a box around it. PAIR GRADE and the Ichor rate moved into the bay header, onto dark planking, because once the bays had straw floors the old position was unreadable. The removal button is the Tier X item plate and the gender marker is a crystal sigil.

2026-09-11 — there is no BEGIN BREEDING button (D). LIVE on release since 2026-09-11 (0.76). A pen holding a compatible pair is breeding. The progress bar and the percentage are gone with the button; the pen reports BREEDING, and the rate line already says what it is earning. Pulling a parent out still resets that pen’s meter to zero — D’s ruling, and the behaviour the code already had. Nothing changed on the server: the same pair lock, the same startedAt stamp the breed-start ledger anchors on, only stamped when the pair lands rather than when a button was pressed. Saves written before 0.76 that hold an idle pair start it when the pens are opened.

2026-09-11 — the parents are alive in the pen (D). LIVE on release since 2026-09-11 (0.76). Both parents breathe on their own cycle, and every few seconds the male lunges at the female and she takes the hit — the battle screen’s own attack and recoil, at the same timing, scaled to the smaller art. The male is mirrored so he faces her. There is no damage flash and no effect on the hit.

2026-09-11 — a loading tip for grade inheritance (D). LIVE on release since 2026-09-11 (0.76). “Better grade parents can produce better grade eggs.” carries an egg icon, and the loading screen now prints a tip’s icon underneath its text instead of beside it.

2026-09-09 — the server decides what a bred egg is (#821, D). LIVE on release since 2026-09-09 (0.73). The server has always chosen which of the two parents an egg comes from, fifty-fifty. It did not say which creature that meant, and recorded the egg with no species at all — the game client worked it out afterwards, and if it could not, it picked a creature of the shared type at random and minted that. The server now resolves the chosen parent to the first form of its own line, using its own records, sends that with the egg and writes it into the ledger. If a parent cannot be resolved the egg is left unnamed and the case is recorded for review — nothing is invented to fill the gap. The rule this restores is the oldest one in the game: the server decides, the client displays. Gate tools/probe_eggspecies.py 5/5, red 2/5.

2026-09-12 — hovering a parent no longer hides its name, the running pen’s circle takes the egg’s colour, and the parent picker gets a background (D). ON DEV (0.78). Three things in the breeding window. The gate stopped eating the name. Putting the pointer on a parent brightened the whole stall, and brightening an element makes it its own paint layer — which dropped the name, grade, level, gender sigil and remove X behind the stall gate, so hovering covered exactly the information you were hovering to read. The highlight now rides the contents of the stall rather than the stall, so nothing about the layering changes when you hover: the gate still stands in front of the creature’s legs, the name strip still sits in front of the gate. This is the third time this pen’s layering has broken in the same way (the remove X on 2026-09-04, the sheet on 2026-09-03) and all three come from one shape — an overlay authored to sit above a neighbour’s contents, which any brightness, scale or fade silently breaks. The circle tells you what is coming. The circle that spins while a pen is running was a fixed orange on every pen; it is now the grade colour of the egg that pair is working towards, read from the same row the PAIR GRADE readout prints, so the two can never disagree. A stopped or unpaired pen keeps the dead stone colour. The parent picker has a floor. It was drawn straight over the barn plate with nothing behind it, so barn beams ran between the card columns and a post or the feed chest read through the portraits themselves. It has its own panel now, and the cards are no longer see-through where the art sits. The pens view is unchanged — the barn is the pen there.

2026-09-08 — Hatch All gets a SKIP ALL button (#790, D). LIVE on release since 2026-09-08 (0.72). A SKIP ALL button now sits at the bottom of the hatch stage for the whole run. Pressing it ends the show at once and lands on the same summary card the run finishes on by itself; it does not pause on Abyssal-or-better eggs, because that rule belongs to the held fast-forward (#769) and the card names every grade anyway. Theatre only: the eggs were hatched and the creatures were in your bag before the first one took the stage, so skipping changes nothing about what you got. The button’s own tap never reaches the stage underneath — no egg skipped, no fast-forward armed — and a hold released over it simply ends the hold. Gate tools/probe_hatchskip.py 11/11, red 5/11.

2026-09-07 — Hatch All plays low to high and never fast-forwards past an Abyssal+ hatch (#769, D). LIVE on release since 2026-09-08 (0.71). The stage now plays the eggs sorted by the hatched creature’s grade, lowest first (Worn → … → Abyssal → Divine → Primordial → Void; same grade keeps the hatch order), so a held fast-forward burns through the chaff and lands on what is worth watching. Reaching an Abyssal-or-better egg while held drops the run back to pace — that egg cracks and reveals in full — and the finger still down does not race on; a new hold does, and stops again on the next one (with the order, those are all the eggs left). Theatre only: the hatch is still committed once, as before. Gate tools/probe_hatchseq.py 13/13, red 9/13.

2026-09-05 — Hatch All gets its theatre (board 3.6, D). LIVE on release since 2026-09-06 (0.70). The server still answers every egg in one go and the creatures are in your bag from that moment; what changed is the show. Each egg now takes the hatch stage in turn — mist, crack, reveal with the creature’s name and grade colour, a mutant glow when it is one — with a running counter. One click skips the egg on stage to its reveal; click and hold runs the rest at speed until you let go. The summary card (counts per grade, mutants) follows the last egg, and closing the stage early lands on it too.

2026-09-04 — the pen X works again (D). LIVE on release since 2026-09-06 (0.70). Since the grade effects reached the pens (2026-09-03), the portrait had been drawn over the remove X, the gender glyph and the name strip, so a click on the X landed on the portrait. The three sit above the portrait again; the X removes the creature, stops the pen and returns it to the soul bag as before.

2026-09-03 — grade effects in the breeding window, and press-and-hold opens a creature’s sheet (#723, #722, D). LIVE on release since 2026-09-03 (0.69). The pen parent slots and the parent picker cards draw the same grade effect layer the inventory tiles do, beneath the art. Pressing and holding a creature for about half a second — touch or mouse — on a parent slot, a picker card, or an Equipment creature card opens its sheet, the same window a click opens from the inventory; a short press keeps doing what it did (choose, pick, open the slot). The release is judged by the clock, so a hold under a slow frame still counts as a hold. Gates tools/probe_breedgfx.py 3/3, tools/probe_holdsheet.py 5/5.

2026-09-01 — New section: “What decides an egg’s grade”. Nothing on this page was wrong — every pasted rate verifies against codex/breeding.csv and the odds against codex/egg_hatch_weights.csv — but two questions a player actually asks were not answerable from it. Whether the parents’ level affects the egg could only be inferred from an absence, and the page never used the word quality at all, so searching for it found nothing. The new section states plainly that level is never read on the breeding path, that grade is, via the floored average, and that the egg’s grade is random within the row that average selects. Documentation only — no code, CSV or DATA_PIN touched, no behaviour changed, and no existing section edited.

2026-08-22 — every verified pair bred as Worn; fixed, and the eggs it cost are regranted (D order: “fix both”). LIVE on release since 2026-08-22 (0.59). A player reported Void pairs laying Void “almost always” while the grades below looked random. The second half was a defect: the breed-start ledger looked each parent up by id and read back its id and category — not its grade — so the floored average of two missing grades was 0, clamped to 1, and every pair the server could verify was recorded as a Worn pen. The verified claim then drew the egg off the Worn row (84% Worn, 12% Common) and booked the Worn price. The lookup lost the grade on 2026-08-18 (when parents stopped being read from the save blob), reached release with the 2026-08-21 server batch, and the same day's grandfather stamp put every creature into the ledger, so from then on it hit every pair on every account. Measured on release: six Primordial pens laid 42 eggs as 34 Worn / 6 Common / 1 Uncommon / 1 Rare (the Worn row exactly); 24/24 Worn on a second account; 101 wrong eggs across four accounts in about a day. The odds tables themselves were never wrong — the egg roll and the hatch roll read them correctly — and Void looking “sticky” is authored: a Void pair rolls a Void egg 78.1% of the time, and Void is the only grade with nowhere to roll up.

The fix is the paragraph under Pair grade above: the grade rides the lookup, an unknown grade records nothing, and an unchanged pair re-derives its recorded grade on every note so every Worn record made under the defect heals on the account's next battle without losing any waiting. The repair is an ops door, /api/backup/breedfix (documented on Admin & backend): for every stored egg draw whose recorded pair was Worn and which the ledger verified, it recomputes the real pair grade from the pen's recorded parents, re-takes the draw's own keyed lane on the correct row — same lane, right table, so the answer is the egg the player would have been handed — upgrades the egg in place if it is still unhatched in the bag, regrants a fresh egg of that line at that grade if it was hatched or dismantled, books the Ichor the pen actually metered against the Worn price the claim booked, and heals the account's running pens. An honest Worn pair, a pen whose pair has changed since, or a parent without a legal grade is skipped and named, never guessed. Gates: tools/probe_breedgrade.mjs 7/7 (2/7 watched fail on the defect) and tools/probe_breedfix.mjs (the incident reproduced end to end on the pre-fix tree, then repaired).

2026-08-13 — the breed ledger (D's spec: the client may only say breeding started and ended). On release. The server now owns the whole breeding record. START: the anchor rides battle events carrying the pen, the two parent ids and the start time — nothing else — and the server validates every start against its own stored save: both parents present, both creatures, genders opposite (the gender the server's own roll assigned), distinct, and not already breeding elsewhere. The pair grade is computed by the server from the recorded parents — the floored average, the same rule the bench uses — never taken from a claim, and the start time keeps its last-contact clamp. END: the egg ask names its pen; the server checks its own record — it exists, the authored wait for the recorded grade has elapsed, and both recorded parents are still held, the same two that started it, by id. A verified award runs entirely off the record: its grade's weights, its settled cost, and the line names an actual recorded parent. The pen then re-arms by exactly one authored wait, so cycles continue without a fresh start. Watch-first like every ledger guard: an unverifiable ask still pays out as before, flagged with its reason; enforcement is a later flip. Gates: tools/probe_breedledger.mjs 7/7 (real data — the anchor proof and every refusal) and tools/probe_breedledger_unit.mjs 6/6 (the verified branch, transcribed).

2026-08-13 — the egg award is recorded and settled (the economy BOOK phase's fourth and final brick). On release. The bred-egg award was the last uncredited lane in the economy: the egg entered the bag with no record behind it, and the Ichor the pens metered out for it never reached the permanent ledger. At the award — and only on the fresh draw, since every replay answers the stored result verbatim — two records now ride along: the egg is minted with a server id and a grant (origin "breed"), so it is sourced from birth and dismantling it verifies against that grant like everything else; and its authored settled cost (Ichor_Per_Egg) is booked into the permanent ledger, keyed on the ask's own stable id — the egg is already paid for and survives a reload, so the settlement is once-ever by the same key that makes the draw once-ever. With this the BOOK phase is complete: every mint and every currency movement is in the permanent record. Gate: tools/probe_breedbook.mjs 5/5 — the last case chains the whole phase in one line: mint, spend, same-window verify, dismantle earn.

2026-08-13 — pens 4–6 are premium: 5 / 10 / 15 Wraithgold (D ruling). ON DEV; release keeps the old Ichor prices until the next data-pin advance. The price is the server's: the client names a pen, /api/unlock resolves the authored pen_unlocks.csv row (now Currency/Cost aware), judges sequence against the save AND the wallet ledger, and spends through the permanent Wraithgold ledger — one row per pen, forever, so a refresh or replay can never charge twice and ownership is provable from the ledger alone. Pens 2–3 stay Ichor and client-flow for now (the economy BOOK phase picks them up). Gate: tools/probe_unlockpen.mjs 9/9.

2026-08-12 — Adam and Eve, the soul-bag pair keeper (reports #99 + #100). on release. New section above. Keeps the highest-grade male and the highest-grade female of every advancement line and dismantles the rest, behind a confirmation window that names the rule, the survivors, the tie-break and everything it is refusing to touch. It never dismantles a creature whose gender is unknown, whose line cannot be read, or which is sitting in a breeding pen. Verified on a real account before shipping: 87 creatures down to 47, exactly the kill list, nothing better destroyed than what survived, and a second run finding nothing left to do.

2026-08-08 — the bred egg's grade and parent line are decided server-side. LIVE on release since 2026-08-08 (0.42). One ask, because they are one decision. The tick still runs locally and still meters Ichor; only the laying waits. A due egg stops its pen rather than stacking entitlements, and lays exactly once when the answer arrives. rollEggGrade() and the dead rollHatchGrade() are both gone. Probe tools/probe_eggroll.py: BEFORE 1/8, AFTER 8/8.