# Cursebreaker Interactive Map An interactive web-based map viewer for "The Black Grimoire: Cursebreaker" game, built with Rust (Axum) and Leaflet.js. ## Features - **Optimized Tile Loading**: Uses merged tiles to reduce HTTP requests - Zoom level 0: ~31 tiles (4×4 merged) - Zoom level 1: ~105 tiles (2×2 merged) - Zoom level 2: ~345 tiles (original tiles) - **Lossless Compression**: All tiles use lossless WebP for optimal quality - **High-Performance Rendering**: Serves tiles directly from SQLite database - **Interactive Navigation**: Pan and zoom through the game world - **Dark Theme UI**: Game-themed dark interface with collapsible sidebar - **Real-time Coordinates**: Display tile and pixel coordinates while hovering ## Architecture ### Backend (Rust + Axum) - **Tile Server**: Serves WebP-compressed map tiles from SQLite database - **API Endpoints**: - `GET /api/tiles/:z/:x/:y` - Retrieve tile at coordinates (x, y) and zoom level z - `GET /api/bounds` - Get map bounds (min/max x/y coordinates) - `GET /` - Serve static frontend files ### Frontend (Leaflet.js) - **Image Overlay Layer**: Each merged tile is rendered as a positioned image overlay - **Merged Tile System**: Reduces HTTP requests by merging tiles at lower zoom levels: - Zoom 0: 4×4 original tiles merged into 512px images (~31 total requests) - Zoom 1: 2×2 original tiles merged into 512px images (~105 total requests) - Zoom 2: Original 512px tiles (1×1, ~345 total requests) - **Fixed Coordinate System**: Uses Leaflet's CRS.Simple with tiles positioned at their exact pixel coordinates ## Prerequisites - Rust (latest stable) - SQLite database at `../cursebreaker.db` with `minimap_tiles` table populated ## Running the Map Viewer ### First Time Setup 1. **Generate all map tiles** (only needed once, or after updating minimap images): ```bash cd cursebreaker-parser cargo run --bin image-parser --release ``` This processes all PNG files and automatically generates all 3 zoom levels (takes ~1.5 minutes) 2. **Start the map server**: ```bash cd ../cursebreaker-map cargo run --release ``` 3. **Open in browser**: Navigate to `http://127.0.0.1:3000` ### Subsequent Runs Just start the server (step 2 above). All tiles are stored in the database. ## Database Configuration By default, the server looks for the database at `../cursebreaker.db`. You can override this with the `DATABASE_URL` environment variable: ```bash DATABASE_URL=/path/to/cursebreaker.db cargo run --release ``` ## Future Enhancements The sidebar includes placeholders for upcoming features: - **Icon Filtering**: Toggle visibility of shops, resources, fast travel points, workbenches, etc. - **Map Markers**: Display game entities (shops, resources, NPCs) with clickable info popups - **Search**: Find locations by name - **Pathfinding**: Calculate routes between points - **Layer Control**: Toggle different map overlays ## Project Structure ``` cursebreaker-map/ ├── Cargo.toml # Rust dependencies ├── src/ │ └── main.rs # Axum web server ├── static/ │ ├── index.html # Main HTML page │ ├── style.css # Styling (dark theme) │ └── map.js # Leaflet map initialization └── README.md ``` ## Performance Notes - **Merged Tiles**: Reduces HTTP requests by up to 91% at lowest zoom (31 vs 345 requests) - **Lossless WebP**: High quality compression without artifacts - **Database Storage**: All tiles served directly from SQLite BLOBs (no file I/O) - **CRS.Simple**: Avoids expensive geographic coordinate projections - **Total Storage**: ~111 MB for all zoom levels combined ### Load Performance Comparison | Zoom Level | Merge Factor | Tiles Loaded | HTTP Requests Saved | |------------|--------------|--------------|---------------------| | 0 (zoomed out) | 4×4 | 31 | 91% fewer requests | | 1 (medium) | 2×2 | 105 | 70% fewer requests | | 2 (zoomed in) | 1×1 | 345 | baseline | ## Troubleshooting **Tiles not loading**: - Verify database path is correct - Check that `minimap_tiles` table is populated - Look for errors in server console output **Map appears blank**: - Check browser console for JavaScript errors - Verify `/api/bounds` returns valid coordinates - Ensure tiles exist for the displayed coordinate range **Performance issues**: - Try running in release mode: `cargo run --release` - Check database is on fast storage (SSD) - Reduce browser zoom level to load lower-resolution tiles