Commit Graph

20 Commits

Author SHA1 Message Date
Brian Fertig 6ecf199da5 Tune jumpgate activation research duration to 20 s
- Reduce data/gates.json activation.researchDuration from 45 s to 20 s so the "Unlock Jumpgates" tech completes faster once all NAV points are discovered.
- Update SystemCategory.js doc comment and fallback default to match the new duration.
- Adjust system-category.test.mjs assertions (duration, save/restore remaining-time math) to the 20 s value.
2026-09-30 15:36:27 -06:00
Brian Fertig 8ade473479 Add faction-tinted swirl to locked jump gates
- Locked gates (neutral → faction, below minLevel) now render their
  swirling center in the controlling faction's hue as an in-world
  "that gate belongs to someone" tell, complementing the comm window's
  grayed REQUEST JUMP and lock message.
- JumpGate.setFactionTint tints the active swirl (setTint) or recolors
  the procedural fallback field discs; null clears back to the ordinary
  swirl. Falsy-but-valid hues (e.g. 0x000000) are not treated as clear.
- GameScene.gateFactionTintFor resolves the destination faction's color;
  _refreshGateFactionTints re-resolves all gates at build, once the XP
  ledger exists (save may have already lifted the lock), and on each
  level-up event to clear tints as the lock lifts.
- Test harness extended with setTint/setFillStyle mocks; new checks cover
  tint apply/clear/falsy-hue on the sprite path and field-disc recolor
  + restore on the fallback path.
2026-09-21 19:07:18 -06:00
Brian Fertig 78593b1ea2 Add faction gate lock blocking neutral→faction jumps below level 5
- New `factionGateLocked` pure rule in JumpTravel.js: a gate from a neutral system into a faction-controlled one is locked while the player's combat level is below `minLevel`; gates from faction space and neutral→neutral hops are never locked
- Config section `gates.jump.factionLock` (enabled switch, minLevel 5, panel message) in data/gates.json
- Gate comm window shows the lock message in place of the LINK line and grays out REQUEST JUMP; case widens to fit the two-line message
- `jumpThroughGate` adds a flat denial toast on top as defense in depth
- Tests cover the rule's branches (neutral/faction/unknown dest, missing level, enabled switch, custom minLevel) and assert the shipped galaxy has locked gates at level 0 that all open at level 5
2026-09-21 18:56:31 -06:00
Brian Fertig dd898bd594 Color route marks by destination kind
- Cargo deliveries set from the ship manifest or surface scout now read brown on the compass and in-world pulse; story-quest and manual picks keep the route's orange
- Add `destination.kind` ('manual' | 'cargo' | 'quest') to save/load so the mark survives a session
- Carve out held "Special Delivery" quest: a cargo pick that matches its home delivery flips to kind 'quest' so the story keeps orange
- Thread the resolved mark color through JumpGate/Planet/Station `setRouteTarget` and DiscoveryCompass entry recoloring
- Fix lava shop clip references in landing.json (ice-shop → lava-shop) and add arid-shop-01.png asset
- Extend dev probes: ship-cargo-compass checks brown/orange per kind, scout-dest asserts cargo kind, ship-shot gains a park shot for the off-screen route arrow
2026-09-19 12:38:56 -06:00
Brian Fertig d61f2d6934 Add combat comms, block jump/landing during fights, and retime pirate am
- Add OAC "enemies detected" / "enemies defeated" visual comms with random voice pools, fired on CombatSystem active-flag flips
- Deny jumping or landing while a fight is live so the wave run can't be escaped or hidden on a surface
- Move the 'Pirate Problems' ambush trigger to the midpoint of the entry-gate → capital-world stretch, persisting lastJumpFrom through saves for a stable midpoint
2026-09-17 17:18:53 -06:00
Brian Fertig 54d2886c91 Remove waypoint kind; allow up to two deep-space stations per system
- Waypoints were comms-only beacons with no landing or trade; a second
  deep-space station is a more useful destination in their place
