Commit Graph

3 Commits

Author SHA1 Message Date
Brian Fertig 8fd94ce48c Combat SFX layer: seven distinct event voices, shared across both contexts
- js/combat/CombatSfx.js (new): ONE event→voice map + playback path for
  both contexts, using ONLY existing data/sfx.json files:
    fire=scan · impact=ui_click · shield=solar_buzz · hull=mining_split
    kill=thunder_01..04 (one at random) · down=deconstruct ·
    respawn=discovery
  plus combatSfxEnemyHit() (shield/hull decision in one place: a hit
  that breaks through to the hull plays both — the shield-pop read),
  loadCombatSfx() for the range's preload (the main game already loads
  all of sfx.json), and a capped dev log on window.__COMBAT_SFX__ so
  the wiring is verifiable headless (no audio manager) in both.
- js/combat/CombatScene.js: fire/enemy-fire/wall-clip/ram/lance/kill/
  down/respawn sites call the shared path; the player-hit voices
  (impact + shield/hull from applyDamage) funnel through damagePlayer.
- js/combat/CombatSystem.js: the same seven call sites, identical
  wiring (no per-context copies).
- dev/combat.test.mjs: sfx block — seven events mapped, voices exist in
  data/sfx.json, pairwise distinct, vol scaling, thunder pick, the
  shield/hull decision, the dev log, the master switch (0 failures).
- dev/combat.sfxcheck.mjs (new): CDP check that drives real events in
  /combat AND index.html?combat and asserts all seven events pass
  through the shared path — PASS in both.
2026-09-16 00:47:45 -06:00
Brian Fertig 5949bac861 Sharpen range flight feel: smoothed turn, ramped throttle, instant brake
- js/combat/Combat.js: new pure handleFeel() step (smoothed turn
  velocity, ramped/decaying throttle, instant brake) with EXACT
  analytic integration of the eased turn — frame-rate independent by
  construction (dev/combat.test.mjs: feel block, 0 failures).
- data/combat.json: combat.player tuning surface — thrust 2000, drag
  1.8 (now actually overrides ship.drag in the range), rotSpeed 6.4,
  rotApproach 20, thrustRamp 18, thrustDecay 30, brake 0.9.
- js/combat/CombatScene.js: updatePlayer runs the shared feel step.
  ALSO FIXES WASD: this Phaser build's addKeys() object form only
  resolves single KeyCodes names, so {up:'W,UP',...} put every name on
  ONE shared Key with keyCode undefined and isDown polling could never
  see a key-press (WASD was dead). Now keys drive off the working
  keydown-/keyup- event API (the main game's pattern) with real Key
  objects registered for capture; window-blur clears held keys.
- dev/combat-flycheck.mjs: CDP flight-feel check — thrust 60% in ~300
  ms, 30° turn in ~150 ms, sustained spin ≥ rotSpeed, stop from full
  in ~300 ms (headless ~24 fps budgets; PASS).
2026-09-16 00:17:35 -06:00
Brian Fertig 15fe08a926 Add combat sandbox: standalone arena to tune combat before it ships
- New `combat.html` + `/combat` dev-server route + `index.html?combat`
  boot a fixed arena where the player ship fights a pack of enemy craft;
  all tuning lives in `data/combat.json` (thrust, hulls, shields, lance,
  rams, respawns).
- Add `js/combat/` modules: CombatScene, EnemyShip (standoff-ring AI +
  lance), Bullet, Fx, StarDrift, and pure rules in Combat.js (armor
  damage, orbit step) exercised by the new `dev/combat.test.mjs`.
- Extract shared `awaitFonts` into `js/utils/Fonts.js` so both the game
  and sandbox boots use one copy.
- Preload the enemy spritesheet in GameScene so the texture is ready when
  combat ships in; add `ships-enemy.png` (+ `.psd`) art.
- Expose `window.__COMBAT__` (reset, spawnEnemy, player, kills) for
  devtools tuning; R resets the range, P freezes it.
2026-09-15 20:54:33 -06:00