Files
cursebreaker-parser-rust/cursebreaker-map/README.md
2026-01-11 02:46:49 +00:00

4.4 KiB
Raw Blame History

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):

    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:

    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:

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