janhouse 9f6b0772f0
Build / build (push) Successful in 3m6s
mapsyncer-paper 0.2.0: Paper 26.3
Build against the 26.3 dev bundle (26.3.build.151-beta; no stable build
exists yet).

26.3 rewrote the block palette in region files: a default-state block is a
bare string, any other state is {id, properties}, and a list mixing both
wraps the strings as {"": name}. The parser cast every entry to a
compound with Name/Properties, so every chunk saved by 26.3 threw
ClassCastException and the whole region failed to render. Both formats are
read now (a region holds a mix until every chunk is re-saved), and a chunk
that fails to parse is skipped instead of aborting the region.
2026-10-04 18:18:09 +03:00
2026-10-04 18:18:09 +03:00
2026-10-04 18:18:09 +03:00
2026-10-04 18:18:09 +03:00

mapsyncer-paper

The server half of MapSyncer for Xaero's World Map, as a Paper plugin — with one twist: the map players receive is built from what players have actually discovered, not from every chunk the server has ever generated.

Players run the stock MapSyncer client mod (Fabric or NeoForge, same Minecraft version as the server) next to Xaero's World Map. The plugin speaks the mod's wire protocol byte for byte, so nothing on the client needs patching.

What it does

  1. Tracks discovery. Every chunk the server sends to a player is recorded for that player (PlayerChunkLoadEvent). That is exactly the set Xaero's client maps on its own, so the server's picture of a region is always a superset of the player's — which matters, because the client mod overwrites region files wholesale.
  2. Seeds history once. On first start the plugin scans each world's region files and marks chunks with InhabitedTime > 0 as discovered. Pre-generated terrain (Chunky, distant-terrain LOD generation) has InhabitedTime = 0 and stays hidden until somebody walks there.
  3. Renders on demand. A region is converted from its .mca file into a Xaero region zip only for the discovered chunks; everything else becomes a "no data" tile. Re-rendering happens when the region file changes or the discovery mask grows.
  4. Streams to the mod. On join the client gets a hello, polls periodically, and receives whatever changed since it last asked, hash- and timestamp-checked per region layer.

Two visibility modes (config.yml):

visibility Player receives
shared (default) the union of everyone's discoveries
own only what they discovered themselves, plus the seeded history

Requirements

  • Paper 26.3 on Java 25 (the build compiles against Paper's Mojang-mapped internals via paperweight; other versions need a rebuild).
  • Clients: Xaero's World Map 1.40.11+ and the MapSyncer client mod for the same Minecraft version.
  • Xaero's Multiplayer world map setting should be Single. The client mod writes into the newest mw$… folder; Xaero's "world spawn" mode uses folders without the $ and would never see the synced files.

Install

Drop the jar from the latest release into plugins/, start the server, read the generated plugins/MapSyncer/config.yml. The first start scans every tracked world once (a few minutes for a multi-gigabyte world, in the background); nothing is served until the first render cycle after that.

Dimension folders on the client follow Xaero's own naming: vanilla keys map to null, DIM-1, DIM1; anything else, including Multiverse worlds, to namespace$path (e.g. minecraft$survival).

Commands

/mapsync status            counters: discovery, cache, syncs, clients with the mod
/mapsync worlds            per-world mapping, layers, region directory
/mapsync render [force]    run a render cycle now; force drops the cache first
/mapsync seed <world|all>  re-run the InhabitedTime scan
/mapsync player <name>     what one player has discovered
/mapsync reload            re-read config.yml

Permission mapsyncer.admin (default: op).

Data

Everything lives under plugins/MapSyncer/:

discovery/<world>.bin           discovery bitmaps (per region: union, seeded, per player)
cache/<scope>/<dim>/[caves/<L>/]<x>_<z>.zip   rendered regions; scope = shared or a player UUID
cache/<scope>/index.tsv         timestamps, CRC32s, content stamps

Deleting cache/ is always safe (it is rebuilt). Deleting discovery/ loses who-discovered-what; the next start re-seeds from InhabitedTime.

Building

./gradlew build          # runs the unit tests; jar in build/libs/mapsyncer-paper-<version>.jar

CI (.gitea/workflows/build.yml) builds on every push and attaches the jar to a release for every v* tag.

Licence

GPL-3.0. The Xaero region writer and MCA parser are vendored from MapSyncer (GPL-3.0); see NOTICE.md for the exact provenance and the local changes.

S
Description
Paper plugin: server side of MapSyncer for Xaero World Map, limited to what players discovered
Readme GPL-3.0
211 KiB
0 Stars 1 Watchers 0 Forks
v0.2.0
Latest
2026-10-04 15:48:31 +00:00
Languages
Java 100%