Top-down shooter: TopDown decoupled move/aim (mouse/stick/move-dir/auto-aim), a name-keyed Weapon registry (fire-rate/spread/pellets/pattern + data-driven pierce/homing), and a self-contained deterministic Projectile pool with faction-filtered Combat hits, pierce, ring/spiral patterns, and homing. One weapon impl serves player + NPC via a want_fire intent. Budgeted wave Spawner. Reuses ludic.gameplay Faction/Combat/Stats. 11-check example, in the suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.3 KiB
bump: minor
type: feat
Builtin top-down Shooter controller (#60) — the source package ludic.shooter, conforming to the six-lever contract and built on the engine Body/Collider + ludic.gameplay Faction/Combat/Stats. TopDown decouples movement from aim (aim_mode: mouse / right-stick / move-direction / nearest-enemy auto-aim, with a turn_rate for tank-style rotation). Weapons are a name-keyed registry (Weapon.def("shotgun", …) — add a gun with zero code) with per-weapon fire-rate, damage, speed, spread, pellet count, pattern (single / spread cone / ring / spiral), plus data-driven pierce (Weapon.set_pierce) and homing (Weapon.set_homing); esys_weapon reads a want_fire intent so the same weapon fires for a player (input) and an NPC (AI). Projectile + esys_projectile is a self-contained deterministic pool: integrate, TTL, faction-filtered hit through Combat.damage, pierce, and homing that curves onto the nearest enemy — every step observable via ProjectileSpawned (mutable/veto) / ProjectileHit / ProjectileExpired. A budgeted Spawner wave director emits SpawnRequested / WaveCleared. Example: examples/games/shooter_demo.ludic (11 self-checks: movement, aim, faction damage, friendly-fire immunity, spread, kill, ring, homing, waves).