f185c92088b19911d8680f4bb7d8b60eb80e4d0a
10
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f185c92088 |
Add OPEN DAY, the recruitment prologue
Ten civilians, one decommissioned telephone exchange, and eleven minutes during
which the building went back to being on the street it was built on. Nothing
attacks anybody. Nothing wants anything. That is the horror, and it is the whole
design.
The premise was already in the pregens. Wren Finch's biography said she was
inside a building "on the night it stopped being on the street it was on", and
Soraya Rahimi's said she talked a caller down on air "for eleven minutes, and
the recording does not play back the same way twice". Those are two views of one
afternoon, so the scenario is built at the intersection and the other eight
"How they found her/him" lines are the same afternoon from eight more jobs.
Nothing in the prologue contradicts a sheet, because the sheets came first.
The reconciliation pass, which is most of the work:
- Finch's line said "night". The open day is an afternoon. One word changed on
the pregen, and both are true. Her line also says she was the only witness
who could describe the inside, so she is the one who goes into number 11 —
written into the location note rather than left to chance.
- Rahimi's line says she was ON AIR. So the disconnected telephone that rings
at 15:45 is patched through to her outside broadcast, which makes the canon
line and the scene the same event instead of two coincidences.
- Okonkwo carries two men out; Nkemdirim's patient has a forearm that healed
crooked over a break he took six minutes ago. Both seams needed an injury in
Act Two and there was none, so 15:50 and 15:51 now have one.
- Sandoval's forty minutes of traffic sit inside an eleven-minute window. That
is the anomaly, so it is on the handout in those words.
- "Prine" collided with an NPC already in the world. The engineer is Kearsley.
Structure: 2h15 against the house 3h30, stated in the design intent, because a
prologue exists to make the first real case land. No combat, no antagonist, no
Coherence — the last one is thematic, not a simplification: Coherence is what it
costs to keep looking once you know what you are looking at, and these ten do
not know yet. The Briefing is the first time the word is said aloud.
Ships as docs/scenarios/OPEN_DAY.md (the full GM document) and a Foundry
Adventure in a new `prologue` pack: 8 GM pages, 7 handouts, 5 NPCs, and ten
generated plates. The PCs are the "(before)" pregens already in the Pregens
pack — a second copy here would give a GM two sets of the same ten people and
no way to know which one their notes were on.
Verified in Foundry: the adventure imports, both journals render branded, the
countdown table reads as a table, and all ten plates load.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
26ad00174f |
Add the same ten before the department found them
Ten civilian counterparts, one per roster agent: same person, same
characteristics, same face, no induction and nothing ever issued to them. A
player can hold the two sheets side by side and read exactly what the job did.
Keyed off ROSTER rather than written out again, so the pair cannot drift apart.
The five who joined straight into a posting get the trade they came out of, and
between them the ten now cover all ten trades exactly once — which makes this
set a demonstration of the whole trade half of character creation as well as a
set of characters.
expandFromRegister grows a `civilian` mode: no induction skills, no standing
issue, no tier issue, no trade cant, and nothing anomalous or Coherence-costing.
Three things the build guard caught, each of which would have shipped:
- Holloway was "carrying issued kit: notebook". Wrong: an interpreter owned a
notebook long before anyone issued her one. The rule is now kit that could
ONLY have come from the department.
- Same again for skills — the linguist's core list contains trade cant,
because it is a language and she is a linguist.
- Wren Finch was carrying the black mirror, which is era "anomalous", from a
transposed tradition, and costs Coherence to look into twice. That is
something you acquire after the night the department notices you, not
before. It is the only anomalous item in any trade kit.
The guard runs over the built objects rather than trusting the flag that made
them, because the flag is three call-frames away from the result.
Verified in Foundry: 24 pregens, the before sheets show the civilian job in
place of rank, no armour, nothing readied but fists, and the right face.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
c15b13c3b9 |
Add the duty roster: ten ready-to-play agents with generated portraits
Five postings and five trades, so a group choosing from this sheet meets both halves of character creation without anyone having to explain them. Skills and kit are not written out per agent. They are expanded from the register at build time by the same helper the starter scenario uses, which is hoisted out of the BLACK PLATFORM block for the purpose — two copies of that expansion is two places for the induction rule to drift. Ratings sit at the middle of each band rather than being rolled, because a pregen that varies between installs is not a pregen. Portraits are generated art, resized to 512 and stored as webp (12MB of PNG became 210KB). buildActor now takes a portrait and gives the same face to the prototype token: a pregen you can recognise on the map is worth more at a convention table than a correct one you cannot tell apart. It throws on a portrait that is not on disk, because a broken image on a pregen sheet is the sort of thing that is first noticed on a projector. Guard: check-behaviour gains a test that every roster agent names a real posting or trade and has its portrait on disk, verified to bite. It caught "archive", which is not a posting — Bhattacharya is Registry. Verified in a running Foundry: 14 pregens in the pack, sheets render with the portraits, coherence and hit points fill from the template, no system errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7f8355f0d0 |
Add the player primer and cheat sheet, and brand every journal
Ten pages a player reads before session one, in their own compendium at OBSERVER ownership: nine of setting, one cheat sheet. The draft called the organisation "the Bureau"; everything else in the game calls it the department or the agency, so that is what it is called. Thin areas filled rather than padded: the seven character principles as a list, the real Coherence band table instead of a paragraph describing one, and "what continuity is not" pulled out of the middle of a page because it is the most important sentence for a new player. The cheat sheet's numbers are computed from rules.mjs and lang/en.json at build time. A hand-typed one would have been the sixth time this project shipped a number that disagreed with the code, and the one the players were holding. R-250: the design tokens were never on :root. Journals rendered as default parchment, and four things were wrong in sequence — v14's hook is renderJournalEntrySheet; its `element` is the node, so `[0]` returns the first CHILD and put the class on a header button; there is no .journal-page-content in v14; and then the real one: with the selector matching, font-size, line-height and padding all applied while every colour did not, because the palette is declared on .ringbrp-sheet/.ringbrp-chat/.ringbrp-window and never on :root. A journal inherited no tokens, so every var() silently became nothing. A rule that HALF applies is not a specificity problem — I spent three attempts treating it as one, including a version bump on a cache theory that was wrong. Branded: primer, rulebook, starter GM text and handouts. Scoped by flag, so other modules' journals are untouched. Version 0.9.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d9bce12c27 |
Replace the starter with BLACK PLATFORM, and make the dialogs ask questions
The starter is now an action case: a train running through a station whose rails were lifted in 1976, two engineers aboard, eleven minutes until it returns. Descend, take the platform, board, rescue, fight forward along a moving train, stop it. Simpler than PAPER WINDOW on purpose — one clue scene, no social subsystem — which also means it cannot reproduce R-248, because there are no groups or standings to leave unwired. Every agent can fight, deliberately: floors of firearm 42%, melee 40%, Brawl 40%, Dodge 40% so nobody is a spectator on their first evening. Floors only RAISE, so a posting already better stays better — Callum's shield lands at 53, not the floor's 45. The builder now handles combat floors, extra weapons issued for a case, and a scenario with NO Borrowed Authority at all; the last was assumed to exist and would have thrown. Two new tests: every floor names a real skill, and every agent clears the fighting floors the handout promises. Sixty-two dialog strings reworded. They were naming mechanics at people: "Situational modifier %" is now "Anything else helping or hurting? (%)", "Target cover" is "Is the target behind anything?", "Difficult (÷2)" is "Difficult — half your skill". Labels ask the question; hints say what it does to the number; notifications say what to do next rather than what went wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4e28de2a64 |
Play PAPER WINDOW with the shipped pregens; fix four silent defects
Ran the starter end to end. It closed, and it found four defects in what I shipped an hour earlier — all in the scenario data, all silent. R-247: the Borrowed Authority did not work. I wrote scope "operate", which is not one of the five scope tiers; an unrecognised scope ranks 0 and every action came back "impossible" with no error. The first scene of the starter is the Borrowed Authority tutorial. Fixed, guarded in check-kits, and covered by a test that documents the failure mode. R-248: the contact subsystem was unreachable in the scenario built around it. The case file carried a standing for the Returned Clerks and no GROUP ITEM; resolveContact returns null without one, so READ, SIGNAL and OFFER did nothing. Groups are data now, and a test asserts every standing on a shipped case file has a group behind it. R-249: legs wrote `kindId` where resolveLegDialog reads `leg.kind`. It worked only because the terrain text happens to begin with "Extraction". Not a defect: phase four went Difficult because Resources hit 0 and destitution makes every remaining phase Difficult. Best beat in the session. All four phases failed and the case still closed — Containment 8 to 2, Resources 8 to 0 — which is what the scenario is built to survive. Two of six closing requirements succeeded and the settlement still completed. The Cancellation Man opened with a critical against a raised riot shield and went through 10 points of armour, teaching the shield and graded-defence lessons in one roll. Also documented: nobody on the starter team can aim the return, because only the Anchor Officer trains Transposition. The extraction page now says to narrate it rather than roll six dice that will all fail. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
49c2e9fc7b |
Add PAPER WINDOW as the starter scenario Adventure
The six-player introductory case ships as a Foundry Adventure in a new `starter` pack, because a scenario that arrives as nine loose documents a GM has to assemble is a scenario that gets read rather than run. One import brings in: the GM scenario in twelve pages; the seven player handouts as their own journal at OBSERVER ownership so they can be revealed one at a time without the GM editing permissions first, while the GM text stays hidden; the six pregens built through the same buildActor path the shipped pregens use, so they arrive with full skill lists, kit, hit points and linked tokens; the cast, including the Cancellation Man; the Borrowed Authority as a real credential with scope, Trust 2 and its three red flags; and the case file already at Containment 8 / Resources 8 / Clearance 6 with its four phases loaded at the stated difficulties and modifiers. Pregen ratings are fixed at mid-band rather than rolled — a pregen that varies between installs is not a pregen. The expansion from posting or trade into a sheet reuses the register and the induction rule rather than restating them, so the starter cannot drift from the generator. Verified by importing it: no errors, the roster resolves through stable keys, handouts arrive player-visible, Nia has the team's highest Tradecraft as the text requires, Callum's shield is slung so raising it is still a decision, the three probationers show the trade/induction split, and phase one runs out of the box. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
43508259ac |
Consolidation pass after a Codex review
Four real defects, each verified against the source before acting on it. Trade expertise was coupled to agency rank. A probationary burglar came out at 35-50% and a veteran at 65-80%, as though fifteen years of picking locks were something the department conferred. TRADE_BANDS is now fixed at 50-65/30-50 at every rank, and INDUCTION scales with service instead (20-32 probationary to 45-60 veteran) because that half genuinely is the department's. The two axes were the wrong way round. This is the thing I flagged myself after PAPER HARBOUR and then left alone — flagging a defect is not the same as fixing it. Bonus points were sprayed across every skill in the game. grantFullSkillList runs immediately before the loop and puts all fifty-nine skills on the sheet, and the loop picked from actor.items, so a veteran's ninety points landed anywhere. The comment two hundred lines above has always said "over the core skills"; the code never did. "Random species" passed "baseline" into generators that support random perfectly well. No behavioural tests. The strongest point in the review: the three guards are static and none of them can tell whether a rule is READ, which is the only kind of defect this project has ever shipped. tools/check-behaviour.mjs now runs 28 deterministic tests, gated into the build, covering R-231/232/243/245/246, graded defences and the lamp rule. Proved it bites by re-breaking R-246. The register moved to postings.mjs, a Foundry-neutral module the engine, rulebook, guards and tests all import normally — they were previously pulled out of the engine with a regex and eval, which worked and was a trap. My first version of that used `export … from`, which re-exports without local bindings, so ROLES was undefined and the system threw on init: node --check passes that, loading it in Foundry does not. Also: the contact doc comment still said "only OFFER moves standing"; check-kits accepted mas/app, which are the DISPLAY names of siz/cha, so a posting declaring one would have passed and produced an undefined characteristic; package.json disagreed with the manifest; README counts were three revisions stale and are now generated at build. Deferred with reasons: splitting the 6,700-line engine into modules. Right, and a multi-session refactor whose risk is exactly the silent breakage demonstrated above. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
2e10ecced9 |
Fire modes, fitted sights and lamps, and a tab rail
Selectable fire, with the modifiers on the choice Every weapon has carried a fireMode since the packs were first built and nothing read it: a musket could rip a ten-round burst and "rapid" bought a weapon nothing. FIRE_MODE now gates the burst rules and carries its own attack modifier — slow +10% and then you work for the next one, fast a second shot at -20% to both, rapid bursts, beam +5% and it can be held on the target for damage instead of hits. The gate lives in burstAttack too, so no macro can route round it. `fast` was on five catalogue weapons and was not in the system's list of modes at all, so re-saving one of them silently blanked it; the list is derived from the rule now. burstAttack shipped complete and was reachable from nothing. It is the resolution path the selector chooses, and takes the dialog's whole stack rather than charging the player twice for the same burst. Sights and lamps that apply themselves A sight is graded by range band, so a telescopic sight is a -10% liability inside ten metres and worth +20% at extreme, and it only counts if it fits. The band is already known when the modifier is wanted, so nothing is selected and nothing is forgotten. The dark costs something now; a carried lamp buys it back to dim, never to daylight, and the card says it shows them exactly where you are. A migration fits gear that predates the fields, matched on the stamped key rather than by name. The damage card The last card still wearing Foundry's stock dice styling — it posted a bare Roll and let the core template dress it. It renders through the module's own card now, with the Roll still on the message so dice stay inspectable. A rail instead of a strip Eight tabs across an 820px sheet compressed to 11px type. They run down the side now, one line each, with counts as badges; the sheet is 152px wider to pay for it. Also fixed: any weapon with a Coherence cost could not be attacked with AT ALL — the handler re-read the weapon after an await, when currentTarget is already null, and the attack died on a TypeError with nothing shown. And the duplicate-rule guard failed an honest table because FIRE_MODE and speedBands share two key names; it wants a majority now, and prints partial overlaps rather than swallowing them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d0144f744e |
The Custodians v0.6.1 — full system
A Foundry VTT game system: Basic Roleplaying d100 in a drab British agency that deals with crossings, where reality keeps a record of what belongs where and can be made to get it wrong. Contents: - rules.mjs as the single authority for every rule formula, with 40 rules and 132 spot-checked values. Nothing may restate a formula it defines. - 25 postings, each with a key characteristic, trained skills, talents and its own kit; a 175-item catalogue across four eras; 231 generated icons. - Reaction Lanes initiative, re-rolled every round including the first. - Coherence, and the Quiet Arts, which only ever arrive from a crossing gone wrong. - Graded defences: only a critical stops a critical. - Borrowed Authority — access as a record rather than a hacking roll. - A case generator, and a rules journal generated from rules.mjs so the book cannot drift from the code. Built compendia are committed so a remote Foundry needs only the files. node_modules is not; `npm install` restores it for rebuilding content. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |