GENERATOR_VERSION had sat at 0.1.0 while the emitted object gained the
authored layer and the content model moved under it, so a delve file
claimed a generator that no longer existed — both samples say 0.1.0 and
only one of them has an authored layer. Nothing gates on the stamp, so
this is informational only and old files still load. The comment on it
now says what it tracks and when to bump it, which is what stopped it
being bumped before.
test.mjs read ./content/barrow.json relative to the working directory, so
it only ran from inside core/ and crashed from the repo root. It now
resolves from the module file, matching build-index.mjs and
validate-pack.mjs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Groundwork for many themes, plus the first new one.
A pack validator enforces every structural rule this project learned the hard
way: situations that render as broken English, decisions that gate progress with
no alternative, motifs too thin to fill six areas without repeating, rosters
that do not say what harms them. Fifteen packs cannot be hand-checked; this
checks them in a second.
Themes are now discovered from content/index.json rather than hardcoded, so the
CLI takes --theme and --themes, the Foundry dropdown fills itself, and packs
load on demand instead of all at once.
Castle: four appetites — to be feared, never to give ground, to be obeyed at
once, the name to go on — over barrow geometry, since a keep is rooms and
corridors. 168 kernels from its own claimants and accommodations.
Fixed a bug the second theme exposed: the question the bottom problem asks was
hardcoded against barrow's appetite ids, so every other theme fell through to a
generic "Well?". It lives on the appetite in the pack now, and the validator
requires it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two bugs the first real button-press exposed.
The ⛏ never appeared. getSceneControlButtons was written for the old array
shape, but v13+ passes a record keyed by name and the token group is `tokens`,
plural — so the hook silently added nothing. Every earlier test had gone through
the API, which masked it completely. It now handles both shapes.
Area names were picked per-area from a small per-role list, so two areas sharing
a role could collide: a generated dungeon shipped with two scenes both called
"The Lesser Vault". Names are now dealt globally without replacement, falling
back to other roles' lists before ever repeating. This is the same bug already
fixed for features, decisions, temptations and situations — missed for names
because names were assigned in beat.mjs rather than dealt in delve.mjs.
A test now generates 180 delves at 6, 9 and 12 areas and asserts no two areas
in one delve share a name. Tests 38 -> 39.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The review's verdict after resolution blocks: 'still choices attached to
prompts, not spaces that naturally produce play'. The hand-written delve gives
a place — four people back-to-back around a dead lantern — and the decisions
fall out of it. DELVE gave a decision and asked the GM to imagine the room.
Every area now carries a situation: an occupant, what they are doing, what
changes when the party walks in, why (GM), and what it offers. 48 across 8
motifs, motif-scoped and dealt without replacement.
It produces chains nothing planned: in seed live-table-01 a grave-robber in
area 2 is trying to get a password's intonation right, and area 4 is a door
that needs one. Three routes to it now exist where there was a Wits roll.
Also closes the last two open complaints: the five roll-less decisions now have
real attempts (a voice you could not speak to was the weakest), and {priorCue}
resolves against a cue the party has actually seen instead of granting the
answer by fiat.
Tests 19 -> 24.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Playtest 3 put four players (Codex) through a generated delve with only the
player-facing text. Verdict: "a list of room-prompts, not a place", which
"expects the GM to invent too much of the actual game". It localised that to
one thing — decisions had a cue and a cost but no resolution.
Every decision now carries: an attempt roll, an explicit success outcome, an
explicit failure outcome, and an always-available alternative. 48 blocks across
8 motifs. The alternative is not optional: playtest 1 died on a gate the table
could fail without knowing, and the sharpest complaint this time was a door
whose only options were "guess blind and bleed Banes" or "pay time".
Features are now motif-scoped too, so all three furniture pools belong to the
fiction rather than a global list. 136 authored entries per theme.
Three new invariants make the failure modes unauthorable: every decision has a
resolution, no decision gates progress without an alternative, and every rolled
decision states both success and failure. Tests 16 -> 19.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The review's sharpest finding was that the fiction cohered but the things in
the rooms did not belong to it: only the motif cue fragment was projected, while
decisions and temptations came from global pools. The output was a consistent
wrapper around generic room furniture.
Both now live under motifs.<id> — 6 decisions and 5 temptations each, 88
authored entries across 8 motifs. A `keeping` delve offers a flower that has not
wilted and a room you may search or leave exactly as you found it; a
`precedence` delve offers a corridor that will not let two walk abreast.
Two bugs surfaced while wiring it, both the same shape as one fixed earlier for
cue fragments: decisions and temptations were picked independently per area
rather than dealt, so a pool of 3 repeated a temptation in 75 of 80 test delves.
Both are now dealt without replacement.
Where a long delve outruns its motif pool, decisions top up from the generic
pool but temptations do not. A generic relic breaks the fiction; a repeated one
only looks thin.
Tests 11 -> 15: motif provenance for both pools, and no repeats at 6 and 9 areas.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Build steps 1, 2 and 4 of the plan in DESIGN.md.
core/ is pure JS with zero Foundry globals and 11 passing invariants. The
fiction model has one root draw — an APPETITE plus the ACCOMMODATION someone
made for it — and projects the motif, danger, prize, faction, cue fragments and
the appeasement move from it, so the fiction coheres instead of being four
unrelated draws. 336 kernels from 21 authored lines; 60 generated delves gave
51 distinct kernels.
Cue fragments are tagged by facet (institution/ritual/demand/wound/anchor) and
dealt without replacement. The facet progression across the arc reproduces the
hand-authored paper delve's structure, which had arrived at it by instinct.
Generation and table dice stay apart: pressure.mjs decides when a clock roll is
due and what it means, and never rolls. That is what makes the skeleton seed an
honest promise rather than a half-truth.
paper/ holds the hand-written delve and both playtest logs. spike/ holds the
instrumented harness that measured the Forge outside Foundry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>