Add chance and a cast that changes between runs, and a pack to try them
An option used to do exactly what it said. Now it may carry a check: one of
four attributes (Nerve, Wits, Charm, Resolve) against a set difficulty or
against a named person's own attribute, leaning on how they regard you, with a
success and a failure. The player sees only the odds in words ("a long shot",
"likely"), never a number. The roll is one draw from the run's generator, so a
run still replays exactly from its seed and choices.
A character may be a role with several authored candidates, one drawn per run,
or a group of two to four drawn into numbered slots. Everyone carries a name, a
description and the same four attributes as the player, so a replayed pack
meets a different office. Text names people as {partner} or {clerk}, and an
event about "a clerk" binds one present clerk for the turn. The draw and the
binding are saved with the run, and a save from before a pack drew a cast gets
the same one every time it is loaded.
All of it is generic and optional: Corporate Ladder and the Frontier use none
of it and play as before. The Counting House, a one-stage office about 1910
built from the story-to-pack catalogue, exercises it, and was tuned against the
conformance suite by measurement. DECISIONS #41. Version 0.4.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MhABSrqkwTdcybXmheDPr
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
112e558dbb
commit
3108319a2b
@@ -527,3 +527,52 @@ test('the header reads the second pack\'s display map, not the first\'s', async
|
||||
dom.restore();
|
||||
}
|
||||
});
|
||||
|
||||
// ---- a drawn cast, and checks (DECISIONS #41) ----------------------------------
|
||||
|
||||
test('a pack with a drawn cast shows whoever this run drew, and never a placeholder', async () => {
|
||||
const dom = await boot({ pack: 'countinghouse' });
|
||||
try {
|
||||
const people = byClass(dom.root, 'person');
|
||||
// One partner, one chief clerk, and two to four clerks.
|
||||
assert.ok(people.length >= 4 && people.length <= 6, `${people.length} people in the panel`);
|
||||
const titles = byClass(dom.root, 'person__title').map((t) => t.textContent);
|
||||
assert.equal(titles.filter((t) => t === 'Senior Partner').length, 1);
|
||||
assert.equal(titles.filter((t) => t === 'Chief Clerk').length, 1);
|
||||
const clerks = titles.filter((t) => t === 'Clerk').length;
|
||||
assert.ok(clerks >= 2 && clerks <= 4, `${clerks} clerks`);
|
||||
for (let turn = 0; turn < 25; turn++) {
|
||||
assert.doesNotMatch(text(dom.root), /\{[a-z_0-9.]+\}/, 'a {placeholder} reached the screen');
|
||||
enabledOptions(dom.root)[0].click();
|
||||
assert.doesNotMatch(text(dom.root), /\{[a-z_0-9.]+\}/, 'a {placeholder} reached the outcome');
|
||||
firstByClass(dom.root, 'button--next').click();
|
||||
}
|
||||
} finally {
|
||||
dom.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test('a checked option shows its odds in words, and the outcome says whether it came off', async () => {
|
||||
const dom = await boot({ pack: 'countinghouse' });
|
||||
try {
|
||||
let checked;
|
||||
for (let turn = 0; turn < 40 && !checked; turn++) {
|
||||
checked = optionButtons(dom.root).find((b) => !b.disabled && firstByClass(b, 'option__odds'));
|
||||
if (checked) break;
|
||||
enabledOptions(dom.root)[0].click();
|
||||
firstByClass(dom.root, 'button--next').click();
|
||||
}
|
||||
assert.ok(checked, 'a checked option turned up within forty days');
|
||||
const odds = firstByClass(checked, 'option__odds').textContent;
|
||||
assert.match(odds, /^(a long shot|unlikely|an even chance|likely|a safe bet)$/);
|
||||
assert.doesNotMatch(text(dom.root), /\d+%/, 'no percentage is ever shown');
|
||||
|
||||
checked.click();
|
||||
const said = text(firstByClass(dom.root, 'outcome__check'));
|
||||
assert.match(said, /and it (came|did not come) off\./);
|
||||
assert.ok(said.toLowerCase().startsWith(odds), `the outcome repeats the odds: "${said}"`);
|
||||
assert.ok(firstByClass(dom.root, 'outcome__text'), 'and says what happened');
|
||||
} finally {
|
||||
dom.restore();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user