Commit graph

80 commits

Author SHA1 Message Date
8e6865dfa4 chore: fix mcp 2026-05-13 11:55:53 +02:00
53710dbe09 chore: add CLAUDE.md 2026-05-13 11:32:57 +02:00
725d770fa0 fix(flake): guard linux-only deps behind stdenv.isLinux
wayland, alsa-lib, and udev are Linux-only — including them
unconditionally breaks evaluation on darwin.
2026-05-13 11:31:56 +02:00
fb132aea2a Merge branch 'opencode/happy-rocket'
Brings in scripted flight paths for special stage enemies (GAL-40) on
top of the high-score persistence work (GAL-56) already on main.

Conflict resolution:
- src/game_state.rs, src/systems.rs: kept HEAD's imports — they are a
  superset that includes HighScore/persistence; the incoming branch's
  changes were just import-formatting that HEAD had already adopted.
- src/resources.rs: kept both — HEAD's HighScore resource and the
  incoming flight_patterns test module are independent additions.
2026-05-09 14:07:28 +02:00
6eef94b783 Merge branch 'opencode/clever-wolf' 2026-05-09 14:02:18 +02:00
4189b8c908 chore(todo): update GAL-56 status to Done, check off all AC 2026-05-09 11:05:28 +02:00
933d23cc35 fix(game-state): reset score, lives, stage, and formation on restart; despawn explosions on cleanup
Reset Score, PlayerLives, CurrentStage, and FormationState resources
when restarting from GameOver. Extend cleanup_game_entities to also
despawn Explosion entities.
2026-05-09 11:02:09 +02:00
73c76e75be chore(todo): add GAL-56 — Score resource does not reset on game restart 2026-05-09 09:55:05 +02:00
b0e5e4c9b8 chore: enable bevy debug feature for tests
Adds bevy as a dev-dependency with the `debug` feature so that
`cargo test` builds with system-name diagnostics enabled, while
release/run builds remain unaffected.
2026-05-08 09:51:22 +02:00
0c23dfde84 chore(todo): update GAL-53 status to Done and mark acceptance criteria complete 2026-05-07 23:33:34 +02:00
ff3416b664 chore: apply cargo fmt formatting 2026-05-07 23:31:30 +02:00
52b5c9d7e6 feat(ui): wire high score into game lifecycle and display
Add check_high_score system on GameEnter, insert HighScore resource
loaded from disk at startup, display best score on Start Menu and
Game Over screens.
2026-05-07 23:31:15 +02:00
060a9a2a14 feat(persistence): add high score saving/loading
Add HighScore resource, persistence module with save/load, and
integration tests. Dependencies: serde, serde_json, dirs.
2026-05-07 23:30:59 +02:00
adbd04e87e chore(todo): update GAL-40 status to Done 2026-05-07 19:56:40 +02:00
a0863b290c feat(gameplay): add scripted flight paths for special stage enemies
Add Lissajous and cubic Bezier path types for enemies on special stages
(every 3rd level). Path-following enemies spawn with ScriptedPath marker
and FollowingPath state, move along parametric curves, and despawn when
their path ends off-screen.

Key changes:
- New flight_paths module with pure path evaluation (Lissajous + Bezier)
- ScriptedPath marker component and FollowingPath EnemyState variant
- flight_patterns field on StageConfigurations for composable path data
- Special stage spawn branch in spawn_enemies() with stagger delays
- Path-following movement in move_enemies() with delay gating and despawn
- Formation complete early return for special stages
- Without<ScriptedPath> filter on attacking_query to prevent double-processing
- 13 new unit tests for path evaluation and data contracts

Refs: GAL-40
2026-05-07 19:54:18 +02:00
459e8a2353 chore: .gitignore 2026-05-07 14:57:22 +02:00
b1fe22fcaf docs: add line for testing 2026-05-07 14:53:17 +02:00
483107196f docs: remove bash -c 2026-05-07 14:45:24 +02:00
365e3a7cc4 chore(todo): add acceptance criteria and test hints to open issues
Flesh out the 14 still-open issues (GAL-34/35/36/37, 40/41, 43, 46/47/48/49,
52/53/55) with explicit acceptance criteria and concrete integration test
hints that reference existing types and headless tooling, so future work
on these tickets has a clear definition of done.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 09:53:09 +02:00
53938f22b5 chore: remove stale GEMINI.md 2026-05-07 09:29:40 +02:00
db9f7714b1 chore(todo): split TODO.md into per-issue files under TODO/
Convert the flat TODO.md into a TODO/ folder where each GAL-N issue is
its own Linear-style markdown document with YAML frontmatter (id, title,
status, parent, labels), and add a README index grouped by section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 09:29:17 +02:00
38c68e6d58 chore(todo): update GAL-39 status and progress 2026-05-06 23:33:25 +02:00
9e6d53867a feat(game): add special stage type every 3rd level
Every 3rd stage (3, 6, 9, ...) is now a special stage with no enemy
dive attacks and no enemy shooting. Enemies still spawn in the default
grid formation (32 enemies) but remain in formation without attacking.

