initial commit: classic-only M+ planner with upreza-derived maps

This commit is contained in:
2026-04-25 21:39:15 +02:00
commit aa1cd9ee40
11 changed files with 11732 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
# mplus-routes
Mythic+ route planner targeted at `mplus.exil.es` (Ascension community).
Static web app: pick a dungeon, see the 4K AI-upscaled map with boss
positions, click to drop waypoints/pull markers, draw a route, share via
URL hash.
## Data sources
- **Boss coords:** AtlasLootAscension `MapData.lua` (vanilla / TBC / WotLK
data files), exported by `bisbeard/export_atlasloot_maps.lua`
`data/atlasloot_maps.json`.
- **Dungeon maps:** [keyboardturner/WoWMapUprez_Dungeons][uprez] —
AI-upscaled (SRCNN) ~4K dungeon maps for every WoW expansion. Tiles are
4×3 grids of 1024×1024 BLPs that we stitch into 4096×3072 PNGs.
[uprez]: https://github.com/keyboardturner/WoWMapUprez_Dungeons
## Stack
- **Frontend:** vanilla HTML/CSS/JS, single page, no build step. Pan/zoom
via CSS transform on the canvas stage; all overlays drawn into an SVG
matching the map's image-pixel coord space.
- **Build pipeline:** Python + Pillow (uses Pillow's native BLP decoder).
- **Hosting:** static. ~260 MB of WebPs total — drop behind any nginx /
CDN. No backend.
## Layout
```
mplus-routes/
├── data/
│ ├── uprez/ # sparse-clone of WoWMapUprez_Dungeons
│ ├── atlasloot_maps.json # boss coords by MapName
│ └── aliases.json # AtlasLoot id → uprez basename overrides
├── tools/
│ ├── stitch_uprez.py # BLP tiles → 4096×3072 WebP per floor
│ └── build_data.py # combine into web/assets/dungeons.json
└── web/
├── index.html
├── style.css
├── app.js
└── assets/
├── dungeons.json # combined data feeding the UI
└── maps/ # per-dungeon WebP files served to browsers
```
## Build
```bash
python3 -m venv .venv
.venv/bin/pip install Pillow
# 1. (one-time) sparse-clone the uprez map pack into data/uprez/
git clone --depth=1 --no-checkout https://github.com/keyboardturner/WoWMapUprez_Dungeons.git data/uprez
cd data/uprez && git sparse-checkout init --cone && git sparse-checkout set "Interface/Worldmap" && git checkout && cd ../..
# 2. stitch BLP tiles → WebP (parallel, ~2 minutes on a modern laptop)
.venv/bin/python tools/stitch_uprez.py --no-png
# 3. combine boss coords + map index → dungeons.json
.venv/bin/python tools/build_data.py
```
`stitch_uprez.py --max-width 2048` halves output size if 4K is overkill.
## Run locally
```bash
cd web && python3 -m http.server 8765
# http://localhost:8765/
```
## Hosting
The whole `web/` directory is fully static.
- **Domain:** `mplus.exil.es`
- **TLS:** wildcard via the cluster's existing edge (Caddy / Traefik / certbot).
- **Backend:** none — routes encode into `#<base64>` for sharing.
A short-URL service is a clean follow-up if shareable `/r/<slug>` URLs
become wanted (KV-backed Cloudflare Worker would be enough).
## Refresh data sources
- **AtlasLoot coords:** re-export with `lua5.4 ../bisbeard/export_atlasloot_maps.lua > data/atlasloot_maps.json`
after AtlasLootAscension updates.
- **Maps:** `cd data/uprez && git pull` then re-run `stitch_uprez.py`
+ `build_data.py` after upstream uprez updates.
## Attribution
Map textures derived from [WoWMapUprez_Dungeons][uprez].
World of Warcraft trademarks belong to Blizzard Entertainment.
This site is not affiliated with Blizzard.
## Known gaps
- AtlasLootAscension's WotLK `MapData.lua` has a known upstream bug where
every dungeon's `MapName` is `"DireMaul"` — we ignore `MapName` for
resolution and use the AtlasLoot dungeon-id (with explicit aliases as
needed) instead.
- A handful of dungeons in AtlasLoot don't have a corresponding upreza
texture (e.g. SerpentshrineCavern interior) — those land in the
picker without a map and can still be used for blank-canvas routing.
- No trash-pull data — coords are boss-only. Trash groups are authored
by hand using the Pull tool.
- Multi-floor dungeons currently put all bosses into `unassignedBosses`
rather than mapping each pin to its specific floor. Floor-assignment
is a follow-up tool.