Add The Frontier, a second setting, and a picker to choose between them

Cold Fork is a freight yard: 29 events across two stages, a four-day cycle, and
its own relationship and skill vocabulary. src/engine/ was not touched. Adding it
needed three changes outside the engine: one save slot per pack, app.js holding
the current pack, and turn.js no longer naming the mailroom (DECISIONS #34).
build.js now handles imports wrapped across lines. A conformance suite runs over
every registered pack. DECISIONS #35 records three calls on open questions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RxdJFbLq1rBKsUeticGV1g
This commit is contained in:
JesseMarkowitz
2026-09-12 21:03:50 -04:00
co-authored by Claude Opus 5
parent 4957c24e31
commit 7f20be83e8
25 changed files with 3015 additions and 300 deletions
+139
View File
@@ -0,0 +1,139 @@
// Running out of money.
//
// No game over and no failure mode in the engine — these are ordinary events
// whose conditions happen to be about money, weighted heavily enough to crowd
// out an ordinary day. Neither declares a stage: being broke follows you up
// the ladder rather than vanishing when you take the star.
//
// The arithmetic that matters, and the one Corporate Ladder got wrong once:
// `every_run` pays 30 against a room-and-board cycle of 20 and a fully-loaded
// store charge of 10, so there is always a way out that is worth more than the
// hole is deep. Change either number and re-derive the other.
export const hardTimes = [
{
id: 'store_cut_off',
// Heavy, but on a cooldown: being broke should colour a run, not become
// the run. Corporate Ladder learned this the expensive way at weight 5000
// with no cooldown.
weight: 900,
cooldown: 3,
requires: [{ path: 'money', op: '<', value: 0 }],
description:
'The storekeeper turns the book round on the counter so you can see ' +
'your own line in it, and does not say anything at all, which is worse ' +
'than the several things he could have said.',
options: [
{
id: 'on_the_book',
label: 'Ask him to carry you a while longer.',
// He stops eventually. Past that, the ways out cost standing and
// favours rather than interest, which is where the spiral gets real.
requires: [{ path: 'owed', op: '<', value: 120 }],
result:
'He turns the book back round and writes it. The figure at the ' +
'bottom of your line is now larger than a month of runs.',
effects: [
{ path: 'money', op: 'add', value: 30 },
{ path: 'owed', op: 'add', value: 32 },
{ path: 'flags.owes_the_store', op: 'set', value: true },
{ path: 'standing', op: 'add', value: -2 },
{ path: 'notable', op: 'push', value: 'Went further into the book at the store.' },
],
},
{
id: 'ask_dutch',
label: 'Ask Dutch to settle a line of his own.',
requires: [{ path: 'relationships.dutch.owes_you', op: '>=', value: 20 }],
result:
'He pays it without a word and crosses it out of the book in front ' +
'of you, and afterwards you are a man he has settled with rather ' +
'than a man he owes.',
effects: [
{ path: 'money', op: 'add', value: 18 },
{ path: 'relationships.dutch.owes_you', op: 'add', value: -20 },
{ path: 'relationships.dutch.trusts_you', op: 'add', value: -3 },
{ path: 'notable', op: 'push', value: 'Called in what Dutch owed.' },
],
},
{
id: 'ask_hollis',
label: 'Ask Vane for the smith’s money back.',
requires: [{ path: 'relationships.hollis.owes_you', op: '>=', value: 20 }],
result:
'He pays in the doorway, in full, and finds a reason not to look at ' +
'you for the rest of the week.',
effects: [
{ path: 'money', op: 'add', value: 22 },
{ path: 'relationships.hollis.owes_you', op: 'add', value: -20 },
{ path: 'relationships.hollis.trusts_you', op: 'add', value: -4 },
],
},
{
id: 'every_run',
label: 'Take every run going.',
// Has to be worth more than a cycle of room and board plus the fully
// stepped-up store charge, or it is not a way out — it is the hole
// with extra hours in it.
result:
'Eleven days without one off. The Ridge road stops being a road ' +
'after a while and becomes a sequence of turns you take.',
effects: [
{ path: 'money', op: 'add', value: 30 },
{ path: 'skills.nerve', op: 'add', value: 2 },
{ path: 'standing', op: 'add', value: -1 },
],
},
],
},
{
id: 'the_book_called',
// Often enough to matter. At weight 25 Corporate Ladder's equivalent
// appeared six times in 262 turns and debt became a one-way ratchet.
weight: 45,
cooldown: 4,
requires: [{ path: 'owed', op: '>', value: 0 }],
description:
'The storekeeper has written to the county about three lines in his ' +
'book and yours is one of them. He mentions this to you in the street, ' +
'in daylight, in front of two other people.',
options: [
{
id: 'pay_chunk',
label: 'Pay a real piece of it down.',
requires: [{ path: 'money', op: '>=', value: 45 }],
result: 'He rules a line through most of it and is disappointed about it.',
effects: [
{ path: 'money', op: 'add', value: -45 },
{ path: 'owed', op: 'add', value: -45 },
{ path: 'standing', op: 'add', value: 2 },
],
},
{
id: 'pay_minimum',
label: 'Pay what you have on you.',
requires: [{ path: 'money', op: '>=', value: 12 }],
result: 'Twelve dollars, ten of which is the line and two of which is coffee.',
effects: [
{ path: 'money', op: 'add', value: -12 },
{ path: 'owed', op: 'add', value: -10 },
],
},
{
id: 'stall',
label: 'Tell him after the next stage.',
result:
'He says after the next stage. The two other people in the street ' +
'say nothing, and repeat all of it by evening.',
effects: [
{ path: 'owed', op: 'add', value: 4 },
{ path: 'standing', op: 'add', value: -3 },
{ path: 'relationships.ward.wary_of_you', op: 'add', value: 4 },
],
},
],
},
];
export default hardTimes;