A real-time map overlay tool for Dark and Darker that uses computer vision to automatically detect which map you're on and display location names with a grid overlay.
- Auto-Detection: Automatically identifies the current map using ORB feature matching on the first visible cell
- Real-Time Updates: Progressive cell detection with live overlay updates
- Multi-Language Support: Location names in English, Chinese, and more (easily extensible)
- Smart Caching: Remembers your map selection for 15 minutes (configurable)
- ROI Selection: One-time region selection for the map area on your screen
- Performance Optimized: Multithreaded detection with configurable parameters
- Custom Fonts: Support for custom font loading (place .ttf/.otf files in
fonts/directory)
- Crypt
- Goblin Cave
- Ice Abyss
- Ice Cave
- Inferno
- Ruins
- Go to Releases
- Download the latest
MapHelper-vX.X.X-Windows.zip - Extract to a folder
- Run
MapHelper.exe
✨ Truly Standalone:
- Single .exe file (~100MB) with all maps and fonts embedded
- No Python installation required
- No external folders needed (except config files you create)
- Just download and run!
Prerequisites:
- Python 3.7 or higher
- Windows (tested), Linux/Mac (may require adjustments)
Setup:
- Clone the repository:
git clone https://github.com/garyku0/dnd-maphelper.git
cd dnd-maphelper- Install dependencies:
pip install -r requirements.txt- Run the application:
python main.py-
Run the application - A transparent overlay will appear
-
Press M to toggle the map overlay
-
Select ROI - On first run, drag to select the map area on your screen
Drag to select the map area (shown in red). The green border is incorrect exmaple
-
Choose Detection Method:
- Auto-Detect - Automatically identifies the map (Slower)
- Manual Selection - Choose from available maps
- Settings - Configure detection parameters
| Key | Action |
|---|---|
M |
Toggle map overlay on/off |
R |
Reset cache and force re-detection |
ESC x2 |
Exit application (press ESC twice within 1 second) |
- Press
Mto activate - Application captures the map area (ROI)
- Auto-detection analyzes the first cell only (fast!)
- Confirms the detected map with you
- Performs full detection on all cells (background)
- Displays grid overlay with location names
- Results cached for 15 minutes
Customize detection parameters via the in-app settings menu or by editing settings.json:
{
"threading_enabled": true,
"thread_count": 8,
"min_inliers": 6,
"match_threshold": 10,
"cache_duration_minutes": 15,
"update_interval_cells": 3,
"orb_features": 6000,
"ratio_test": 0.75,
"early_stop_threshold": 75,
"min_cache_confidence": 60,
"language": "en"
}Key Settings:
language: Display language for location names ("en","zh", etc.)cache_duration_minutes: How long to remember the current mapthreading_enabled: Enable/disable multithreading (tryfalseif detection is slow)thread_count: Number of parallel threads for detection (8-10 recommended)orb_features: Number of ORB features to extract (higher = more accurate but slower)update_interval_cells: Update overlay every N cells during detectionearly_stop_threshold: Confidence % (0-100) to stop checking other rotations (higher = more thorough)min_cache_confidence: Minimum confidence % to trust cached cell results (prevents bad matches from sticking)
Threading Notes:
- ORB feature matching is CPU-intensive. Due to Python's GIL, threading may not always improve speed
- Try
"threading_enabled": falseif multithreading feels slower - Single-threaded can be faster on some systems, especially with small grids (5x5)
The ROI is saved per screen resolution in config.json. To reset:
- Press
Rto reset cache, or - Delete
config.jsonand restart
- Create a folder in
maps/with your map name (e.g.,maps/NewMap/) - Add cell templates as images:
1_0.png,1_90.png,1_180.png,1_270.png(cell 1, all rotations)- Continue for all cells
- (Optional) Create
grid_config.txt:(rows, columns)5,5 - (Optional) Add translations in
locations_XX.json:{ "cell_name": "Display Name" }
See maps/TRANSLATION_GUIDE.md for details on adding translations.
maphelper/
├── main.py # Entry point
├── matcher.py # Core matching logic
├── requirements.txt # Dependencies
├── settings.json # User settings
├── config.json # ROI configurations
│
├── ui/ # UI Components
│ ├── overlay_manager.py # Overlay display
│ └── dialogs.py # Menus and dialogs
│
├── core/ # Core Logic
│ └── detection.py # Real-time detection
│
├── utils/ # Utilities
│ ├── config.py # Config management
│ ├── capture.py # Screen capture
│ └── settings.py # Settings manager
│
├── maps/ # Map templates
│ ├── Crypt/
│ ├── GoblinCave/
│ ├── IceAbyss/
│ ├── IceCave/
│ ├── Inferno/
│ └── Ruins/
│
├── fonts/ # Custom fonts (optional)
│ └── [your-font].ttf
│
└── tools/ # Utility scripts
└── optimize_templates.py
The app logs confidence scores to confidence_log.txt during detection. Use this data to optimize settings:
python analyze_confidence.pyThis shows:
- Min/Max/Average confidence scores
- Percentile distribution
- Recommendations for optimal thresholds based on your actual data
Example output:
RECOMMENDATIONS:
Suggested Settings (based on your data):
"early_stop_threshold": 68 // P75 - stop when match is in top 25%
"min_cache_confidence": 52 // P25 - re-match if below bottom 25%
If confidence values are consistently lower than defaults (75/60), the thresholds are too high and should be adjusted.
- Ensure the ROI correctly captures the map area
- Try increasing
orb_featuresin settings - Check that lighting/brightness is consistent with templates
- Use manual selection if auto-detect fails
- Run
python analyze_confidence.pyto check if thresholds are too high
- Verify the overlay window appears (check taskbar)
- Press
Mto toggle visibility - Ensure ROI is properly set
- Reduce
thread_countin settings - Decrease
orb_featuresfor faster detection - Increase
update_interval_cellsfor less frequent updates
- Template Matching: Uses ORB (Oriented FAST and Rotated BRIEF) feature detection
- Feature Extraction: 6000 features per template (configurable)
- Matching: FLANN-based matcher with ratio test (0.75)
- Validation: Homography with RANSAC, minimum 6 inliers
- Rotation Handling: Tests 0°, 90°, 180°, 270° rotations
- Optimization: Early stopping when confidence exceeds threshold
- First Cell Detection: <1 second (fast auto-detect)
- Full Map Detection: 2-5 seconds (background, progressive updates)
- Multi-threading: Parallel cell matching for speed
- Caching: Results cached for 15 minutes to avoid re-detection
We welcome contributions! There are several ways to help:
Help expand map coverage by contributing templates for new maps. See CONTRIBUTING.md for detailed instructions.
We need help with translations! Current location names are basic/automatic and need improvement.
To contribute translations (just change your game language and record the names!):
- Find translation files in
maps/[MapName]/names.json - Add or improve translations for your language:
{ "en": {"CellName": "English Name"}, "zh": {"CellName": "中文名称"}, "es": {"CellName": "Nombre en Español"} } - Submit a pull request
Supported languages:
- English (
en) - Chinese (
zh) - Spanish (
es) - And more! (Use ISO 639-1 codes)
See maps/TRANSLATION_GUIDE.md for more details.
Open an issue on GitHub with your bug report or feature suggestion.
See CONTRIBUTING.md for:
- Development setup
- Building executables
- Code guidelines
- Pull request process
MIT License - See LICENSE file for details
- Built for the Dark and Darker community
- Uses OpenCV for computer vision
- ORB feature detection for robust matching
For issues or questions:
- Open an issue on GitHub
- Check existing issues for solutions
- Review the troubleshooting section above

