148 Commits

Author SHA1 Message Date
Matteo Benedetto e76c6f665a Revert "Redraw wall/bush maze tiles with richer pixel-art detail"
The user asked to go back to the pre-commit assets. The original
BMP_{1..4}_*.png tiles have been restored. The generator script
introduced in that commit is also removed.
2026-06-27 20:21:05 +02:00
Matteo Benedetto 0f14ae3376 Redraw wall/bush maze tiles with richer pixel-art detail
The original BMP_{1..4}_{N,S,E,W,NE,NW,SE,SW,EN,ES,WN,WS}.png tiles were
very noisy low-quality checkerboard patterns. They are now redrawn as
hand-styled pixel-art bush/hedge tiles:

- 5-color per-theme palette (deep shadow, dark, mid, light, highlight)
- irregular wall/passage boundary with natural erosion
- shaded interior (darker in the center = depth)
- scattered leaf clusters and highlights
- kept 32x32 resolution and engine transparent-gray convention

A new generator tool is added at tools/redraw_walls.py. Run it again
with python3 tools/redraw_walls.py to regenerate the tiles if you want
to iterate on the style or palettes.
2026-06-27 20:19:41 +02:00
Matteo Benedetto 5ce084f04d Fix missing state_machine import in controls.py
Resolves NameError when toggling pause (and any other control path
referencing state_machine.GameState). The module was referenced but
never imported after the recent cheat/controls edits.
2026-06-27 20:18:04 +02:00
Matteo Benedetto 4bab8d1a79 Scale gas spread, weapon refill, litter size, and post-mating stop with difficulty
Four gameplay parameters are now driven by the selected difficulty,
following the existing 'hard = harder for the player' philosophy:

  param                       easy   normal   hard
  gas_spread_speed            40     50       90     (higher = slower gas)
  weapon_refill_multiplier    1.3    1.0      0.6    (less ammo on hard)
  max_babies                  2      3        5      (more pups on hard)
  mate_stop_male / female     120/240 100/200 60/120 (shorter stop on hard)

Implementation:
- engine/config.py: new keys on each DIFFICULTY_OPTIONS entry.
- rats.py: _apply_difficulty() loads them onto the game (with __init__
  defaults for safety); normal keeps the previous hardcoded values.
- units/gas.py: Gas.speed reads game.gas_spread_speed (fallback 50).
- engine/unit_manager.py: refill_ammo() scales per-frame refill chances
  by game.weapon_refill_multiplier (fallback 1.0).
- units/rat.py: Male.fuck() uses game.mate_stop_male/mate_stop_female
  and random.randint(1, game.max_babies) (fallbacks to old values).

All reads use getattr with the previous constant as fallback, so older
configs / saved state keep working.
2026-06-27 19:52:27 +02:00
Matteo Benedetto a09b9f0878 Add Ctrl+Return cheat to instantly win the current level
During gameplay, pressing Ctrl+Return triggers an immediate level clear:
the current level is marked as won (level_clear, or run_complete on the
last DAT level) and the state transitions to VICTORY, showing the
normal 'Level Clear!' dialog so the player can then advance with Return.

Implementation:
- engine/sdl2.py: mainloop detects Ctrl+Return via SDLK_RETURN + KMOD_CTRL
  and dispatches a 'cheat_win_level' action (bypassing keybindings).
- engine/controls.py: trigger() now also accepts direct action names that
  are registered in the dispatcher (not key-event names), and a new
  cheat_win_level handler forwards to the game.
- rats.py: MiceMaze.cheat_win_level() performs the win, guarded so it only
  fires while a level is actively being played.

No keybinding files need editing; the cheat is wired through the engine
layer directly.
2026-06-27 19:04:37 +02:00
Matteo Benedetto c09840099e Draw rat normally at tunnel entrances
Rats are now drawn fully (single animation frame) regardless of whether
they are on an open cell, a tunnel entrance, or an internal tunnel
passage. The only case where the rat is not drawn is when its center is
inside a wall (non-empty, non-tunnel cell).

