adding classification and division yard updates, train collisions, engine and car updates, turnout improvements.
This commit is contained in:
@@ -9,16 +9,45 @@ Ordered within each section by how much it is currently costing us.
|
||||
|
||||
## Next
|
||||
|
||||
- [ ] **A "load" is stored as a car, so rolling stock cannot be counted.** `outboundBox`,
|
||||
`inboundBox` and `menAtWork` all hold `RollingStock`, and `freightAgent.stockOutbound` takes a
|
||||
LOADED CAR out of the Division Yard to fill a green box. So a census of every holder comes to
|
||||
92 against the 80 dealt at setup — not necessarily duplication, because some of those objects
|
||||
are cargo in transit rather than cars, but there is no way to tell them apart. Until a load is
|
||||
its own type, "is any stock being created or destroyed?" is an unanswerable question, and the
|
||||
supply numbers below cannot be tuned with confidence.
|
||||
- [ ] **Engines are not a SUPPLY yet, only a position.** `engineAt` now records where the engine
|
||||
sits in the tray and the consist shows it, but an engine is still conjured with the tray
|
||||
rather than drawn from the Division Yard and returned to it. The rules put engines in the
|
||||
Division Yard alongside the cars, with a predefined number of them, so running out of engines
|
||||
should be a second way trains get held — today only the Crew Tray count does that. Needs a
|
||||
number to start from, then playtesting.
|
||||
- [ ] **The yards are shown on the play page but not in either replay viewer.** The Frame carries
|
||||
them, so it is a rendering job, not a modelling one.
|
||||
- [ ] **The rolling stock supply is a guess.** `ROLLING_STOCK_SUPPLY` (coach 8+8, boxcar 10+10,
|
||||
hopper 8+8, reefer 5+5, tank 6+6, caboose 6) is marked provisional in `content.ts` and was
|
||||
scaled alongside the Gap 12 industry increase. Now that the Classification Yard returns stock
|
||||
only when the Division Yard empties, these numbers set the real supply pressure. Adjust from
|
||||
playtesting rather than theory, and watch whether industry density feels light or heavy at the
|
||||
same time.
|
||||
- [ ] **Heavy Grade orientation is rolled, not chosen.** The card prints "Player sets orientation",
|
||||
but it is dealt during setup and setup has no decision point at all — `createGame` is a pure
|
||||
function of the seed, which is also what makes a save portable. Rolled from the seed for now.
|
||||
Revisit when setup gains an interactive phase; the orientation matters, because it decides
|
||||
which direction climbs and therefore what Brakeman and Helpers are worth.
|
||||
|
||||
- [ ] **Measure with error bars from now on.** Revenue has a standard deviation of ~9, so a
|
||||
100-game run carries about ±1.0 of noise — every single-change revenue claim in the changelog
|
||||
before the Interlocking work is inside that. Use paired per-seed comparison (the harness deals
|
||||
the same seeds either way) and 400+ games before calling a heuristic change good or bad. The
|
||||
first attempt at the Running Track straight was read as a 0.6 REGRESSION on 100 games and is
|
||||
a 0.7 improvement on 400.
|
||||
- [ ] **Confirm the Classification Yard rule against the source.** Cars now return to the Division
|
||||
Yard at the Day boundary — an ASSUMPTION, not a recovered rule. Gap 2c says everything but
|
||||
cabooses goes to Classification and never says how it empties. It is worth +2.32 revenue a
|
||||
game, so if the real rule differs the balance numbers move with it.
|
||||
- [x] ~~**Confirm the Classification Yard rule against the source.**~~ Confirmed, and the guess was
|
||||
wrong. The rule is: used Rolling Stock to the Classification Yard, used engines and cabooses
|
||||
straight back to the Division Yard, and the Classification Yard empties ONLY when the Division
|
||||
Yard is bare — then all at once. The Day-boundary version I had invented was far more generous
|
||||
and worth **+2.42 revenue a game the game does not actually grant**. Corrected; revenue 9.67
|
||||
→ 7.25.
|
||||
- [x] ~~**Enhancements are placed but mostly do nothing.**~~ Measured: forbidding every Enhancement
|
||||
except Interlocking is worth **-0.01 ± 0.41 (t = -0.04)** over 400 paired seeds. They neither
|
||||
pay nor cost. Left alone. Unlocking the Running Track straight put
|
||||
@@ -42,11 +71,8 @@ Ordered within each section by how much it is currently costing us.
|
||||
needs a stocked green box AND a spotted car AND a free Laborer to line up in the same Stage.
|
||||
Measure how many Stages have all three before changing any heuristic — the answer may be that
|
||||
the economy, not the bot, is what caps freight.
|
||||
- [ ] **`stats.ts` undercounts freight.** `rev.freightUnload` is assigned `eventCounts['unloadBegan']`
|
||||
— unloads *begun*, not revenue *earned* — and `grossFreight` uses `freightLoad` alone, so
|
||||
`freightShare` omits unload revenue entirely. The comment justifying it ("an unload scores
|
||||
through the same event as a load completion") is wrong: `apply.ts:947` emits a distinct
|
||||
`freightUnload` reason. This is why freight was recorded at 13–18% of gross.
|
||||
- [x] ~~**`stats.ts` undercounts freight.**~~ Fixed: both halves counted, freight share 39% → 49%.
|
||||
Worth revisiting the **industry density** decision below, which was taken on the old number.
|
||||
|
||||
---
|
||||
|
||||
@@ -54,13 +80,9 @@ Ordered within each section by how much it is currently costing us.
|
||||
|
||||
Blocked on a decision, not on work.
|
||||
|
||||
- [ ] **Q13 — rear-end collisions on a Mainline card.** §10 says a Mainline collision is the
|
||||
Superintendent's fault and removes both trains, and ABS Signals exists to prevent rear-enders —
|
||||
but §8.3's trigger list does not include one, and **none is implemented**. Granting clearance is
|
||||
currently free: verified, both trains survive, no penalty. Three candidates: collide on entry
|
||||
(clearance becomes a gamble), collide on catching up (rewards judging the gap), or accept that
|
||||
clearance is safe and ABS Signals is worth less than it reads. The buttons currently describe
|
||||
only what the engine does, so nothing promises a consequence that cannot happen.
|
||||
- [x] ~~**Q13 — rear-end collisions on a Mainline card.**~~ Answered: collide on catching up.
|
||||
Implemented, and not on cards that print "trains may pass". Invisible to a bot that always
|
||||
denies clearance; a bot that always allows drops from 7.34 revenue to **-5.13**.
|
||||
- [ ] **Poling.** The only card in the deck with no defined behaviour — the sheet records its effect
|
||||
as "TBD in the source". A test asserts it stays TBD so nobody invents one.
|
||||
- [ ] **Heavy Grade orientation at setup.** The card says "Player sets orientation", but `createGame`
|
||||
@@ -165,7 +187,11 @@ target is settled and freight carries its intended share.
|
||||
- [ ] **No way to start a fresh game from inside the page.** `?seed=` gives a reproducible deal and
|
||||
"new game" only appears once a game has ended, so abandoning a bad opening means editing the URL.
|
||||
- [ ] **Save/restore is not version-aware.** A save from an older ruleset stops replaying rather than
|
||||
failing loudly, which is the safe direction but says little about what changed.
|
||||
failing loudly, which is the safe direction but says little about what changed. **This has now
|
||||
bitten once**: both published replays were dead — one got 42 intents into 360, the other 4 of
|
||||
338 — and nothing said so; they simply ended early and looked like short games. A save should
|
||||
carry a ruleset stamp and the page should say "this replay was recorded under an older
|
||||
ruleset and stops at Stage N" rather than presenting a truncated game as a whole one.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user