- The old waypoint chance in systems.json becomes
  deepSpaceStation.second, so a system can roll 0–2 stations
- StationFrames now assigns a distinct sprite variant per station
  (Galaxy.stationFrames is id → [frame, …]) and a two-station system
  always wears two different variants
- Rename the route-gate pulse from "destination's waypoint" to
  "route's next stop" so the term no longer refers to a removed kind
2026-09-14 10:25:19 -06:00
Brian Fertig 141cbdb156 Add route-target pulse halo to gates, planets, and stations
- New shared RoutePulse entity draws a steady ring + two radar ripples
  scaled to the host's keepout radius, with configurable alpha/period
- JumpGate wears the full pulse (route.pulse) when it is the route's next
  stop; Planet and Station wear the subdued variant (route.objectPulse)
  when they are the destination object in the destination system
- GameScene marks exactly one entity per frame via setRouteTarget() and
  drives its update loop; all others are cleared
- Add data/gates.json sections for pulse and objectPulse geometry/alpha
- Rename laval-surface-02.png to lava-surface-02.png and add the
  corresponding video asset
- Extend jumpgate, planet, and station test stubs with Phaser Display.Color
  and recording graphics; add dev/route-pulse.test.mjs unit tests and
  dev/route-pulse-live.{html,mjs} browser integration checks
2026-09-12 16:35:05 -06:00
Brian Fertig e2878da59c Add faction worldgen layer: territories, capitals, bridges, and arid pla
- Assign each jump-tree branch a faction (apex/mindweave/zenith) with seeded
  shuffle; territory = depth 2..maxDepth-1 per branch, ring + tips stay neutral
- Designate four capital worlds (neutral + one per faction) as the outermost
  planet of their system, with fixed frames 18-21 and faction-owned settlements
- Add cross-branch bridge gates in the middle belt so factions can reach each
  other without routing through the trunk; Dijkstra picks the shorter route
- Introduce arid planet class (always habitable, settles as colony) across all
  system types with rebalanced class weights
- Wire Trestle's last brief to auto-set destination to the neutral capital on
  acknowledgment (CommsHub onEnd → GameScene._commEnded)
- Render faction ring layer + capital seat marks on the galaxy plate; style
  bridge lanes distinctly from trunk edges
- Populate settlement owner from system faction (reputation seam now live);
  SystemReport reads faction label/color
- Add dev/factions.test.mjs covering config, branches, capitals, territory,
  arid, bridges, determinism; update existing tests for new invariants
2026-09-10 21:45:33 -06:00
Brian Fertig 54fbf4091c Rebuild in-system layout around tether discovery + the edge margin
- 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
2026-09-10 18:53:30 -06:00
Brian Fertig a8246bb594 Place anchored jump gates on a 3500–4990 px band around their anchor
- 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.
2026-09-10 18:37:22 -06:00
Brian Fertig 71cbea2fab Shorten research labels and fix console layout clipping
- Use fixed short button copy for the gates tech ("Unlock Jumpgates") and mining nodes (drop "Mining" prefix) since the tree node has no room for system names or category words
- Raise detail panel height and widen node/button plates so long descriptions and status labels stop bleeding past plate edges
- Add word-wrap to the unlocks line and trim redundant status prefixes ("RESEARCH CONSOLE STANDBY", "PROJECT COMPLETE")
- Fix ice-surface-01 video reference in landing.json (was pointing at rocky-surface)
- Add OAC speech clips and ice surface video asset; update planets.psd
- Tighten tether research descriptions to match the new short-copy style
2026-09-09 08:28:32 -06:00
Brian Fertig bfd85c8e1f Extend route compass to mark the destination object as final stop
- In the destination system, the orange compass arrow now points at the
  destination OBJECT (not just the next gate), so the "where to fly next"
  marker persists across the last hop into the system.
- Add `_checkDestinationReached` per-frame check: clears the destination and
  fires REACHED only when the ship is within the object's keep-out rim,
  replacing the old jump-time clear for destinations with a specific object.