Removed the now-unused _get_tunnel_entrance_direction helper.
2026-06-27 18:56:04 +02:00
Matteo Benedetto 705f3ba260 Remove _draw_partially_hidden_in_tunnel clipping
The clipping logic that sliced the rat sprite when entering/leaving a
single-entrance tunnel produced a jarring half-rat visual. Removed it
entirely: a rat on a single-entrance tunnel cell is now simply not
drawn (it disappears into the tunnel) instead of being partially
clipped. Internal tunnel passages are unchanged and still render the
rat normally.
2026-06-27 18:54:46 +02:00
Matteo Benedetto 1627f58103 Fix rat sprite strip artifact inside internal tunnel cells
After merging new-newnassets, the rat sprite assets are now horizontal
4-frame sprite sheets (e.g. BMP_MALE_UP.png is 80x40 instead of 20x40).
The drawing path for rats inside internal tunnel passages still called
draw_image() without source_rect, so the engine rendered all 4 frames
side by side as a single wide strip (the visual artifact shown in
/tmp/pi-clipboard-...png).

This brings the tunnel-internal rendering in line with the non-tunnel
path, which already used source_rect = (frame * w, 0, w, h).
2026-06-27 18:42:46 +02:00
Matteo Benedetto f348d7e0d9 Merge branch 'merge-newassets-clean' into master
Integrates new LPC-style rat assets and animations from origin/new-newnassets.

Summary:
- 32 new LPC-style sprites (assets/Rat_LPC_Style/)
- 4 animation sprite sheets (assets/Rat_Animated/) for animated rats
- 64 updated Rat sprites in assets/Rat/ with backup originals
- engine/sdl2.py: added 'scale=True' param to load_image()
- engine/graphics.py: rat textures loaded with scale=False
- units/rat.py: animation frame computed from partial_move * 4
- 22 final-version generator scripts in tools/lpc_extract/
- 3 cherry-picked commits from origin/new-newnassets

Excluded from upstream (working artifacts, not appropriate for prod repo):
- ~25 PNG in repo root (male_rats*.png, spritesheet*.png, etc.)
- ~416 tile extracts in tools/lpc_extract/grid/
- scattered debug PNGs (bushes, preview, montages)
- early-iteration scripts (animate_rat v1-v4, restyle v2-v10, etc.)
2026-06-27 17:56:16 +02:00
Matteo Benedetto e26464d843 Merge origin/new-newnassets: new LPC rat assets and animations
Cherry-picked from new-newnassets (3 commits):
- bdf5a8d Add new start animation asset for game launch
- 5f2d09f Fix rat animations and restore map tiles
- 2e2c5bb feat: add LPC-style rat assets, sprite generation scripts, and grid extraction tools

Conflicts resolved:
- engine/sdl2.py: kept 'if scale:' wrapper (compatible, default scale=True)
- units/rat.py: kept animation frame computation (partial_move * 4)
- 12 PNG files (BMP_BABY/MALE/FEMALE_*): kept new-newnassets versions

Cleanup applied: removed ~480 working artifacts not appropriate for the
production repo:
- 25 PNG in repo root (male_rats*.png, spritesheet*.png)
- 416 tile extracts in tools/lpc_extract/grid/
- scattered debug PNGs (bushes, preview, montages, etc.)
- early iteration scripts (animate_rat v1-v4, restyle v2-v10, etc.)

Kept: 32 new LPC-style sprites in assets/Rat_LPC_Style/, 4 animation
sprite sheets in assets/Rat_Animated/, 64 updated Rat sprites, 22
final-version generator scripts, plus all .py/.md updates.
2026-06-27 17:53:45 +02:00
Matteo Benedetto c1662ecf29 Add regression test for gray-strip artifact in asset rendering
Tests/test_gray_strip_artifact.py renders lose.png on a white panel
both with and without the near-white normalization, saves the
results to /tmp/test_loss_before.png and /tmp/test_loss_after.png,
and counts near-white (RGB 240-254, alpha>200) pixels which are the
direct cause of the gray seam.

