aa1cd9ee40278930982cc1e849065caf7ce2938f
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 bybisbeard/export_atlasloot_maps.lua→data/atlasloot_maps.json. - Dungeon maps: keyboardturner/WoWMapUprez_Dungeons — 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.
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
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
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.jsonafter AtlasLootAscension updates. - Maps:
cd data/uprez && git pullthen re-runstitch_uprez.pybuild_data.pyafter upstream uprez updates.
Attribution
Map textures derived from WoWMapUprez_Dungeons. World of Warcraft trademarks belong to Blizzard Entertainment. This site is not affiliated with Blizzard.
Known gaps
- AtlasLootAscension's WotLK
MapData.luahas a known upstream bug where every dungeon'sMapNameis"DireMaul"— we ignoreMapNamefor 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
unassignedBossesrather than mapping each pin to its specific floor. Floor-assignment is a follow-up tool.
Description
Languages
Python
46.6%
JavaScript
40.9%
CSS
9.4%
HTML
3.1%