Changes:
- Add SPECIAL_STAGE_INTERVAL constant and is_special_stage() function
- Add special_stage config to StageConfigurations with empty attack_patterns
- Modify for_stage() to route special stages to special config
- Guard enemy_shoot system to skip shooting during special stages
- Show '*' suffix in window title for special stages

Refs: GAL-39
2026-05-06 23:31:12 +02:00
eaff717054 chore(todo): update GAL-27 status and progress 2026-05-06 22:02:13 +02:00
98b74a7ae2 game: award 300 points for Boss kills (3x Grunt)
Boss enemies now award 300 points instead of the same 100 as
Grunts. The scoring match in check_bullet_collisions already
routed by EnemyType; only the BOSS_POINTS constant was wrong.

Refs: GAL-27
2026-05-06 21:59:35 +02:00
ad2037a7a5 refactor: idiomatic cleanup across the codebase
Net -311 lines (1075 → 764). Build clean, clippy clean, 8 tests pass,
headless render verified.

Highlights:
- player.rs: bug fix in handle_captured_player — was cloning captured.timer
  and ticking the clone, never the real timer. Consolidated kill_player as
  pub(crate) helper (was duplicated across 3 sites). Switched from ParamSet
  to two disjoint Queries.
- enemy.rs: extracted step_attacker(), spawn_beam_visual(), end_beam(),
  pick_pattern() helpers — move_enemies is no longer 3-deep nested matches,
  beam cleanup no longer duplicated. Fixed SwoopDive overshoot check (was
  using already-applied movement). Mid-file `use` hoisted to top.
- resources.rs: added StageConfigurations::for_stage() helper (was repeated
  4×); FormationState/Score/CurrentStage now Default; extracted
  circle_formation() helper.
- stage.rs: replaced raw world: &mut World access with ordinary ResMut
  system params (no need — resource types are disjoint).
- game_state.rs: cleanup queries collapsed via Or<…> filters; dropped dead
  RestartMessage cleanup from cleanup_game_entities; button colors
  extracted as constants.
- bullet.rs: reuses kill_player; introduced GRUNT_POINTS/BOSS_POINTS with
  TODO referencing GAL-27.
- lib.rs: init_resource::<T>() for Default-implementing resources.
- Removed unused TRACTOR_BEAM_COLOR constant.
- Replaced per-frame println! debug spam with targeted info!/warn!.
- Stripped noise comments that restated what the code does.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:36:26 +02:00
b2b564f690 chore(deps): upgrade Bevy 0.13 → 0.18
Three major versions of breaking changes:
- Bundles → Required Components (SpriteBundle, NodeBundle, ButtonBundle,
  TextBundle, Camera2dBundle removed; spawn tuples of components instead)
- Style merged into Node; TextStyle split into TextFont + TextColor
- Color API: rgb/rgba → srgb/srgba; Color::Rgba pattern matching replaced
  with .alpha()/.set_alpha(); .r()/.g()/.b() → .to_srgba().red/green/blue
- Time: delta_seconds() → delta_secs(); elapsed_seconds() → elapsed_secs()
- Query: get_single()/get_single_mut() → single()/single_mut() (now Result)
- Timer::finished() → Timer::is_finished()
- despawn_recursive() removed (despawn() is now recursive); despawn_descendants()
  removed — replaced with Children query iteration
- BorderColor(c) → BorderColor::all(c)
- WindowResolution: From<(f32,f32)> removed → cast to (u32,u32)
- flake.nix: added wayland to runtime libs (default-on in 0.18)

Tests pass (8/8), clippy clean, headless render verified showing start
menu, button, starfield, and player ship.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:26:48 +02:00
7a4305677b chore(todo): uncheck GAL-25/GAL-27 — Boss points not differentiated
Audit revealed Boss and Grunt both award 100 points (bullet.rs:48-51),
contradicting GAL-27's "different points" requirement. Added breakdown
sub-items to track what's done (colors, behaviors) vs. what's missing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:12:27 +02:00
e5cc1b310a add .mcp.json 2026-05-06 21:09:21 +02:00
ef3b7389e7 remove .opencode/workflow-summary.md 2026-05-06 21:07:41 +02:00
c6dcf9d728 feat: add take-screenshots flake app for headless capture
Expose a `nix run .#take-screenshots` app that runs a binary inside an
Xvfb display with lavapipe software Vulkan and captures PNG snapshots
via ImageMagick. Useful for smoke-testing the Bevy renderer in
environments without a GPU (CI, sandboxed shells, agents).