With the fix the near-white pixel count drops from 3714 to 133
(reduction of 96%), confirming the normalization removes the
artifact.
2026-06-17 11:46:01 +02:00
Matteo Benedetto 2ad6a082b3 Normalize near-white pixels to pure white in all loaded assets
Assets like lose.png contain thousands of (254,254,254) pixels on a
background that is also white. When drawn on a white panel these
near-white pixels are slightly darker, producing a visible gray seam.

Apply a global normalization in load_image(): any opaque pixel with
R=G=B >= 250 is clamped to (255,255,255). Applied to every asset, not
only those with transparent_color, so the background is always pure
white regardless of off-by-one in the source PNG.
2026-06-17 11:13:40 +02:00
Matteo Benedetto 319801d6e5 Fix rat reproduction collision check
Replace the brittle 'self.position == other.position_before' check
with a symmetric cell-intersection test: two rats are considered
colliding if any of their current/previous cells overlap. This handles
both 'both rats in same cell' and 'one rat enters the cell the other
just left'.

Also remove the erroneous hasattr(other_unit, 'fuck') guard that
prevented Male.fuck() from being called on Female (Female has no fuck
method, but only Male should initiate reproduction).

Add tests/test_rat_reproduction.py with 8 scenarios covering overlapping
rats, baby rats, already-pregnant females, far-apart rats, female
self-initiation, sound playback, and procreate interval spawning.
2026-06-17 10:29:26 +02:00
Matteo Benedetto 2eccf504f5 Add semi-transparent tunnel cover overlay for internal passages
- Add sdl2.create_overlay_texture() and draw_overlay_texture(alpha) for
  transparent full-map overlays built from sub-tile surface blits.
- Add Graphics.regenerate_tunnel_cover() which builds an overlay of
  4 random grass sub-tiles (20x20) for every internal tunnel cell,
  defined as a tunnel cell surrounded by occupied cells (wall or
  tunnel) on all four sides. Cells with at least one open side are
  handled by cave_foreground and skipped here.
- Draw the tunnel cover in the game loop after top-layer units/effects
  but before cave_foreground and points, at 95% opacity (alpha=242)
  so the unit and effect passing underneath is just barely visible.
2026-06-16 23:06:17 +02:00
Matteo Benedetto 62a65f599d Draw explosions and gas inside tunnel cells
Remove the is_hidden_in_tunnel() checks from Explosion.draw() and
Gas.draw() so explosions and gas clouds remain visible when their center
falls inside a tunnel cell. Logic already spawned them in tunnel cells,
but they were rendered invisible because the draw path returned early.
2026-06-16 21:56:22 +02:00
Matteo Benedetto 5afdf3705b Render rats inside internal tunnel passages
Previously Rat.draw() hid any rat whose center fell inside a tunnel.
The clipping helper only handled single-entrance cells and returned None
for internal passages/crossroads, causing rats to vanish entirely.

Now internal tunnel cells (those with 0 or 2+ open sides) draw the rat
normally so it remains visible while walking through the tunnel.
Single-entrance cells keep the partial clip effect.
Also fix the visible-ratio math for DOWN/RIGHT clipping: the old
formulas subtracted cell_size from a local coordinate, producing
zero or negative visibility.
2026-06-16 20:37:46 +02:00
Matteo Benedetto b1e9770991 Use wall-only neighbor checks for wall border rendering
Previously regenerate_background() used occupied() (wall or tunnel) to
choose wall border/corner tiles. This caused walls adjacent to tunnels
to render with inner corners as if the tunnel were solid ground.

Now wall border logic uses is_wall() so only actual wall neighbors
influence the shape. Tunnel neighbor checks for flower-suppression are
kept explicit.
2026-06-16 20:24:33 +02:00
Matteo Benedetto 2f8e3e8b28 Fix gas poisoning, explosion hit detection and render order
- Move gas poisoning from Gas.move() to Gas.collisions() so all rats are
  registered in the collision system before the poison query runs.
- Shrink gas and explosion bboxes so rats must be well inside the tile to
  be poisoned/killed.
- Use AABB overlap instead of partial_move threshold for gas poisoning.
- Draw mobile units first, then top-layer effects (gas, mines, bombs,
  explosions) so rats appear under the gas.