- Route compass entries (`route:`/`dest:` ids) are now resolvable by
  `autopilotTo`, fixing the ship aiming at the star instead of the gate.
- New `alwaysFull` flag on compass targets keeps route waypoints at full
  readout (arrow + type + name) regardless of distance; add tests.
- Add `route.destTypeLabel` config key and update docs/PROJECT_NOTES.md.
2026-09-07 20:36:11 -06:00
Brian Fertig a5152590db Add SET DESTINATION route plotting with compass guidance
- New `js/galaxy/Route.js` derives the unique path between systems over the spanning-tree jump network (Dijkstra), exposing `planRoute` / `nextSystem`; pure and Node-tested in `dev/route.test.mjs`.
- Persist only the destination (`systemId`, `objectId`) in save data; the route itself is recomputed from the current system, so following it shortens automatically and a detour re-plots.
- Compass marks the route's next gate in orange (shown even while undiscovered) and suppresses that gate's ordinary cyan entry.
- On jump, resolve arrival / on-course / detour before `captureState` and queue REACHED / RE-PLOTTED notices to surface after the destination scene spawns.
- Map console SYSTEM tab now charts a charted star's system; confirming an object sets the destination and closes the map.
- Fix galaxy stars bleeding through the system chart: plate culling respects overall visibility, fog skips when no tethers anchor it, and the boot reveal finalizes to full alpha on tab switch.
- Add `assets/videos/ss-land-03.mp4` and document the route feature in PROJECT_NOTES.
2026-09-07 20:10:15 -06:00
Brian Fertig 963b2b5bc2 Redesign galaxy as sparse 60-system spanning-tree maze without rendered
- Shrink the roster from 200 to 60 systems and drop spiral arms / core bulge for a uniform-in-area sparse disk (data/galaxy.json)
- Turn the jump network into a pure spanning tree (shortcuts off): exactly one route between any two systems, barren systems become single-gate dead-end leaves
- Remove the rendered Star entity; non-home system centers are now empty space with the star kept only as invisible dossier flavor
- Gate anchors restricted to planets (stations no longer anchor) and every non-barren system guaranteed ≥1 planet so a buildable world always exists
- Give barren dead ends 1–2 asteroid clusters drifting inside their gate's level-1 tether as the stop's only payload
- Bump save format to 2 and reject legacy format-1 saves with a clear toast message
- Update tests, docs, and README to reflect the maze layout, leaf dead ends, empty centers, and new barren cluster rules
2026-09-07 14:12:40 -06:00
Brian Fertig d78b7ad505 Add gate comm window and sprite-based jump gate rendering
- Replace direct-click-to-jump with a shared comms panel variant that shows LINK ACTIVE/DORMANT status, REQUEST JUMP (disabled while dormant), and CANCEL
- Render gates from the new 256x256 spritesheet (frame 0 body, frame 1 active swirl) with procedural fallback when the texture is missing
- Active gate swirl spins clockwise and breathes alpha between configurable bounds; dormant gates keep the body at full alpha with the swirl hidden
- Wire CommsPanel to a dynamic primary-button action id so the same panel serves world and gate variants
- Add dev probe page (dev/gate-comms.html/.mjs) and update jumpgate/jump-travel tests for the new sprite path, fallback renderer, and comm-window flow
2026-09-06 20:26:06 -06:00
Brian Fertig 507d00f818 Add full-screen warp clip to gate jumps
- Play a cover-scaled video between systems on jump, with an opaque backdrop so the source doesn't show through
- Double-click skips the remaining clip; single press is swallowed while it plays
- Fall back to the short jumpDelayMs cut when no video is configured or missing
- Guard against stalled/overlong playback with a grace and duration cap before restarting
- Add assets/videos/jump.mp4 and document the new behavior in gates.json and PROJECT_NOTES.md
2026-09-06 18:08:29 -06:00
Brian Fertig 5a67dbb206 Implement gate jump travel between systems
- Add JumpTravel.js with pure arrival geometry (return-gate lookup, spawn point past keepout) and wire it into GameScene.jumpThroughGate to re-stage the run via the save pipeline and scene restart
- Add gate hit-test (gateAt) so active gates trigger the jump on click while dormant ones show a console nudge and fall through to fly-here
- Add jump config block to gates.json (feature switch, arrival gap, delay, toast templates) and update landing.json gasgiant shop clips
- Add dev/jump-travel.test.mjs covering config, geometry, real-galaxy coverage, and determinism; refresh PROJECT_NOTES for the new mechanic
2026-09-06 16:37:48 -06:00
Brian Fertig a3a229a72d Add per-system research category that unlocks jump gates
- Introduce a dynamic "system" research category built at runtime with two techs: `{System} Map` (granted on entry) and `Unlock {System} Jumpgates` (researchable once every NAV point is discovered).
- Wire gate activation through the research effects seam so completing the jumpgate tech activates the system's gates plus linked return gates, anchors level-1 tethers at each activated gate, and saves/restores via a new `activatedGates` set.
- Extend ResearchModel with optional tree hooks (`available`, `lockNote`) so dynamic categories can gate research on live world state without adding static requires.
- Add map and gate procedural icons, update tests for the new category contract and icon roster, and document the system category in project notes.
2026-09-06 15:56:38 -06:00
Brian Fertig 0b92cb7b98 Galaxy refactor: 200 systems, object-composition, dormant gates, frame diversity
- Galaxy shrunk to 200 systems (data/galaxy.json) — always fully known,
  generation ~15 ms; roster/content two-level design unchanged.