Usage:
  nix run .#take-screenshots -- EXE NUM DELAY_START PAUSE_INBETWEEN [OUTPUT_DIR]

The script picks the first free :N >= 99, locates the lavapipe ICD via
pkgs.mesa with a fallback to /run/opengl-driver (NixOS), reuses the
dev shell's runtimeLibs in LD_LIBRARY_PATH, and traps EXIT for cleanup.

README updated with usage and a worked example.
2026-05-06 21:01:14 +02:00
68e3051f77 refactor: split game logic into library + binary entry point
Move the App setup and module declarations from src/main.rs into a new
src/lib.rs that exposes a single pub fn run(). src/main.rs becomes a
three-line entry point that calls bglga::run(). This is the standard
Bevy-book pattern and lets the game logic be consumed as a library
(e.g. for integration tests, headless tooling, or alternate entry
points) without duplicating the App wiring.

Also gate update_tractor_beam_visual with
run_if(any_with_component::<TractorBeam>) so the system only runs while
a boss has an active tractor beam, instead of every Update tick.
2026-05-06 20:54:09 +02:00
506a775b0c fix: disjoint Transform queries in update_tractor_beam_visual
Add Without<TractorBeamSprite> filter to boss_query so Bevy's parallel
access checker can prove the &Transform read on bosses and the
&mut Transform write on beam-sprite children target disjoint entity
sets. Without it, the system panicked on first run with a B0001
"conflicts with a previous system parameter" error.
2026-05-06 20:54:02 +02:00
35300ec62b Merge branch 'gal-44-add-explosion-effects' 2026-05-06 20:33:23 +02:00
8e06a91dde chore(todo): update GAL-33 status and progress 2026-05-06 19:37:06 +02:00
52b0919d3f feat: improve tractor beam visual with 2-layer glow and pulse animation
Replace the single static rectangle with a 2-layer beam (outer glow +
inner core) and sinusoidal opacity pulse. Add per-frame beam height
tracking to follow boss position. Include 8 unit tests for pure math
functions (beam height calculation, pulse alpha).

Refs: GAL-33
2026-05-06 19:35:16 +02:00
405c326e9c chore(workflow): summary for GAL-44 2026-05-06 16:46:44 +02:00
08838c3428 chore(todo): update GAL-44 status and progress 2026-05-06 16:45:26 +02:00
2ff561efb1 feat: add explosion animations on entity destruction
Spawn expanding/fading orange explosion effects when enemies or
the player are destroyed. Explosions scale from 15x15 to 50x50
over 0.4s while fading from full opacity to transparent, then
auto-despawn.

Integration points:
- Enemy killed by player bullet (bullet.rs)
- Player hit by enemy bullet (bullet.rs)
- Player collides with enemy (player.rs) - both explode
- Captured player released (player.rs)

Refs: GAL-44
2026-05-06 16:43:16 +02:00
db061820b9 Merge branch 'todo-fix' 2026-05-06 15:12:28 +02:00
a2c85b153a chore: re-apply Linear-style issue IDs to TODO.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 15:12:16 +02:00
9d80626cc6 feat: add scrolling starfield background
Add 150 stars with randomized positions, sizes, speeds, and brightness.
Stars scroll downward with parallax depth effect and wrap around at
screen edges. Also fixes Bevy 0.13 API issues in game_state.rs
(KeyCode::R → KeyR, Input → ButtonInput).
2026-05-06 15:05:32 +02:00
c9188f58f6 chore: add wav files to .gitignore 2026-05-04 22:15:51 +02:00
6dd8559912 chore: add opencode config, replace AGENT.md with AGENTS.md 2026-05-04 22:15:32 +02:00
b04bd3e74b refactor: replace nixify with flake-utils and rust-overlay in flake.nix 2026-05-04 22:15:27 +02:00
3c226b3f78 feat: add restart from game over with R key 2026-05-04 22:15:16 +02:00
e484c09f14 chore: remove unused RestartRestarted component 2026-05-04 22:15:12 +02:00
704a4476f0 fix: remove orphaned duplicate code in cleanup_game_entities 2026-05-04 22:14:58 +02:00
28e4e53da9 feat: add start menu with interactive button
- Add StartMenu as the default game state
- Create StartMenuUI and StartButton components
- Implement menu UI with BGLGA title and Start Game button
- Add button interaction system with hover effects
- Set up proper state transitions from menu to game
- Update TODO.md to mark task as completed

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-27 09:31:03 +02:00
aee3c9c91b chore: update TODO.md
Signed-off-by: Harald Hoyer <harald@hoyer.xyz>
2025-06-27 09:22:36 +02:00