v0.64.0: market top-up + coverage spawn run on every tick including frozen ones, so a grounded fleet can never drain the market to zero (#135 follow-up)
CI / build + unit + e2e (pull_request) Successful in 14m12s

This commit is contained in:
2026-09-23 10:07:28 +00:00
parent d7f352adcf
commit b2ff1d631b
5 changed files with 81 additions and 9 deletions
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## v0.64.0 — 2026-09-23 10:06
- **Market keeps topping up while the fleet is grounded (#135 follow-up).** Root cause of a soft-lock introduced by v0.62.0's frozen clock: in `tickOnce` (`lib/sim/engine.ts`) every package-CREATION path (market top-up + coverage spawn) sat behind the same `advanceMs > 0` gate as expiry/delivery/repairs, while removal paths did not — `ignorePackage` runs on any request regardless of advance. A fully grounded fleet therefore froze the clock AND stopped all spawning, so repeated ignores could drain the market below `MARKET_TARGET_OPEN_PACKAGES = 10` (down to zero) and no code path ever created new jobs again: a player with a grounded fleet and an empty market was stuck forever. Fix: only the two spawn calls moved OUT of the gate — `spawnOpenPackages` + `spawnCoveragePackages` now run on EVERY tick, including frozen ones, passing the current (possibly frozen) `clockMs`; `expirePackages`, `deliverPackages` and `finishRepairs` stay inside it. Both spawns were already idempotent no-ops when satisfied (count-gated at target / set-gated by uncovered grounded airports), so advancing ticks behave exactly as before and the clock stays EXACTLY frozen while grounded — only new packages appear, created at game time. No schema change, no migration, no other engine behavior touched.
- **Tests.** Unit: `lib/sim/engine.test.ts` — "a frozen tick still tops up the market so a grounded fleet never starves (#135 follow-up)": fully grounded fleet (advance=false), open market drained to zero via direct DB writes, one tick → asserts BOTH that `sim.clockMs` is unchanged (freeze preserved) AND that the open count is back at ≥ `MARKET_TARGET_OPEN_PACKAGES` with ≥1 open package originating at the grounded starter's airport (EDDF coverage). E2E: `e2e/sim.spec.ts` — "a grounded fleet never starves: ignoring every open package cannot empty the market (#135 follow-up)": self-heals to a fully grounded fleet, drains by calling `POST /api/packages/[id]/ignore` for every open package in repeated passes (pre-fix this reached zero and stayed there; post-fix each request's tick re-tops-up before its removal, so it can't), then `expect.poll`s that the open count from `/api/state` is above 0 within ~5 s of real time while asserting `simState.clockMs` stays EXACTLY equal to its pre-drain value and no plane took off — pinning both starvation-fixed and clock-still-frozen.
## v0.63.0 — 2026-09-23 08:43
- **Overlay colors retuned for the Fiord default (ISS-118).** The first half of this issue landed in v0.4.0 (`DEFAULT_STYLE_ID = 'fiord'` + top-bar switcher, e2e already pins `toHaveValue('fiord')`); this completes the second half — auditing every color drawn on the map against Fiord's actual palette. Key finding: OpenFreeMap's Fiord is a DARK cool-toned basemap (land #45516E slate, water #38435C navy — verified byte-identical between the self-hosted `public/styles/fiord.json` and `tiles.openfreemap.org/styles/fiord`), not a light one. WCAG contrast audit of all nine overlay colors against both base surfaces: seven already read fine (≥ 3.3:1 on land AND water) and are untouched — amber flying leg #f59e0b, gold dotted queue line #d4a017 (ISS-098 picked it for light+dark), sky-blue grounded plane + hover halo #38bdf8, green flying plane #22c55e, yellow hover ring/trace #facc15, green target ring #4ade80. Two were weak and got brightened one step within the same hue family: airport dot fill rose-600 #e11d48 (1.68:1 on slate land — the weakest element on the map) → rose-500 #f43f5e (2.15:1), and the hovered-route highlight red-500 #ef4444 (2.10:1, below the 3:1 graphical-object bar for an emphasis layer) → red-400 #f87171 (2.86:1 on land / 3.57:1 on water). White strokes and all other paint values unchanged; no new constants — both colors are single-use inline paint values, matching the existing style of this file.
- **Tests.** No test changes needed: `components/map.test.ts` pins only #d4a017 (untouched), e2e specs query rendered features by id/layer rather than color, and `lib/mapStyles.test.ts` already pins `DEFAULT_STYLE_ID = 'fiord'`.