- 8 new enemy types (frames 50–57) split 4/4: combo seekers fire flank-angle homing missiles with capped turn-rate; elementals throw darts that bloom into growing, damage-ticking electrified zones
- Balance follows the faction rule (2× damage, 3.5× armor vs pirate raider), documented in combat.json comments
- New `flank_barrage` and `shock_dart` abilities in EnemyAbilities.js with shared `stepShock` frame step wired into CombatSystem.update
- Generalized `_combatBootMode` to accept any id from `factionIds()` so new factions need no code change
- Painted frames 50–57 in ships-enemy.png/.psd; added capital-mindweave-surface-01 reference art
- Tests: dev/zenith.test.mjs (Node), dev/zenith-arena-browser.mjs (Playwright), updated combat.test.mjs roster and sheet-art checks, extended cdp-faction-arena.mjs with zenith tab
- Register 8 Apex (frames 30-37) and 8 Mindweave (frames 40-47) in
data/combat.json enemyTypes at 2x damage / 3.5x armor vs the pirate,
each with a distinct weapon pattern and ability kit
- New shared skill layer (js/combat/EnemyAbilities.js): cloaked ambush,
flank strafe, blink reposition, illusion decoys, telekinetic waves;
wired into CombatSystem update/collide with cloak gating on fire,
targeting, and player skills
- Add sweep/spiral/shell weapon patterns in js/combat/Weapons.js
- New ?combat=apex / ?combat=mindweave duel arena with an in-game
DuelPicker (keys 1-8 / click, 0 = whole pack); plain ?combat demo
unchanged
- Paint the 16 missing spritesheet frames (ships-enemy.png) so the
fighters are visible; add a PNG alpha regression test guarding against
blank cells
- Add dev/cdp-faction-arena.mjs CDP smoke check and extend
dev/combat.test.mjs with faction roster, balance, ability, duel, and
sheet-pixel checks
- New `data/skills.json` (registered in manifest) owns every number/string for the
per-class skill trees, type taxonomy, seat table, bar look, and window copy;
code only reads behavior off it so adding a third skill is a data edit.
- Pure skill model + ledger (`js/skills/SkillModel.js`, `SkillState.js`): rank
points from the class bank, spend-through-unlock edges, seat bindings, save
round-trip via `record.playerSkills` (old saves load as an empty ledger).
- Combat runtime in `CombatSystem.js`: cast pipeline with per-skill recharge
clocks, energy spend/regen (now on by default), Ramming Charge dash + arrival
blast (4x..12x weapon damage by rank), Reinforced Plating hull pool re-rolled
from base so it never compounds; charge passes through the pack and settles once.
- UI: full-screen Skill Tree console (`js/ui/SkillWindow.js`) opened from the ship
console's SKILL TREE door (lit when the class owns a tree), combat bar seats draw
icon/rank/cooldown/affordability states with click-to-assign and right-click clear,
keys 1-8 cast or place.
- Evidence: new Node + Playwright suites (`skills.test.mjs`, `skills-combat.test.mjs`,
`skills-bar-browser.test.mjs`, `skills-window-browser.test.mjs`,
`skills-devdoor-browser.test.mjs`) plus screenshots in `dev/shots/`; README and
PROJECT_NOTES document the layer and dev doors (`?skill`, `?skilltree`).
- Introduce data/classes.json as the single source for roster, copy, accents, icon frames, perk numbers, and console chrome
- Add ClassModel (pure reads), ClassState (idempotent run ledger + save round-trip), and Aiming (intercept solve + barrel geometry) so perks are testable without Phaser
- Wire CombatSystem to the class ledger: Vanguard dual-cannon volley, Wraith predictive aim with a max-lead fallback to raw aim; cooldown unchanged
- Add full-screen ClassWindow console over the frozen GameScene (looping muted feed, Trestle briefing, themed tabs, PICK confirm), opened once at level 5 when combat is quiet or via the ship console door / ?level5 dev param
- Persist record.playerClass in saves and clear it on New Game; ship console now shows a class plate with crest + banked skill points instead of the choose-class door
- New "Escort" contract type on neutral job boards (minLevel 3): the player
links a persistent transport + 1-2 escort fighters at a local waypoint,
flies them through a seeded 1-2 hop gate route to a planet/station, and
delivers with the sky clear.
- TransportShip extends NeutralShip with a lapsed break-off window and a
`persistent` flag so CombatSystem's active/neutralOnly gates skip it; the
convoy never holds the jump gate or landing door open.
- Dedicated escort EncounterDirector (9-18s rolls, 85-100% chance) fires
mixed-fighter waves ~5x more frequently than normal encounters; one wave at
a time via the patrol contact's law.
- Transport loss fails the contract; landing on a planet resets it with a
fresh rendezvous in the current system and full-armor transport, same
destination.
- 20 unique escort dossier descriptions, reward band raised to 120-175 CR.
- Three new test suites: escort.test.mjs (model), escort-flow.test.mjs
(scene flow), escort-browser.test.mjs (real browser boot + board render).
- New EncounterDirector (js/combat/Encounters.js): pure, data-driven clock that rolls pirate / neutral / mixed encounters in neutral non-home systems on a ~45–90s interval at 50–60% chance, one at a time with a 30–60s cooldown, never during a live wave run or on a downed player.
- Neutral ally ships (js/combat/NeutralShip.js) on spritesheet frames 20–27: escort the player for a per-ship 10–15s window, engage the nearest pirate in mixed fights, then break off and fly off-screen; player-safe by construction (never targeted or damaged by ally bolts/seekers).
- Pirate targeting generalized so hostiles can draw aggro onto escorts when the player is out of range; escort and pirate bolts/missiles collide with each other but not the player.
- Group size scales with combat level (1–2 low → 4–5 high, bands in data/combat.json); encounter hostiles are one-shots so the fight ends when the sky clears.
- New 'volley' weapon pattern (wide staggered-speed fan) and owner-tagged bolts/missiles for ally vs enemy routing in Weapons.js.
- Neutral roster config + encounters section added to data/combat.json; EnemyTypes gains neutralTypeConfig/Ids/SheetList.
- Tests: dev/encounters.test.mjs (cadence, gate, weights, size bands), dev/neutral.test.mjs (roster, escort AI, targeting, no friendly fire), plus combat/xp test updates; CDP probes and encounter-hud-check for in-browser HUD verification.
- Enable the `bounty` category in data/sidequests.json with level-2 gate,
Neutral-only contexts, encounter chain odds, and 20 written leader dossiers
- Add pure bounty model to SideQuests.js: plan derivation, wave scripts, XP,
sequential waypoint rule, and completion only via the mark's kill
- Extend combat seam (Waves/CombatSystem/EnemyShip) for a named elite unit
deployed with the opening group at scaled hull/damage, plus haltWaves() so
killing the mark stops deployments while survivors stay hostile
- Wire GameScene/SurfaceScene/JobBoardWindow for locked rows, dossier readout,
sequential check-ins, engagement chain, and single idempotent claim
- Add dev/bounty-hunts.test.mjs (591 checks) and in-browser probe with JSON/PNG
evidence; update patrol/sidequests tests for the new live category
- New hostiles frames 1–7 (bomber → warden) with distinct stats and
monotonic difficulty ramp in data/combat.json
- Shared js/combat/Weapons.js dispatch for lance, spray, burst, rapid,
ring, missile, and combo patterns used by both combat contexts
- New dodgeable heat-seeking Missile (capped turn-rate homing) plus pure
geometry helpers in Combat.js
- Rewire ?combat boot to startWaves('combat_demo'): 7 rolling waves, one
type each, 6 ships per wave, 3 concurrent, replacement per kill
- Add missile_fire SFX voice and extend tests/CDP demo checks for all
patterns and the full wave run
- Void in-flight count-up tween when max changes so a late landing can't redraw against the old cap (250/250 → full after cap grew to 500)
- Add regression test for mid-count-up capacity restore voiding the stale tween
- Archive completed ship-screen goal and add ship.mp4 asset
- Wire the deck's SHIP slot to a full-screen ShipWindow (depth 80) following the Map/Quest window contract: bay-camera video panel with NO SIGNAL fallback, tab row, glitch/sweep dressing, ESC/scrim close, and exclusive open/close against research/map/quests/comms.
- Add data-driven Ship Status plate via pure js/ship/ShipScreenModel.js resolving every stat row from data/shipScreen.json (hull/shields live vs nominal, shield recharge, flight, fire rate/DPS, cargo/mineral holds) plus the combat level journey timeline that swaps to a CHOOSE YOUR CLASS door at level 5.
- Add Cargo Holds tab: bay grid with filled/empty/locked states, mineral aggregate bar, and a selected-bay manifest reusing TradeScout.scoutGood() for ranked exits in the buy/sell style.
- Register data/shipScreen.json in the manifest, preload ship.mp4 with skip-if-missing guard, and add dev test + screenshot harness (dev/ship-window.test.mjs, dev/ship-shot.{html,mjs}).
- Replace dot tracers with elongated glowing bolts (trail band + core streak + head bloom)
and a directional muzzle flare in both the range and main-game contexts.
- Add enemy impact reads: core flash, directional sparks along the travel vector,
cyan arc ripple on shield hits vs orange shards on hull hits, white craft hit-flash,
and a polished damage-number pop.
- Add player shield-sphere strike effect: full-sphere outline + bright arc centered on
the laser's incoming bearing, radial ripple, spark burst, and a shield-collapse cue
when shields break to hull.
- Add subtle world-camera shake on player hits, enemy kills, and shield-break while
keeping the HUD/combat bar perfectly still via the fx-ui camera split.
- Expose new visual knobs (bolt size/trail, muzzle, arc span, shake intensity) in
data/combat.json; fix Fx.update destroying ships on tintFlash expiry.