- Object composition replaces planetCount (data/systems.json → objectCount):
  10% barren (jump-gate-only), else 2/3/4/5 objects (planets + free-space
  stations) at 15/30/30/15. One unified roll (rollSystemComposition) shared
  by the content generator and the frame pass.
- Barren systems: no planets, no stations, no asteroid clusters; their
  single gate sits on the star→destination ray at barrenDistance (8192 px).
  Strong connectivity keeps them reachable.
- Jump gates are DORMANT by default: every gate record carries
  active:false, the entity renders dim with a still field. Activation is
  the seam for the tether mechanic (an activated gate anchors a level-1
  tether). data/gates.json gains barrenDistance.
- Frame diversity (js/galaxy/PlanetFrames.js): one galaxy-wide pass spreads
  (class, frame) across the galaxy — fixed spatial order, least-used face
  among already-assigned nearest stars, seeded tie-breaks. Stamps
  planet.frame + content.homeFrame, read by GameScene.
- Tests: dev/frames.test.mjs added; jumps/galaxy/discovery/jumpgate/asteroids
  suites updated to the new rules (composition buckets, barren gates,
  active flags, frame determinism/spread, 5-object max, index clamps).
- Docs (README, PROJECT_NOTES) and stale 40k references updated.
2026-09-06 13:06:29 -06:00
Brian Fertig a1aa25b5ba Add jump gate network and in-system gate placement
- Introduce data/gates.json + js/galaxy/JumpNetwork.js: a strongly-connected, degree-limited spanning tree over the nearest-star graph (plus local shortcuts) so every system holds 1–3 gates, all jumps are local, and no system is closed or trapped
- Place each gate on the tether circle of an anchor (planet / space station / home world), facing its destination star; enforce radius band, clearance from anchors, and gap between gates in SystemGenerator.layoutGates
- Add the JumpGate entity (procedural twin-pylon portal) with the same solid contract as Planet/Station, discoverable in cyan, listed in the HUD dossier; wire into GameScene solids + discovery
- Guarantee every system holds at least one gate anchor (barren systems get a deep-space station); cap the home system at 3 objects so it fits the tighter band
- Rework solar-system layout to a full pairwise band [minSpacing, maxSpacing] with rotation tuned toward gate bearings; update tests and docs accordingly
2026-09-06 11:56:26 -06:00