- Add draw_on_top hint to Unit base class and top-layer units.
2026-06-16 19:32:50 +02:00
Matteo Benedetto 3e8cd97fda Fix bomb explosions not killing rats and remove tracked pycache
- Move Timer explosion from move() to collisions() so all units are
  registered in the collision system before the kill query runs.
- Explosion units now set a bbox and kill rats that touch them.
- Guard Rat.draw() so dead rats are not drawn.
- Remove units/__pycache__ files from tracking.
2026-06-16 19:15:35 +02:00
John Doe c7ed24483d Add comprehensive test suite for game mechanics and level handling
- Introduced `test_final_level_flow.py` to validate final level transitions and game end scenarios.
- Created `test_game_over_flow.py` to ensure game over conditions trigger correctly based on rat counts.
- Implemented `test_keybindings.py` to verify keybinding configurations and their context-specific actions.
- Developed `test_level_editor.py` to assess level editor functionalities and layout computations.
- Added `test_level_io.py` for testing level data serialization and deserialization.
- Established `test_loop_logic_parity.py` to ensure consistent game state across multiple simulation runs.
- Created `test_non_regression.py` to simulate game behavior and capture states for future verification.
- Implemented `test_verify.py` to compare current game states against a golden master for regression detection.
2026-05-19 22:18:43 +02:00
John Doe 486cd6b7c5 Add non-regression test states and Bluetooth diagnostic script
- Introduced a new JSON file containing non-regression test states with detailed unit information, including positions, ages, and movement directions across multiple frames.
- Added a shell script for Bluetooth diagnostics that checks system information, Bluetooth binaries, running processes, D-Bus status, Bluetooth controller details, and audio stack status, providing a comprehensive overview for troubleshooting.
2026-05-17 23:36:24 +02:00
John Doe dd82ccc087 Add launcher script for microphone visualizer with gamepad support 2026-05-09 17:57:57 +02:00
John Doe 7868d83ced Add microphone visualizer tool using SDL2 for audio input visualization
- Implemented a new Python script `mic_visualizer.py` that captures audio from a microphone and visualizes it in real-time.
- Utilized SDL2 for audio capture and rendering, allowing users to see waveform and spectrum representations of the audio input.
- Added command-line arguments for listing devices, selecting a capture device, and configuring window size and audio settings.
- Included functionality for displaying audio levels and peaks, enhancing user experience with visual feedback.
2026-05-09 17:55:29 +02:00
John Doe d4c73a344b Add Mice! game box art image to MUOS catalogue 2026-05-09 17:27:26 +02:00
John Doe 703e4717e4 Add metadata files for Mice! game in muOS catalogue 2026-05-09 17:22:55 +02:00
John Doe b849e16f69 Add new start animation asset for game launch 2026-05-09 17:08:53 +02:00
John Doe c7ff5ae4cf Refactor code structure for improved readability and maintainability 2026-05-09 16:35:25 +02:00
John Doe ac80210ba5 Add guide button to quit game in start menu keybindings 2026-05-09 13:32:57 +02:00
John Doe d9d7a4ac82 Update keybindings and enhance loading screen functionality
- Refactor keybindings for gas spawning across multiple configurations
- Implement new loading screen updates during game initialization
- Add tests to ensure all weapon actions are exposed in keybinding profiles
- Introduce new assets for explosion effects
2026-05-09 13:29:32 +02:00
John Doe 310dc0dca9 Add DAT finale flow, editor, and new soundtrack assets 2026-05-09 12:03:17 +02:00
John Doe f0d056e7f0 Make muOS launcher prefer local venv 2026-05-08 19:45:25 +02:00
John Doe d32d2cd79c Refine start menu difficulty and preview workflow 2026-05-08 18:26:55 +02:00
John Doe f1770b218c Add animated start menu and level music config 2026-05-07 23:18:39 +02:00
John Doe 2367f4fb1c Add menu audio controls and menu music 2026-05-07 20:35:15 +02:00
John Doe a908b50019 Add looping gameplay music 2026-05-07 20:03:20 +02:00
John Doe 5233294b26 Detect muOS board for keybindings 2026-05-07 19:38:05 +02:00
John Doe 486fea38e7 Implement game controller support and add keybindings for gamepad input 2026-05-07 17:50:07 +02:00
John Doe 9421d8d47c Remove 'kill_rat' keybinding from game controls for cleaner input mapping 2026-05-07 17:49:52 +02:00
John Doe 509b3433b8 Refactor rendering logic in MiceMaze and Rat classes for improved clarity and efficiency 2026-04-14 12:15:16 +02:00
John Doe bbafc3bbba Add new PNG assets for Rat character and environmental elements 2026-04-14 11:35:57 +02:00
John Doe b243cf04d3 Add explosion stage 1 PNG assets for all directions
- Added BMP_1_EXPLOSION_DOWN.png to original and preview directories.
- Added BMP_1_EXPLOSION_LEFT.png to original and preview directories.
- Added BMP_1_EXPLOSION_RIGHT.png to original and preview directories.
- Added BMP_1_EXPLOSION_UP.png to original and preview directories.

