# Mice! Mice! is a strategic game where players must kill rats with bombs before they reproduce and become too numerous. The game is a clone of the classic game Rats! for Windows 95. ## Compatibility *It's developed in Python 3.13, please use it* ## Features - **Maze Generation**: Randomly generated mazes using Depth First Search (DFS) algorithm. - **Units**: Different types of units such as rats, bombs, and points with specific behaviors. - **Graphics**: Custom graphics for maze tiles, units, and effects. - **Sound Effects**: Audio feedback for various game events. - **Scoring**: Points system to track player progress. - **Performance**: Optimized collision detection system supporting 200+ simultaneous units using NumPy vectorization. ## Engine Architecture The Mice! game engine is built on a modular architecture designed for flexibility and maintainability. The engine follows a component-based design pattern where different systems handle specific aspects of the game. ### Core Engine Components #### 1. **Collision System** (`engine/collision_system.py`) - **CollisionSystem Class**: High-performance collision detection using NumPy vectorization - **Features**: - Spatial hashing with grid-based lookups (O(1) average case) - Support for 6 collision layers (RAT, BOMB, GAS, MINE, POINT, EXPLOSION) - Hybrid approach: simple iteration for <10 candidates, NumPy vectorization for ≥10 - Pre-allocated arrays with capacity management to minimize overhead - Area queries for explosion damage (get_units_in_area) - Cell-based queries for gas/mine detection (get_units_in_cell) - **Performance**: - Handles 200+ units at ~3ms per frame - Reduces collision checks from O(n²) to O(n) using spatial partitioning - Vectorized distance calculations for massive parallel processing #### 2. **Rendering System** (`engine/sdl2.py`) - **GameWindow Class**: Central rendering manager using SDL2 - **Features**: - Hardware-accelerated rendering via SDL2 - Texture management and caching - Sprite rendering with transparency support (SDL_BLENDMODE_BLEND for alpha blending) - Text rendering with custom fonts - Resolution-independent scaling - Fullscreen/windowed mode switching - Blood stain rendering with RGBA format and proper alpha channel - **Optimizations**: - Cached viewport bounds to avoid repeated calculations - Pre-cached image sizes for all assets at startup - Blood overlay layer system (no background regeneration needed) - Pre-generated blood stain pool (10 variants) for instant spawning - **Implementation**: - Uses SDL2 renderer for efficient GPU-accelerated drawing - Implements double buffering for smooth animation - Manages texture atlas for optimized memory usage - Handles viewport transformations for different screen resolutions #### 3. **Input System** (`engine/controls.py`) - **KeyBindings Class**: Handles all user input - **Features**: - Keyboard input mapping and handling - Joystick/gamepad support - Configurable key bindings - Input state management - **Implementation**: - Event-driven input processing - Key state buffering for smooth movement - Support for multiple input devices simultaneously - Customizable control schemes #### 3. **Map System** (`engine/maze.py`) - **Map Class**: Manages the game world structure - **Features**: - Maze data loading and parsing - Collision detection system - Tile-based world representation - Pathfinding support for AI units - **Implementation**: - Grid-based coordinate system - Efficient collision detection using spatial partitioning - Support for different tile types (walls, floors, special tiles) - Integration with maze generation algorithms #### 4. **Audio System** - **Sound Management**: Handles all audio playback - **Features**: - Sound effect playback - Background music support - Volume control - Multiple audio channels - **Implementation**: - Uses subprocess module for audio playback - Asynchronous sound loading and playing - Audio file format support (WAV, MP3, OGG) ### Game Loop Architecture The main game loop follows an optimized 4-pass pattern: 1. **Pre-Registration Phase**: Populate collision system with unit positions before movement 2. **Update Phase**: Execute unit logic and movement (bombs/gas can now query collision system) 3. **Re-Registration Phase**: Update collision system with new positions after movement 4. **Collision & Render Phase**: Check collisions and draw all game objects ``` Pre-Register → Move → Re-Register → Collisions → Render → Present → Repeat ``` This architecture ensures weapons (bombs, gas) can detect victims during their execution phase while maintaining accurate collision data. ## Units Implementation The game uses an object-oriented approach for all game entities. Each unit type inherits from a base unit class and implements specific behaviors. ### Base Unit Architecture All units share common properties and methods: - **Position and Movement**: 2D coordinates with movement capabilities - **Unique Identification**: UUID-based unique identifiers - **Collision Detection**: Bounding box collision system - **State Management**: Current state tracking (alive, dead, exploding, etc.) - **Rendering**: Sprite-based visual representation ### Unit Types Implementation #### 1. **Rat Units** (`units/rat.py`) **Base Rat Class**: - **AI Behavior**: Implements pathfinding using A* algorithm - **Movement**: Grid-based movement with smooth interpolation - **State Machine**: Multiple states (wandering, fleeing, reproducing) **Male Rat Class**: - **Reproduction Logic**: Seeks female rats for mating - **Territorial Behavior**: Defends territory from other males - **Lifespan Management**: Age-based death system **Female Rat Class**: - **Pregnancy System**: Gestation period simulation - **Offspring Generation**: Creates new rat units - **Maternal Behavior**: Protects offspring from threats **Implementation Details**: ```python # Optimized rat behavior with pre-calculated render positions class Rat: def move(self): self.process_ai() # Decision making self.handle_movement() # Position updates self._update_render_position() # Cache render coordinates def collisions(self): # Use optimized collision system with vectorization collisions = self.game.collision_system.get_collisions_for_unit( self.id, self.bbox, self.collision_layer ) # Process only Rat-to-Rat collisions for _, other_id in collisions: other_unit = self.game.get_unit_by_id(other_id) if isinstance(other_unit, Rat): self.handle_rat_collision(other_unit) def draw(self): # Use cached render positions (no recalculation) self.game.render_engine.draw_image( self.render_x, self.render_y, self.sprite, tag="unit" ) ``` #### 2. **Bomb Units** (`units/bomb.py`) **Bomb Class**: - **Timer System**: Countdown mechanism before explosion - **Placement Logic**: Player-controlled positioning - **Damage Calculation**: Blast radius and damage computation **Explosion Class**: - **Visual Effects**: Animated explosion graphics - **Damage Dealing**: Affects units within blast radius - **Temporary Entity**: Self-destructs after animation **Implementation Details**: - **State Machine**: Armed → Countdown → Exploding → Cleanup - **Optimized Damage System**: Uses collision_system.get_units_in_area() with vectorized distance calculations - **Effect Propagation**: Chain reaction support for multiple bombs - **Area Query Example**: ```python def die(self): # Collect explosion positions explosion_positions = self.calculate_blast_radius() # Query all rats in blast area using vectorized collision system victims = self.game.collision_system.get_units_in_area( explosion_positions, layer_filter=CollisionLayer.RAT ) for unit_id in victims: rat = self.game.get_unit_by_id(unit_id) if rat: rat.die() ``` #### 3. **Point Units** (`units/points.py`) **Point Class**: - **Collection Mechanics**: Player interaction system - **Value System**: Different point values for different achievements - **Visual Feedback**: Pickup animations and effects ### Unit Interaction System Units interact through a centralized collision and event system: 1. **Collision Detection**: - **Spatial hashing**: Grid-based broad phase with O(1) lookups - **NumPy vectorization**: Parallel distance calculations for large candidate sets - **Hybrid approach**: Direct iteration for <10 candidates, vectorization for ≥10 - **Layer filtering**: Efficient collision filtering by unit type (RAT, BOMB, GAS, etc.) - **Area queries**: Optimized explosion and gas effect calculations 2. **Event System**: - Unit death events - Reproduction events - Explosion events (with area damage) - Point collection events (90 frames lifetime ~1.5s at 60 FPS) 3. **AI Communication**: - Shared pathfinding data - Pheromone trail system for rat behavior - Danger awareness (bombs, explosions) 4. **Spawn Protection**: - Rats won't spawn on cells occupied by weapons (mines, bombs, gas) - Automatic fallback to adjacent cells if primary position blocked - Prevents unfair early-game deaths ## Technical Details - **Language**: Python 3.13 - **Libraries**: - `numpy` 2.3.4 for vectorized collision detection - `sdl2` for graphics and window management - `Pillow` for image processing - `uuid` for unique unit identification - `subprocess` for playing sound effects - `tkinter` for maze generation visualization - **Performance Optimizations**: - **Collision System**: NumPy-based spatial hashing reducing O(n²) to O(n) - **Rendering Cache**: Pre-calculated render positions, viewport bounds, and image sizes - **Blood Overlay**: Separate sprite layer eliminates background regeneration - **Hybrid Processing**: Automatic switching between direct iteration and vectorization - **Pre-allocated Arrays**: Capacity-based resizing minimizes NumPy vstack overhead - **Texture Atlasing**: Reduced memory usage and GPU calls - **Object Pooling**: Blood stain pool (10 pre-generated variants) - **Delta Time Updates**: Frame rate independence - **Memory Management**: - Automatic cleanup of dead units - Texture caching and reuse - Efficient data structures for 200+ simultaneous units - Blood stain sprite pool to avoid runtime generation ## Environment Variables - `SDL_VIDEODRIVER`: Set the video driver (x11, wayland, etc.) - `RESOLUTION`: Set the screen resolution (format: WIDTHxHEIGHT) - `FULLSCREEN`: Enable/disable fullscreen mode (true/false) - `SOUND_ENABLED`: Enable/disable sound effects (true/false) ## Installation 1. **Clone the repository**: ```bash git clone https://github.com/yourusername/mice-maze-game.git cd mice-maze-game ``` 2. **Create a virtual environment**: ```bash python3 -m venv venv source venv/bin/activate ``` 3. **Install the dependencies**: ```bash pip install -r requirements.txt ``` 4. **Run the game**: ```bash python rats.py ``` ## Project Structure ``` mice/ ├── engine/ # Core engine components │ ├── collision_system.py # NumPy-based vectorized collision detection │ ├── controls.py # Input handling system │ ├── graphics.py # Blood overlay and rendering optimizations │ ├── maze.py # Map and collision system │ ├── sdl2.py # Rendering and window management │ └── unit_manager.py # Unit spawning and lifecycle management ├── units/ # Game entity implementations │ ├── unit.py # Base unit class with collision layers │ ├── bomb.py # Bomb and explosion logic with area damage │ ├── gas.py # Gas weapon with cell-based detection │ ├── mine.py # Proximity mine with trigger system │ ├── rat.py # Rat AI with optimized rendering cache │ └── points.py # Collectible points (90 frames lifetime) ├── assets/ # Game resources │ ├── images/ # Sprites and textures │ └── fonts/ # Text rendering fonts ├── sound/ # Audio files ├── maze.py # Maze generation algorithms ├── rats.py # Main game entry point with 4-pass game loop ├── requirements.txt # Python dependencies (including numpy) ├── .env # Environment configuration └── README.md # This documentation ``` ## Game Files Details - `maze.py`: Contains the `MazeGenerator` class implementing DFS algorithm for procedural maze generation - `rats.py`: Main game controller with 4-pass optimized game loop, manages collision system and unit lifecycle - `engine/collision_system.py`: NumPy-based spatial hashing system supporting 200+ units at 3ms/frame - `engine/graphics.py`: Blood overlay system with pre-generated stain pool and rendering optimizations - `engine/controls.py`: Input abstraction layer with configurable key bindings - `engine/maze.py`: World representation with collision detection and pathfinding support - `engine/sdl2.py`: Low-level graphics interface wrapping SDL2 with alpha blending and texture caching - `engine/unit_manager.py`: Centralized unit spawning with weapon collision avoidance - `units/unit.py`: Base unit class with collision layer support - `units/bomb.py`: Explosive units with vectorized area damage calculations - `units/gas.py`: Area denial weapon using cell-based victim detection - `units/mine.py`: Proximity-triggered explosives - `units/rat.py`: AI-driven entities with cached render positions and collision filtering - `units/points.py`: Collectible scoring items (90 frame lifetime, ~1.5s at 60 FPS) - `assets/`: Game resources including sprites, textures, and fonts - `sound/`: Audio assets for game events and feedback - `scores.txt`: Persistent high score storage - `.env`: Runtime configuration and environment settings - `.gitignore`: Version control exclusion rules