27 KiB
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
Developed and tested with Python 3.11+
Features
- Maze Generation: Randomly generated mazes using Depth First Search (DFS) algorithm
- Multiple Unit Types: Rats, bombs, mines, gas, and collectible points with unique behaviors
- User Profile System: Track scores, achievements, and game statistics
- Graphics: Custom graphics for maze tiles, units, and effects
- Sound Effects: Audio feedback for various game events
- Scoring: Points system with leaderboards and profile integration
- Dual Rendering Engines: Support for both SDL2 and Pygame
Rendering Engine Options
The game now supports two rendering backends with identical interfaces:
1. SDL2 Backend (engine/sdl2_layer.py)
- Original implementation using PySDL2
- Hardware-accelerated rendering via SDL2
- Optimized for performance on Linux systems
- Direct access to low-level graphics features
2. Pygame Backend (engine/pygame_layer.py) ⭐ NEW
- Drop-in replacement for SDL2 backend
- More portable and easier to set up
- Better cross-platform support (Windows, macOS, Linux)
- Simplified dependency management
- Identical API - no game code changes needed
Switching Between Rendering Engines
To switch from SDL2 to Pygame, simply change the import in rats.py:
# Using SDL2 (original)
from engine import maze, controls, graphics, sdl2_layer as engine, unit_manager, scoring
# Using Pygame (new)
from engine import maze, controls, graphics, pygame_layer as engine, unit_manager, scoring
That's it! No other code changes are required thanks to the compatible interface design.
Browser / Pyodide Support (experimental)
- The project includes an experimental browser build that runs the game in WebAssembly using Pyodide and a bundled pygame-ce build. This supports running the game inside modern browsers (desktop only) and is intended for demos and lightweight testing.
- Key points:
index.htmlcontains the Pyodide bootstrap, asset loader and a JS-driven game loop that calls into the Python game tick function so the UI stays responsive.- The browser integration includes a small profile sync mechanism so profiles saved by the Python code (inside Pyodide's virtual FS) are synchronized back to browser
localStorage. - A tiny utility
tools/create_favicon.pygeneratesfavicon.icofrom the game'sassetsif you want a browser favicon for local hosting.
Use the browser demo for quick sharing and testing, but prefer the native Python + SDL2/pygame backends for actual play and development.
Cleanup notes
This repository contains some auxiliary files used during development and for old/demo flows. If you want me to remove unused items, I can safely delete them in a single branch/commit after you confirm. Suggested candidates are listed in the developer checklist below.
Developer cleanup checklist (proposed deletions)
These files look like auxiliary or duplicate/demo artifacts and can be removed to reduce noise. I'll only delete them if you confirm.
BROWSER_GAME_README.md— duplicate/demo readme for browser buildBROWSER_SETUP_QUICK_START.md— quick-start for browser demoPYGAME_BACKEND_GUIDE.md— documentation duplicatepyodide-guide.html— local demo HTML (we already shipindex.html)browser-game-setup.shandplay.sh— demo scripts not used in CIassets/asset-manifest.json,assets/sound-manifest.json— generated manifests (can be regenerated)engine/pygame_layer.pyandengine/sdl2_layer.py— ensure you want to keep one backend; if you prefer only SDL2 or only Pygame, remove the other
If you'd like me to proceed, reply with "delete these files" and I will create a branch, remove them, and push the change.
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. Rendering System (engine/sdl2_layer.py or engine/pygame_layer.py)
- GameWindow Class: Central rendering manager
- Features:
- Hardware-accelerated rendering
- Texture management and caching
- Sprite rendering with transparency support
- Text rendering with custom fonts
- Resolution-independent scaling
- Fullscreen/windowed mode switching
- Dynamic blood splatter effects
- White flash screen effects
- Implementation:
- Double buffering for smooth animation
- Texture atlas for optimized memory usage
- Viewport transformations for different screen resolutions
- Alpha blending for transparency effects
2. Input System (engine/controls.py)
- KeyBindings Class: Handles all user input
- Features:
- Keyboard input mapping and handling
- Joystick/gamepad support
- Configurable key bindings via YAML/JSON
- Context-sensitive input (menu vs. gameplay)
- Implementation:
- Event-driven input processing
- Support for multiple input devices simultaneously
- Dynamic key binding system with action mapping
3. Map System (engine/maze.py)
- Map Class: Manages the game world structure
- Features:
- Maze data loading from JSON
- Collision detection system
- Tile-based world representation
- Pathfinding support for AI units
- Implementation:
- Grid-based coordinate system
- Efficient collision detection
- Support for walls and floor tiles
- Integration with procedural maze generation
4. Audio System
- Sound Management: Handles all audio playback
- Features:
- Sound effect playback with multiple channels
- Background music support
- Volume control
- Per-channel audio mixing
- Implementation:
- SDL2 backend: Native SDL2 audio system
- Pygame backend: pygame.mixer module
- Support for WAV format audio files
- Multiple simultaneous sound channels (base, effects, music)
5. Unit Management System (engine/unit_manager.py)
- UnitManager Class: Manages all game entities
- Features:
- Dynamic unit spawning and removal
- Position tracking for collision detection
- Resource management (ammo, items)
- Implementation:
- UUID-based unique identifiers
- Efficient lookup structures
- Automatic cleanup on unit death
6. User Profile System (engine/user_profile_integration.py)
- UserProfileIntegration Class: Manages player profiles
- Features:
- Multiple user profile support
- Score tracking and leaderboards
- Game statistics (games played, wins, best score)
- Device-specific profiles
- Global leaderboard integration
Game Loop Architecture
The main game loop follows the standard pattern:
- Input Processing: Capture and process user input
- Update Phase: Update game state, unit logic, and physics
- Render Phase: Draw all game objects to the screen
- Timing Control: Maintain consistent frame rate (target 60 FPS)
Input → Update → Render → Present → Repeat
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 (units/unit.py)
All units share common properties and methods defined in the abstract Unit class:
Common Attributes:
id(UUID): Unique identifier for each unitposition(tuple): Current (x, y) grid coordinatesposition_before(tuple): Previous position for smooth movementage(int): Time alive in game ticksspeed(float): Movement speed multiplierpartial_move(float): Sub-cell movement progress (0.0 to 1.0)bbox(tuple): Bounding box for collision detectionstop(int): Remaining ticks of immobilization
Abstract Methods (must be implemented by subclasses):
move(): Update unit position and state each framedraw(): Render the unit on screen
Concrete Methods:
collisions(): Handle interactions with other unitsdie(score=None): Remove unit from game and handle cleanup
Unit Types Implementation
1. Rat Units (units/rat.py)
Base Rat Class:
- AI Behavior: Pathfinding with direction memory to avoid backtracking
- Movement: Smooth interpolated movement between grid cells
- Lifecycle: Age-based behavior changes (baby → adult → elder)
- Gas Vulnerability: Can be killed by poison gas
Male Rat Class:
- Reproduction: Seeks female rats for mating
- Fighting: Territorial combat with other males
- Adult Threshold: Becomes fertile after 200 game ticks
Female Rat Class:
- Pregnancy System: 500-tick gestation period
- Offspring Generation: Spawns baby rats at intervals
- Maternal Behavior: Protects territory from threats
Implementation Details:
class Rat(Unit):
def move(self):
self.age += 1
if self.gassed > 35:
self.choked() # Death by gas
if self.age == AGE_THRESHOLD:
self.speed *= SPEED_REDUCTION # Slow down with age
self.partial_move += self.speed
if self.partial_move >= 1:
self.position = self.find_next_position()
self.partial_move = 0
2. Bomb Units (units/bomb.py)
Timer Bomb Class:
- Countdown System: Visual timer (4 stages) before explosion
- Chain Reactions: Triggers nearby bombs
- Directional Blast: Explodes in 4 cardinal directions until hitting walls
Nuclear Bomb Class:
- Instant Kill: Destroys all rats on the map
- White Flash Effect: Screen flash on detonation
- Single Use: Limited to 1 per game
Explosion Class:
- Temporary Effect: Short-lived visual and damage entity
- Kill Radius: Destroys all rats in the same cell
- Score Bonus: Awards points for each rat killed
Implementation Details:
class Timer(Bomb):
def move(self):
self.age += 1
if self.age > 160: # 160 ticks = explosion
self.die(unit=self, score=10)
def die(self, unit=None, score=None):
# Create explosion and propagate in 4 directions
for direction in ["N", "S", "E", "W"]:
# Spread until wall
while not self.game.map.is_wall(x, y):
self.game.spawn_unit(Explosion, (x, y))
3. Mine Units (units/mine.py)
Mine Class:
- Arming Delay: Becomes active after placement delay
- Contact Trigger: Detonates when rat steps on it
- Gas Release: Creates poison gas clouds on detonation
- Limited Supply: Max 4 mines at a time
4. Gas Units (units/gas.py)
Gas Cloud Class:
- Lingering Effect: Stays in place for duration
- Poison Damage: Accumulates damage on rats over time
- Chaining: Can spawn additional gas clouds
- Visual Effect: Semi-transparent gas sprite
5. Point Units (units/points.py)
Point Class:
- Collection Mechanics: Auto-collected by player cursor
- Value System: Different point values (5, 10, 25, 50, 100)
- Timed Existence: Disappears after ~5 seconds
- Score Tracking: Updates player score on collection
Unit Interaction System
Units interact through a centralized collision and event system:
Collision Detection
- Spatial Hashing: Grid-based lookup for nearby units
- Bounding Box: Precise pixel-perfect collision detection
- Overlap Tolerance: Small margin to prevent jittering
- Bi-directional: Both units check for collisions
Event System
- Death Events: Spawn points, trigger explosions, update score
- Reproduction Events: Create new rat units
- Explosion Events: Chain reactions, area damage
- Collection Events: Point pickup, ammo refill
AI Communication
- Position Tracking:
unit_positionsdictionary for fast lookup - Shared Pathfinding: Avoid blocked cells
- Danger Awareness: Rats flee from explosions
Technical Details
Language & Core Libraries
- Python: 3.11+ (recommended)
- Rendering:
pysdl2- SDL2 bindings for graphics (original backend)pygame- Pygame library for graphics (new backend)
- Image Processing:
Pillow- For image loading and manipulation - Configuration:
pyaml- YAML config file parsing - Standard Library:
uuid,random,os,json
Performance Optimizations
- Spatial Partitioning: Grid-based collision detection reduces O(n²) to O(n)
- Texture Caching: Pre-loaded assets prevent repeated disk I/O
- Background Rendering: Static maze rendered once, cached as texture
- Delta Time: Frame-rate independent updates using
partial_move - Efficient Drawing: Only draw units in visible viewport area
Memory Management
- Automatic Cleanup: Dead units removed from
unitsdictionary - Surface Reuse: Blood stains combined into background texture
- Lazy Loading: Assets loaded on demand
- Reference Counting: Python GC handles most cleanup
Architecture Patterns
- Multiple Inheritance: Game class combines Controls, Graphics, UnitManager, Scoring
- Abstract Base Classes:
Unitdefines interface for all game entities - Factory Pattern:
spawn_unit()method for dynamic unit creation - Observer Pattern: Event-driven input system with callbacks
- Strategy Pattern: Different AI behaviors for rat types
Environment Variables
Configure the game behavior using environment variables:
SDL_VIDEODRIVER: Video driver selection (x11, wayland, etc.)RESOLUTION: Screen resolution in formatWIDTHxHEIGHT(default: 640x480)FULLSCREEN: Enable fullscreen mode (true/false)SOUND_ENABLED: Enable/disable sound effects (true/false)
Example:
RESOLUTION=1920x1080 FULLSCREEN=true python rats.py
Installation
Prerequisites
- Python 3.11 or higher
- pip package manager
Step-by-Step Installation
-
Clone the repository:
git clone https://github.com/yourusername/mice-maze-game.git cd mice-maze-game -
Create a virtual environment (recommended):
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate -
Install dependencies:
For Pygame backend (recommended for beginners):
pip install pygame Pillow pyamlFor SDL2 backend (advanced users):
pip install pysdl2 Pillow pyamlOr install all dependencies:
pip install -r requirements.txt -
Run the game:
python rats.py
Platform-Specific Notes
Linux
- SDL2 backend requires
libsdl2-devpackage - Install via:
sudo apt-get install libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev
macOS
- Install SDL2 via Homebrew:
brew install sdl2 sdl2_ttf sdl2_mixer - Pygame backend works out of the box
Windows
- Pygame backend recommended (easiest setup)
- SDL2 backend requires manual SDL2 DLL installation
Project Structure
mice/
├── engine/ # Core engine components
│ ├── controls.py # Input handling system
│ ├── graphics.py # Graphics and rendering helpers
│ ├── maze.py # Map and collision system
│ ├── sdl2_layer.py # SDL2 rendering backend
│ ├── pygame_layer.py # Pygame rendering backend ⭐ NEW
│ ├── unit_manager.py # Entity spawning and management
│ ├── scoring.py # Score tracking system
│ ├── user_profile_integration.py # User profile system
│ └── score_api_client.py # API client for global leaderboard
├── units/ # Game entity implementations
│ ├── __init__.py # Unit package exports
│ ├── unit.py # Abstract base class for all units
│ ├── rat.py # Rat AI and behavior (Male/Female)
│ ├── bomb.py # Bombs, timers, and explosions
│ ├── mine.py # Mine traps
│ ├── gas.py # Poison gas clouds
│ └── points.py # Collectible point items
├── profile_manager/ # Profile management system
│ ├── profile_manager.py # Profile CRUD operations
│ ├── profile_data.py # Profile data models
│ ├── ui_components.py # UI helpers
│ └── screens/ # Profile management screens
│ ├── screen_manager.py # Screen navigation
│ ├── main_menu_screen.py
│ ├── profile_list_screen.py
│ ├── create_profile_screen.py
│ ├── edit_profile_screen.py
│ ├── profile_stats_screen.py
│ └── leaderboard_screen.py
├── assets/ # Game resources
│ ├── Rat/ # Sprite images
│ │ ├── BMP_*.png # Various game sprites
│ └── decterm.ttf # Font file
├── sound/ # Audio files
│ ├── converted/ # Converted audio format
│ └── *.WAV # Sound effects
├── conf/ # Configuration files
│ ├── keybindings.yaml # Key mapping configuration
│ ├── keybindings_*.yaml # Device-specific bindings
│ └── keybindings.json # JSON format bindings
├── tools/ # Utility scripts
│ ├── convert_audio.py # Audio format converter
│ ├── resize_assets.py # Image resizing tool
│ └── colorize_assets.py # Asset colorization
├── rats.py # Main game entry point
├── maze.json # Maze layout data
├── user_profiles.json # User profile storage
├── requirements.txt # Python dependencies
├── README.md # This documentation
├── README_PROFILE_MANAGER.md # Profile system documentation
└── UNIT_ARCHITECTURE_GUIDE.md # Unit system guide
Game Files Details
Core Game Files
rats.py: Main game controller, entry point, and game loopmaze.json: Maze layout definition (grid of walls and paths)key.py: Additional key handling utilities
Engine Modules
engine/controls.py: Input abstraction with configurable bindingsengine/graphics.py: Graphics helpers (asset loading, background generation)engine/maze.py: World representation with collision detectionengine/sdl2_layer.py: Low-level SDL2 graphics interfaceengine/pygame_layer.py: Pygame graphics interface (new)engine/unit_manager.py: Unit spawning and lifecycle managementengine/scoring.py: Score calculation and persistence
Unit Implementations
units/unit.py: Abstract base class defining unit interfaceunits/rat.py: Rat AI with pathfinding and reproductionunits/bomb.py: Explosive units with timer and blast mechanicsunits/mine.py: Trap units with proximity triggerunits/gas.py: Poison gas clouds with area effectunits/points.py: Collectible scoring items
Data Files
user_profiles.json: Persistent user profile datascores.txt: Traditional high score storage (legacy)maze.json: Level layout definition
Configuration
conf/keybindings.yaml: Key mapping for different game states- Device-specific configs: Optimized bindings for different devices
How to Play
Objective
Eliminate all rats before they reproduce and overwhelm the maze. Collect points by killing rats with bombs, mines, and gas.
Controls
Default Keyboard Controls
- Arrow Keys: Move cursor
- Space: Place bomb at cursor position
- M: Place mine at cursor position
- G: Release poison gas at cursor position
- N: Deploy nuclear bomb (one-time use)
- P: Pause game
- F: Toggle fullscreen
- S: Toggle sound
- ESC: Quit game
Gamepad Support
- D-Pad: Move cursor
- Button A: Place bomb
- Button B: Place mine
- Button X: Release gas
- Start: Pause game
Controls can be customized via configuration files in conf/
Gameplay Tips
- Early Game: Focus on preventing rat reproduction by targeting adults
- Bomb Placement: Use walls to direct explosion paths
- Mine Strategy: Place mines in narrow corridors where rats pass frequently
- Gas Tactics: Gas lingers and accumulates damage - use in rat-dense areas
- Nuclear Option: Save the nuclear bomb for when rats exceed ~150
- Resource Management: Ammo refills randomly - don't waste bombs early
- Scoring: Chain kills and quick clears give bonus points
Win Condition
Clear all rats from the maze without letting their population exceed 200.
Lose Condition
Rat population exceeds 200 - they've overrun the maze.
Profile System
Mice! includes a comprehensive user profile system to track your progress:
Features
- Multiple Profiles: Create profiles for different players
- Statistics Tracking: Games played, wins, losses, best score
- Device Support: Profile data syncs across devices
- Leaderboards: Compare scores globally and locally
- Achievements: Track milestones and accomplishments
Profile Management
Access the profile manager before starting the game:
python profile_manager/profile_manager.py
Or manage profiles from within the game main menu.
Development
Adding New Units
- Create a new class in
units/inheriting fromUnit - Implement required methods:
move(),draw() - Optionally override:
collisions(),die() - Register in
units/__init__.py - Add spawning logic in
unit_manager.py
Example:
from units.unit import Unit
class MyUnit(Unit):
def move(self):
# Update logic here
pass
def draw(self):
# Rendering logic here
image = self.game.assets["MY_SPRITE"]
self.game.render_engine.draw_image(x, y, image, tag="unit")
Switching Rendering Backends
Edit the import in rats.py:
# For SDL2
from engine import sdl2_layer as engine
# For Pygame
from engine import pygame_layer as engine
Creating Custom Mazes
Edit maze.json - it's a 2D grid where:
0= path/floor1= wall
Example:
{
"maze": [
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 1, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1]
]
}
Troubleshooting
Common Issues
Issue: Game window doesn't appear
- Solution: Check
RESOLUTIONenvironment variable, try640x480
Issue: No sound
- Solution: Verify
SOUND_ENABLEDnot set to false, check audio files insound/
Issue: SDL2 import errors
- Solution: Switch to Pygame backend or install SDL2 libraries
Issue: Slow performance
- Solution: Reduce resolution, close other applications, update graphics drivers
Issue: Profile data not saving
- Solution: Check file permissions for
user_profiles.json
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is a fan remake of the classic "Rats!" game from Windows 95.
Credits
- Original Game: Rats! for Windows 95
- Developer: Matteo (because he was bored)
- Engine: Custom Python engine with SDL2/Pygame backends
- Contributors: See GitHub contributors page
Changelog
Version 2.0 (Current)
- ⭐ Added Pygame rendering backend
- ⭐ Dual backend support (SDL2 + Pygame)
- ⭐ Complete API compatibility between backends
- Improved documentation
- Enhanced README with technical details
Version 1.0
- Initial release
- SDL2 rendering engine
- User profile system
- Multiple unit types
- Configurable controls
- Leaderboard system
Technical Details
- Language: Python 3.11
- Libraries:
sdl2for graphics and window managementPillowfor image processinguuidfor unique unit identificationsubprocessfor playing sound effectstkinterfor maze generation visualization
- Performance Optimizations:
- Spatial partitioning for collision detection
- Texture atlasing for reduced memory usage
- Object pooling for frequently created/destroyed units
- Delta time-based updates for frame rate independence
- Memory Management:
- Automatic cleanup of dead units
- Texture caching and reuse
- Efficient data structures for large numbers of units
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
│ ├── controls.py # Input handling system
│ ├── maze.py # Map and collision system
│ └── sdl2.py # Rendering and window management
├── units/ # Game entity implementations
│ ├── bomb.py # Bomb and explosion logic
│ ├── rat.py # Rat AI and behavior
│ └── points.py # Collectible points
├── 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
├── requirements.txt # Python dependencies
├── .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, initializes engine systems and manages game stateengine/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 functionalityunits/bomb.py: Explosive units with timer mechanics and blast radius calculationsunits/rat.py: AI-driven entities with reproduction, pathfinding, and survival behaviorsunits/points.py: Collectible scoring items with visual feedback systemsassets/: 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