These assets are part of the explosion animation for the game, enhancing visual effects during gameplay.
2026-04-14 11:24:16 +02:00
John Doe eaafd92dc2 Enhance asset loading by removing unnecessary surface parameter and adding texture variants for grass and flowers 2026-03-28 16:53:22 +01:00
John Doe b60ffd87aa Refactor code structure for improved readability and maintainability 2026-03-28 16:05:08 +01:00
John Doe 02202e4d3d Add new PNG images for clean and preview outputs
- Added `image_clean.png` to the output directory for the clean image representation.
- Added `image_clean_preview.png` for the preview of the clean image.
- Introduced `image_svg_clean.png` for the SVG clean image representation.
2026-03-27 23:40:27 +01:00
John Doe e7c5ebb119 Add Miniforge environment definition 2026-03-27 22:44:58 +01:00
John Doe 9a86a3734f Add comprehensive NumPy tutorial for optimizing collision detection system 2025-10-24 23:07:57 +02:00
John Doe b4224ed3a1 v1.1: Performance optimizations and bug fixes
Major improvements:
- NumPy-based collision system supporting 200+ units (~3ms/frame)
- Spatial hashing with vectorized distance calculations
- 4-pass game loop ensuring correct collision timing
- Blood overlay system with pre-generated stain pool
- Cached render positions and viewport bounds
- Spawn protection preventing rats spawning on weapons

Bug fixes:
- Fixed bombs not killing rats (collision system timing)
- Fixed gas not affecting rats (collision system timing)
- Fixed rats spawning on weapons (added has_weapon_at check)
- Fixed AttributeError with Gas collisions (added isinstance check)
- Fixed blood stain transparency (RGBA + SDL_BLENDMODE_BLEND)
- Reduced point lifetime from 200 to 90 frames (~1.5s)
- Blood layer now clears on game restart

Technical changes:
- Added engine/collision_system.py with CollisionLayer enum
- Updated all units to use collision layers
- Pre-allocate NumPy arrays with capacity management
- Hybrid collision approach (<10 simple, ≥10 vectorized)
- Python 3.13 compatibility
v1.1
2025-10-24 20:04:26 +02:00
John Doe 12836dd2d2 Implement optimized collision detection system using NumPy
- Introduced a hybrid collision detection approach that utilizes NumPy for vectorized operations, improving performance for games with many entities (200+).
- Added a spatial grid for efficient lookups and AABB (Axis-Aligned Bounding Box) collision detection.
- Implemented a new `CollisionSystem` class with methods for registering units, checking collisions, and managing spatial data.
- Created performance tests to benchmark the new collision system against the old O(n²) method, demonstrating significant speed improvements.
- Updated existing code to integrate the new collision detection system and ensure compatibility with game logic.
2025-10-24 19:13:30 +02:00
Matteo Benedetto 47028c95ae Implement main menu, profile list, and profile stats screens; add screen manager and user profile integration 2025-08-24 22:13:00 +02:00
Matteo Benedetto c004edef8f Update asset loading to include transparent color and adjust white flash timing; enhance nuclear bomb scoring and gas unit die method 2025-08-21 19:00:32 +02:00