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.
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.
- Original Level Support: Loads the original
level.datfromassets/Rat/level.datwhen present and falls back tomaze.jsonotherwise. - 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.
Utilities
Microphone Visualizer
A small SDL2 microphone visualizer is available in tools/mic_visualizer.py.
- List capture devices:
python tools/mic_visualizer.py --list-devices - Open the default microphone:
python tools/mic_visualizer.py - Open a specific input:
python tools/mic_visualizer.py --device-index 1 - On muOS, use
mice_mic.shas a launcher inROMS/Portsand it will run fullscreen with gamepad quit support.
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
- DAT archive parsing for the original 32 built-in RATS levels
- 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:
- Pre-Registration Phase: Populate collision system with unit positions before movement
- Update Phase: Execute unit logic and movement (bombs/gas can now query collision system)
- Re-Registration Phase: Update collision system with new positions after movement
- 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:
# 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:
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:
-
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
-
Event System:
- Unit death events
- Reproduction events
- Explosion events (with area damage)
- Point collection events (90 frames lifetime ~1.5s at 60 FPS)
-
AI Communication:
- Shared pathfinding data
- Pheromone trail system for rat behavior
- Danger awareness (bombs, explosions)
-
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:
numpy2.3.4 for vectorized collision detectionsdl2for graphics and window management
Map Editor
The project now includes a Tkinter editor for level.dat archives:
- Launch with
python tools/level_editor.py - Open a specific archive with
python tools/level_editor.py --file assets/Rat/level.dat - Start on a specific level with
python tools/level_editor.py --file assets/Rat/level.dat --level 7 - The editor requires a Python installation with the standard
tkintermodule available at OS level
Editor capabilities:
- Edits the full 32-level DAT archive used by the game
- Creates new DAT archives with 32 default levels
- Paints
EMPTY,WALL, andTUNNELtiles with brush, fill, and rectangle tools - Supports undo/redo, level copy/paste, and level duplication between slots
- Imports a single level from JSON and exports the current level back to JSON
- Validates common gameplay issues such as missing spawn cells, open borders, and disconnected traversable areas
Level Sources
- Preferred source:
assets/Rat/level.dat - Fallback source:
maze.json - Current behavior: the loader can read any level from the DAT archive via
--level N, while still falling back tomaze.jsonwhen the DAT is unavailable. - Tile semantics are now preserved internally from the original format:
0=EMPTY,1=WALL,2=TUNNEL. - Rendering uses those semantics directly: walls use themed grass/flower tiles, tunnel cells use themed cave tiles, and empty cells remain the generic walkable tunnel floor used by the Python version.
Run examples
python rats.pypython rats.py --level 7python rats.py --map maze.jsonPillowfor image processinguuidfor unique unit identificationsubprocessfor playing sound effectstkinterfor 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
- Clone the repository:
bash git clone https://github.com/yourusername/mice-maze-game.git cd mice-maze-game - Create a virtual environment:
bash python3 -m venv venv source venv/bin/activate - Install the dependencies:
bash pip install -r requirements.txt - 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 theMazeGeneratorclass implementing DFS algorithm for procedural maze generationrats.py: Main game controller with 4-pass optimized game loop, manages collision system and unit lifecycleengine/collision_system.py: NumPy-based spatial hashing system supporting 200+ units at 3ms/frameengine/graphics.py: Blood overlay system with pre-generated stain pool and rendering optimizationsengine/controls.py: Input abstraction layer with configurable key bindingsengine/maze.py: World representation with collision detection and pathfinding supportengine/sdl2.py: Low-level graphics interface wrapping SDL2 with alpha blending and texture cachingengine/unit_manager.py: Centralized unit spawning with weapon collision avoidanceunits/unit.py: Base unit class with collision layer supportunits/bomb.py: Explosive units with vectorized area damage calculationsunits/gas.py: Area denial weapon using cell-based victim detectionunits/mine.py: Proximity-triggered explosivesunits/rat.py: AI-driven entities with cached render positions and collision filteringunits/points.py: Collectible scoring items (90 frame lifetime, ~1.5s at 60 FPS)assets/: Game resources including sprites, textures, and fontssound/: Audio assets for game events and feedbackscores.txt: Persistent high score storage.env: Runtime configuration and environment settings.gitignore: Version control exclusion rules