127 lines
4.4 KiB
Markdown
127 lines
4.4 KiB
Markdown
# 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
|