- data/tether.json: new edgeMargin (512 px) — a no-man's-land band around
every tether rim where NO object sits: discoverable objects are clearly
inside a tether region (d ≤ radius − edgeMargin) or clearly outside
(d ≥ radius + edgeMargin), never at the edge (the 'scan doesn't find it
at the boundary' case)
- SystemGenerator.layoutSystem: the regular N-gon ring (chords put 2- and
3-object systems past level 2, spread 4-/5-object systems too thin) is
replaced by a compact ARC at one orbital radius — consecutive objects a
level-1 tether apart (≤ L1 − edgeMargin — a level-1 chain walks the
whole system), every other pair off both tether rims (the level-2
graph is connected — level 2 DEFINITELY discovers; level 3 never
required); minSpacing now bounds star/home-world→object only,
neighborMin (2048) is the planet↔planet floor; the step angle is a
deterministic scan (safe-α) landing the gap near a seeded target
- home world IS a tether anchor: its orbital radius caps at
L2 − edgeMargin (9728 px); its objects sit 6400–9728 (level-2 zone by
design — the bootstrap tether), chained to each other at level 1
- gates: anchorMaxDistance 4990 → 4608 (= L1 − edgeMargin) so no gate
sits at the level-1 rim either (still < 5000, Rule 1); candidate
ordering is now side > rim-bands > facing tier > order
- Tether.contains: 1 px rim tolerance (a center exactly on the boundary
counts as inside — float safety on top of the layout margin)
- asteroid placement tetherMargin 96 → 512 (aligned with edgeMargin)
- dev/system-layout.test.mjs (new): level-1 chain, level-2 connectivity,
edge margin, orbital band, same-seed determinism — 90-system galaxies,
all green; discovery/jumps/audit tests + PROJECT_NOTES follow the rules
- Replace the fixed level-1 tether radius (5120 px) with a configurable
`anchorMinDistance`/`anchorMaxDistance` band (default 3500–4990), capped by
the tether range, so gate distance from its planet varies per gate while
staying strictly < 5000 px.
- Generate candidate positions on 8 discrete radius steps spanning the band;
a seeded preferred step orders them and clearance/gap pressure only pushes
the gate outward from its preference.
- Update the tether check in `dev/jumps.test.mjs` to assert the gate sits
within the anchor band rather than merely under the tether radius, and use
the band max for facing-side calculations.
- Update `dev/tether-rules.audit.mjs` Rule 1 to verify < 5000 px and report
the distribution of gate→anchor distances across the band.
- Refresh comments in `data/gates.json`, `docs/PROJECT_NOTES.md`, and
`SystemGenerator.js` to describe the new band-based placement.
- Introduce the oac-system-complete visual comm that fires on the
'systemComplete' trigger when a system's jumpgate research unlocks,
arming before the generic researchComplete sign-off so the FIFO plays
specific -> generic.
- Support an optional audioPool list of speech clips in CommsModel; the
hub picks one at random per arm so only the chosen clip is fetched and
cached, with validation that audio comms need a clip or pool.
- Wire GameScene to trigger systemComplete on activateGates when the
system nav chart is complete.
- Update comms tests for the new comm, pool normalization/asset rolling,
roster counts, and add a tether-rules audit script plus station shop
video references and lava assets.