Files
major_tom/TODO.md
Thomas d0853fb38d Add pause menu, laser turret, charger/spawner enemies, and Mars campaign
Implement four feature phases:

Phase 1 - Pause menu: extract bitmap font into shared engine/font
module, add MODE_PAUSED with Resume/Restart/Quit overlay.

Phase 2 - Laser turret hazard: ENT_LASER_TURRET with charge/fire/
cooldown state machine, per-pixel beam raycast, two variants (fixed
and tracking). Registered in entity registry with editor icons.

Phase 3 - Charger and Spawner enemies: charger ground patrol with
detect/telegraph/charge/stun cycle (2s charge timeout), spawner that
periodically creates grunts up to a global cap of 3.

Phase 4 - Mars campaign: two handcrafted levels (mars01 surface,
mars02 base), mars_tileset.png, PARALLAX_STYLE_MARS with salmon sky
and red mesas, THEME_MARS_SURFACE/THEME_MARS_BASE for the procedural
generator with per-theme gravity/tileset/parallax. Moon campaign now
chains moon03 -> mars01 -> mars02 -> victory.

Also fix review findings: deterministic seed on generated level
restart, NULL checks on calloc in spawn functions, charge timeout
to prevent infinite charge on flat terrain, and stop suppressing
stderr in Makefile web-serve target so real errors are visible.
2026-03-02 19:34:12 +00:00

6.1 KiB
Raw Blame History

TODO

Distance-based sound effects

Implemented: audio_set_listener(), audio_play_sound_at() with linear attenuation and stereo panning. Used by enemy death, asteroid impact, and powerup pickup.

Spacecraft art and entity

Implemented: spacecraft PNG spritesheet (5 frames, 80x48 each), full entity with state machine (FLYING_IN → LANDING → LANDED → TAKEOFF → FLYING_OUT → DONE), engine/synth sounds, thruster particles, level intro sequence with deferred player spawn.

Large map support (5000x5000)

Audited and fixed all engine bottlenecks for maps up to 8192x8192:

  • MAX_MAP_SIZE constant (8192) replaces hard-coded 4096 caps in tilemap loader and editor resize. Tile layers allocate fine at 5000x5000 (~143 MB).
  • Dynamic line reader in tilemap_load() replaces fixed 16 KB fgets buffer; handles arbitrarily long tile rows without truncation.
  • MAX_ENTITY_SPAWNS raised from 128 to 512; MAX_EXIT_ZONES from 8 to 16.
  • Entity distance culling: entity_update_all() skips entities beyond 2× screen width from the camera; entity_render_all() skips entities outside the viewport + 64 px margin. Player, spacecraft, and drone use ENTITY_ALWAYS_UPDATE flag to opt out of culling.
  • Editor flood fill replaced with scanline algorithm — O(height) stack usage instead of O(area), safe for very large maps.
  • Verified: tilemap rendering already viewport-culled, physics queries are O(1) local tile lookups, float precision fine up to ~1M pixels (62 K tiles).

Spacecraft at level exit

Implemented: spacecraft_spawn_exit() with is_exit_ship flag. Proximity trigger in level.c spawns exit ship when player is within ~2 screen widths of an exit zone. Ship flies in, lands near exit. Player overlaps landed ship → player deactivated, ship takes off, camera holds still, level transition fires after ship departs (SC_DONE).

Asteroid refinement

Implemented: base speed 120→200, accel 200→350, respawn 3→6s, stagger 0-3→0-8s, random horizontal drift (±60 px/s), moon level reduced from 24 to 8 asteroids.

Moon campaign: 3 levels with spacecraft transitions

Implemented: 3 moon levels connected by spacecraft takeoff/landing sequences.

  • moon01.lvl (1000 tiles) — Exit triggers spacecraft, transitions to moon02.
  • moon02.lvl (200 tiles) — Crater fields, tighter platforming. Spacecraft intro, 7 asteroids, unarmed. Exit to moon03.
  • moon03.lvl (150 tiles) — Dark side, hardest moon terrain. Spacecraft intro, 5 asteroids, unarmed until gun powerup near exit. Exit to level01.
  • level01.lvl — Space station with spacecraft landing intro (arriving from moon).

Level generator: height zones (verticality)

Implemented: tall level support (46 tiles, two screens) with height zones.

  • Camera vertical look-ahead (30px lead when player moves vertically > 50 px/s)
  • All segment generators (gen_flat, gen_pit, gen_platforms, gen_corridor, gen_arena, gen_shaft, gen_transition) accept ground_row parameter — platforms, enemies, and hazards are placed relative to the zone's ground level
  • SEG_CLIMB connector segment type: vertical shaft with alternating platforms, wall openings, optional moving platform and enemies, bridges height zones
  • levelgen_generate() assigns zones per theme: Surface → LOW (row 43), Base → HIGH (row 17), Station → alternates. SEG_CLIMB auto-inserted at zone boundaries. Single-theme levels stay at standard 23-tile height.
  • Station generator unchanged (23 tiles, corridor envelope constrains)
  • Tall test level: assets/levels/tall_test.lvl (40x46)

Jetpack boost blue flame effects

Implemented: particle_emit_jetpack_boost_burst() (electric blue core + blue-white flare, 18 particles mixed into regular burst) and particle_emit_jetpack_boost_trail() (blue sparks + pale blue wisps, 3 particles/frame). Both activate only when jetpack_boost_timer > 0. Burst fires on dash start, trail emits each frame during dash.

Pause menu

Implemented: extracted bitmap font from editor.c into shared engine/font module (font.h/font.c). Added MODE_PAUSED game state to main.c with semi-transparent overlay, menu items (Resume / Restart / Quit), up/down navigation, confirm with jump/enter. Restart reloads file-based levels or regenerates procedural levels.

Laser turret hazard

Implemented: ENT_LASER_TURRET entity with state machine (IDLE → CHARGING → FIRING → COOLDOWN). Beam uses per-pixel raycast via tilemap_is_solid(). Player damage via point-to-line distance check. Rendering with SDL_RenderDrawLine and perpendicular offset for beam thickness. Two variants: laser_turret (fixed, aims left) and laser_turret_track (rotates toward player at 1.5 rad/s during idle/charge, locks on fire). Both registered in entity registry with editor icons.

New enemies: Charger and Spawner

Implemented in enemy.h/enemy.c:

  • Charger — Ground patrol → ALERT (0.5 s telegraph) → CHARGE (150 px/s rush) → STUNNED (0.8 s on wall hit, reverses). 2 HP. Detects player in horizontal line-of-sight within 200 px.
  • Spawner — Stationary. Spawns grunts every 4.5 s (max 3 alive via count_alive_grunts()). Pulses before spawn. 3 HP, destructible. Purple color scheme. Both registered in entity registry with editor icons.

Mars campaign

Implemented: two handcrafted levels plus procedural generator support.

  • mars01.lvl (250×23, Mars Surface): low gravity (370), wind, wide-open red terrain, charger + grunt enemies, spacecraft intro. New mars_tileset.png and PARALLAX_STYLE_MARS (salmon sky, red mesas, dust).
  • mars02.lvl (40×46, Mars Base): normal gravity (700), tall vertical corridors with narrow passages, turrets, laser turrets (fixed + tracking), spawners, chargers, grunts. Victory exit at bottom.
  • Generator: THEME_MARS_SURFACE / THEME_MARS_BASE with per-theme gravity, bg color, parallax style, tileset path, segment probabilities, and height zone assignment. Mars themes added to procedural progression (6 options).
  • Moon campaign now chains to Mars: moon03 → mars01 → mars02 → victory.