→ Parent: GDD.md
Player Setup Traits & Free-Scenario Setup Ranges¶
The concrete, buildable catalog behind the Free-Scenario setup screen (GDD — Player Setup at Start). This doc closes the open risk from the P0 setup-maps-onto-founding pin (GDD — Free-Scenario Setup Maps onto the Shipped Founding Flow): Starting traits were flagged there as the field with the thinnest shipped support. This pins their payload.
Everything here rides the already-shipped founding seam —
FoundingService.AvailableQuotes(playerStandingByRegion, …) in
scripts/services/FoundingService.cs. A trait's mechanical half is nothing more
than a per-region delta on the player's founding standing. No new engine
mechanic is required; see No New Machinery.
Scope: the two shipped 1920s Michigan seeds (scenario-catalog-copy.md). Traits are period-honest to that setting.
The standing scale traits operate in¶
Traits emit deltas in the founding-standing scale the founding flow consumes, which is the goodwill scale (Goodwill — The Score: 0–100):
- 0–100, Neutral = 50. 0 is maximum hostility, 100 maximum favor.
- The founding flow reads a per-region value
S_playerfor eachmajorUrbanregion and: - Gates the region — a region produces a quote only when
S_player ≥ quoteEligibilityThreshold(60 in both Michigan seeds,founding.quoteEligibilityThreshold). Below 60, that region offers no underwriter at all. - Bends the terms — the terms score is
t = clamp((0.6·S_player + 0.4·firmReputation) / 100, 0, 1)(standingWeights.player = 0.6,firm = 0.4). Highert⇒ less equity surrendered and a lower underwriting fee. Across the eligible bandS_player ∈ [60, 100]against a generic firm (reputation 50),tswings from 0.56 to 0.80 — every +10 standing is +0.06 tot. Real, not runaway.
Design consequence that governs every delta below: the interesting line is 60. A region at neutral-50 is shut out of founding. Traits are the lever that pushes a region over 60 (opening it) or under 60 (closing a region the baseline would otherwise open). That is where the tension lives — a trait is not "a few percent better terms," it decides which financial center will even talk to you.
Setup baseline standing (before any trait)¶
The setup screen starts every majorUrban region at Neutral = 50 — one
below the eligibility line, deliberately. Rationale (Pillar 2 — reputation always
matters, and Pillar 6 — the player sets their own depth): a brand-new promoter
with no stated background is a nobody in every financial center and gets no
quote anywhere until a trait vouches for them. Trait selection is therefore the
act that earns you a founding seat, not a bonus on a seat you already had.
Baseline is 50, not the seed's authored
playerFoundingStandingByRegion. The canonical seed authors{ "wayne_detroit": 70 }for its scripted founding-at-start moment (Standalone). Free-Scenario replaces that scripted seed with the setup-screen assembly below. The two do not stack; Free-Scenario ignores the authored map and buildsplayerStandingByRegionfresh from baseline + traits.
The six majorUrban regions in the canonical Michigan seed (the only regions a
founding quote can come from, per
GDD — HQ region mapping):
| Region id | City | Period identity |
|---|---|---|
wayne_detroit |
Detroit | Auto capital; the state's money center. |
kent_grand_rapids |
Grand Rapids | "Furniture City"; west-Michigan commercial hub. |
genesee_flint |
Flint | Buick / GM; a company town on the rise. |
saginaw_saginaw |
Saginaw | Sugar-beet, salt, ex-lumber valley money. |
ingham_lansing |
Lansing | State capital; Olds / REO autos. |
oakland_pontiac |
Pontiac | Oakland Motor / carriage-to-auto county seat. |
Kalamazoo, Battle Creek, Jackson, Bay City, Ann Arbor et al. are real 1920s cities but are not flagged
majorUrbanin the seed, so they cannot host a founding quote regardless of standing. Traits that mention them (e.g. cereal, paper) therefore route their mechanical effect to the nearest qualifying money center, and carry their local color as flavor. Do not author a trait whose only mechanical effect targets a non-majorUrbanregion — it would be inert on the founding seam.
The trait catalog (1920s Michigan)¶
Eight setup traits. Each has: a display name, a one-line period flavor, and a mechanical payload = a set of per-region founding-standing deltas applied on top of the 50 baseline. Magnitudes obey the scale rules:
- Strong trait: ~+15 to its home center (50 → 65, clears the 60 gate on its own) paired with a −12 to −15 penalty elsewhere. This is the deficit-for-bonus trade: it opens one region and can close another.
- Modest trait: ~+8 to one or two regions (50 → 58 — not enough to clear 60 alone; it needs a second trait or a strong trait stacked on the same region) with no penalty. Modest traits are the "round out a build" pieces.
This keeps one trait from opening every region: even the strong traits open exactly one center each, and stacking two strongs on the same region is what pushes toward the low-cost end of the terms curve (see Trait-count & tension rule).
| # | Trait | Flavor (period-grounded) | Mechanical payload (region: Δ standing) | Class |
|---|---|---|---|---|
| 1 | Detroit Financier's Protégé | Cut your teeth in a Griswold Street bond house; the Detroit money knows your name. | wayne_detroit +15; saginaw_saginaw −12 (out-state valley money resents a Detroit insider) |
Strong |
| 2 | Copper-Country Insider | A Calumet mining man who came south with a stake and grudges. | saginaw_saginaw +8, genesee_flint +8; wayne_detroit −12 (the Detroit houses see a rough up-north operator) |
Strong (split) |
| 3 | Furniture-City Man | Grand Rapids-bred; the west-Michigan commercial set backs its own. | kent_grand_rapids +15; wayne_detroit −12 (an out-of-town west-sider in Detroit) |
Strong |
| 4 | Motor-Town Machinist | Rose off the Flint and Pontiac assembly floors into management. | genesee_flint +15, oakland_pontiac +8; kent_grand_rapids −13 (west Michigan distrusts the auto-belt) |
Strong |
| 5 | Capitol-Steps Fixer | You know which doors open in Lansing and who holds the pen. | ingham_lansing +15; saginaw_saginaw −12 (a statehouse operator, resented in the valley) |
Strong |
| 6 | Former Interurban Man | Ran an electric traction line before the autos ate it; respected statewide, feared nowhere. | wayne_detroit +8, ingham_lansing +8, kent_grand_rapids +8 (no penalty) |
Modest |
| 7 | Sugar-Beet Trustee | Sat on a Saginaw Valley beet-sugar board; the out-state money vouches for you. | saginaw_saginaw +15; oakland_pontiac −12 (an out-state name the auto-county set doesn't know) |
Strong |
| 8 | Distrusted by the Grange | The farm bloc remembers a rate fight you were on the wrong side of. | kent_grand_rapids −10, saginaw_saginaw −10, ingham_lansing −10 (no bonus — a pure liability trait, taken only to unlock a cash offset; see tension rule) |
Penalty-only |
Notes:
- Trait 8 ("Distrusted by the Grange") carries no standing bonus and only penalties. It exists as the cash-offset lever in the tension rule: selecting a liability trait buys back trait-budget or cash. It is period-true — the Grange (farm bloc) was a real anti-railroad political force, and a promoter tarred by a rate dispute would carry that. Never surface it as "free," only as an offset.
- Every strong trait's penalty lands on a different region than its bonus, so a single strong trait's net is still a trade, not a free win.
- Because the baseline is 50 and the gate is 60, only a strong trait (or two stacked modest traits) opens a region. A player who picks only modest traits gets several regions in the 58 band — eligible for nothing — and must commit to at least one strong trait to found at all. That is the intended pressure.
Flavor-only companions (NOT founding-seam effects)¶
Some things a trait wants to do cannot be expressed on the founding seam (which only reads a per-region standing at the single founding moment). Per the P0 two-layer split (setup trait = a standing delta + any authored in-play modifier; flavor trait = texture only), the following are pinned flavor-only — event-prose hooks and contextual color, no mechanical payload at setup, because the shipped seam cannot carry a mid-game or non-founding-region modifier:
- Any ongoing/in-play modifier — e.g. "Former Interurban Man gives −5% passenger operating cost." The founding seam is a one-shot standing read; it cannot express a recurring modifier. If such an effect is ever wanted, it is a separate future in-play-modifier system, explicitly out of scope here — do not invent it to back a trait. Until then, that half of the trait is flavor.
- Effects targeting non-
majorUrbanregions — e.g. a "Cereal-City Insider" raising Battle Creek standing. Battle Creek is notmajorUrban, so it hosts no founding quote; the effect has nowhere to land on the seam. Carry the identity as flavor and, if a mechanical hook is desired, route it to the nearest money center (e.g.kent_grand_rapids) instead. - Non-founding stakeholder standing (Labor, a specific industrial baron, a
rival road) — the setup seed the founding flow reads is per-region, not
per-named-stakeholder. Named-stakeholder starting goodwill is a real
Goodwill concept but is not wired into
AvailableQuotes, so at M18 it is flavor only. (If a later milestone seeds per-stakeholder starting standing through a shipped seam, promote it then.)
This is the honest line for the PM: what the setup screen mechanically
delivers at M18 is per-majorUrban-region founding standing and nothing else.
Everything richer is flavor until a seam exists for it.
Trait-count & tension rule¶
So the screen is a build, not a free power-pick:
- Pick up to 3 traits.
- A standing-budget cap. Sum only the positive per-region deltas across all selected traits (across all regions). That sum may not exceed +30.
- Two strong traits (+15 each) exactly hit the cap. A third pick must then be a modest, a penalty-only, or a strong trait whose bonus is already "paid for" — i.e. you cannot stack three strong bonus traits.
- Stacking is allowed and interesting: two strongs on the same region (e.g. two +15 → net +30 on Detroit, 50 → 80) is a legal build that spends the whole budget to drive one center deep into the low-cost terms band (t ≈ 0.68). The trade is that you've opened exactly one region and nothing else — a specialist founding.
- Penalty/liability traits buy back budget OR cash. Selecting a penalty-bearing trait (any negative delta) raises the positive-budget cap by the magnitude of its largest single penalty, or grants a starting-cash bonus of a scenario-authored amount (default +$1,000 to personal cash; see cash range). Author picks one offset per liability trait; both is disallowed. Example: taking Distrusted by the Grange (−10/−10/−10) raises the budget cap from +30 to +40 (a third strong bonus becomes affordable) or adds $1,000 to the founding purse — the classic "take the handicap for the upside" choice.
- Net-standing floor. After all deltas, no region may sit below 30 (clamp). A pile of penalties cannot drive a region into un-recoverable territory; it just keeps it shut out of founding (which is the intended consequence, not a soft-lock).
Pillar note: this honors Pillar 6 (the player sets their own depth) — a cautious player takes modest traits and a broad, shallow standing spread; an aggressive player takes a liability trait to fund a specialist build — and Pillar 2 (reputation always matters) — every trait moves goodwill, and the positive budget guarantees no free reputation.
Free-Scenario setup-field ranges (both Michigan seeds)¶
The concrete ranges the setup screen enforces. These bound the fields that GDD — Free-Scenario Setup Maps onto the Shipped Founding Flow maps onto the founding flow.
HQ region¶
Restricted to the seed's majorUrban regions (the six above):
wayne_detroit, kent_grand_rapids, genesee_flint, saginaw_saginaw,
ingham_lansing, oakland_pontiac. This is the same flag that gates founding
quotes, so the HQ choice and "which region can underwrite me" are the same set —
picking a frontier town as HQ is not offered because it could never found. The
michigan_contested_1920s seed is a southern-belt subset; enforce the HQ list
against that seed's own majorUrban set (author-verify — it is a corridor
subset, likely Detroit / Grand Rapids / Lansing plus the belt cities that carry
the flag there), not the canonical six.
Era¶
Locked to 1920. Both shipped seeds author a single founding date (1920); the
underwriter roster's activeFrom/activeUntil windows are set for that year.
The setup screen offers 1920 only for these seeds — no era slider — until a
seed authors more than one era. (Pillar 4 — time and information have texture;
the founding date is what the underwriter filter keys on, so it must stay within
the authored roster window.)
Starting cash¶
The personal-cash pool that sets the ceiling on the founding contribution C
(C ∈ [0, min(personal cash, K)], where K = targetCapitalization = $10,000):
- Range: $1,500 – $5,000. Default $3,000.
- Rationale: the canonical seed's scripted founder contributes $3,000 of a
$10,000 target (
playerContribution: 3000,targetCapitalization: 10000). The Free-Scenario default matches it — a genuine but survivable promoter's stake that funds a meaningful founder equity slice (C/K = 30%) while leavingneed = $7,000for the underwriter, so the founding screen still poses the cash/equity trade. The range lets a shoestring founder ($1,500 → thin stake, underwriter takes more equity) or a better-capitalized one ($5,000 → half self-funded) without ever reaching self-funded (C ≥ K = $10,000 skips the underwriter entirely, killing the whole founding decision — so the ceiling is held well below K). - Liability-trait cash offset (tension rule #3) adds to this pool after the slider, and may push effective personal cash above $5,000 but is still capped below K so a fully-self-funded skip stays impossible.
Do not use the contested seed's
playerStartingCash: 5,000,000. That is a test-harness sentinel to isolate the corridor-contest property, per scenario-catalog-copy.md — never a player-facing starting purse. Free-Scenario uses the range above for both seeds; the setup screen must not read the rawplayerStartingCashoff the contested seed.
Player character name¶
Free text; no mechanical coupling (per the GDD mapping). No range to enforce beyond a sane length/character validation, which is a UI concern.
How traits assemble into playerStandingByRegion¶
The pin game-dev needs to turn "player selected traits X, Y, Z" into the dict
FoundingService.AvailableQuotes reads. This is assembly, not new logic — it
builds the same IReadOnlyDictionary<string, decimal> the shipped seam already
takes.
Build playerStandingByRegion(selectedTraits, majorUrbanRegionIds):
1. Seed every majorUrban region at the Neutral baseline:
standing[region] = 50 for each region in majorUrbanRegionIds
2. For each selected trait, for each (region, delta) in its payload:
standing[region] += delta // region must be in the dict/majorUrban set
3. Clamp each region to the floor/ceiling:
standing[region] = clamp(standing[region], 30, 100) // 30 floor per tension rule #4
4. Result IS the playerStandingByRegion dict passed to
FoundingService.AvailableQuotes(playerStandingByRegion, roster, cfg,
majorUrbanRegionIds, foundingDate, C).
Then the shipped seam does the rest unchanged: regions below cfg.QuoteEligibilityThreshold
(60) are skipped, the rest produce quotes ordered by standing. Free-Scenario
does not touch founding.playerFoundingStandingByRegion or
founding.playerContribution in the seed — those are the Standalone scripted
seed; Free-Scenario supplies its own dict (this assembly) and its own C (the
cash slider).
Where this assembly lives is an implementation call for game-dev (a pure-C#
helper in scripts/services/ fed by the setup-screen UI is the natural home,
mirroring the service/UI split). The trait catalog data itself should be
authored in JSON per the
data-in-JSON rule — a setupTraits block (per
scenario or a shared catalog file), each entry carrying id, displayName,
flavor, class, a standingDeltas map, and any cashOffset — never hardcoded
in C#. Magnitudes above are the pinned starting values and are scenario-tunable.
No new machinery¶
Confirmation for the record: every mechanical effect in this doc is expressed
as a per-region entry in the playerStandingByRegion dict that
FoundingService.AvailableQuotes(playerStandingByRegion, …) already accepts.
A trait lowers or raises a region's standing; the founding quotes change with
no new engine mechanic, no new service, no schema change to FoundingService.
The only net-new artifacts are data (the JSON trait catalog) and a UI-fed
assembly helper (the pseudocode above), both squarely on the shipped seam.
Anything a trait wanted to do that the seam cannot carry (in-play modifiers,
non-majorUrban targets, per-named-stakeholder standing) is pinned
flavor-only — not backed
by an invented in-play-modifier system.
Open questions¶
- Contested seed's
majorUrbanset — the HQ/quote region list formichigan_contested_1920smust be verified against that seed's region profiles (it is a southern-belt subset), not assumed equal to the canonical six. Author-verify before wiring the setup screen for that seed. - Cash-offset magnitude ($1,000 default) and the positive-budget cap (+30) are first-pass tuning values; confirm in a Free-Scenario founding playtest that a legal 3-trait build cannot trivialize the founding terms curve.