# MCMapper-Backend Map-render backend for [MCMapper-Mod](https://git.octoturge.com/octoturge/MCMapper-Mod). Does all the heavy lifting a thin in-game mod shouldn't: persists world state, renders 2D tiles and 3D meshes, relays chat, and serves the web map viewer — instead of the MC server itself burning CPU/RAM on rendering the way Bluemap/Dynmap do. ## Services Three independently-deployable services, each its own docker-compose service: - `api/` — ElysiaJS on Bun. The I/O layer: WS gateway for mod connections, chat relay, chunk store, marker/waypoint sharing, admin config, region export, tile/mesh serving. - `worker/` — Rust. CPU-bound rendering: tile rasterization and chunk meshing, consumed off a Redis dirty-chunk stream. Stateless — scale it with `docker compose up --scale worker=N`, or run instances on separate hardware pointed at the same Postgres/Redis/MinIO over a private network. Rendering strategy (`cpu`/`gpu`/`hybrid`) is config-selectable behind a `RenderBackend` trait; only `cpu` (rayon) exists so far — `gpu`/`hybrid` (wgpu) land in Phase 8. - `frontend/` — ElysiaJS + Pug + Tailwind 4 + Alpine.js. The public-facing pages (map viewer, chat, admin panel). Stateless — no DB access, calls `api` for anything server-rendered; the browser's own live map/chat/tile traffic talks to `api` directly, not proxied through here. Plus `postgres` (source chunk data, accounts, chat history, config, render-artifact metadata pointers), `redis` (dirty-chunk queue, pub/sub, link-code TTLs), `minio` (S3-compatible object storage for the actual rendered tile PNGs and mesh binaries — kept out of Postgres so backups stay free of large binaries and remote `worker` instances have a shared place to write output), and `caddy` (reverse proxy: `/ws` + `/api/*` → `api`, everything else → `frontend`). Postgres/Redis/MinIO are never exposed publicly — only reachable on the compose network or a private network (VPN/Tailscale/LAN) for remote `worker` instances. ## Running ``` docker compose up ``` `api` on :3000, `frontend` on :3001, both behind Caddy on :80. First boot pulls/builds all images; `worker` starts polling an empty Redis stream until Phase 1 gives it something to do. ## Attribution See `THIRD_PARTY_NOTICES.md`.