No description
  • TypeScript 68.5%
  • mcfunction 29.8%
  • Shell 1.7%
Find a file
blue f7f0dbb404
All checks were successful
CI / Lint and typecheck (push) Successful in 4s
silly test case fix
2026-07-17 14:52:32 +02:00
.forgejo/workflows no compilation, different user 2026-07-14 18:50:32 +02:00
assets/markers Reworked the icons 2026-07-17 14:49:34 +02:00
datapack Reworked the icons 2026-07-17 14:49:34 +02:00
packaging/Archlinux Marker new features 2026-07-17 12:45:03 +02:00
src Reworked the icons 2026-07-17 14:49:34 +02:00
test silly test case fix 2026-07-17 14:52:32 +02:00
biome.json First commit 2026-07-14 17:02:55 +02:00
bun.lock First commit 2026-07-14 17:02:55 +02:00
LICENSE First commit 2026-07-14 17:02:55 +02:00
package.json logs and restructuring a bit 2026-07-14 19:18:53 +02:00
README.md Remade marker api 2026-07-17 13:24:34 +02:00
tsconfig.json logs and restructuring a bit 2026-07-14 19:18:53 +02:00

bluemap-telemetry

Standalone Minecraft player telemetry daemon. It connects to a Minecraft server over RCON, polls online player positions on a fixed interval, and writes players.json into each configured map directory under a web root.

The daemon is not a BlueMap plugin or package dependency. It produces plain JSON files on disk that any web map (or other consumer) can read. BlueMap is one such consumer: when configured to load live/players.json from each map directory, BlueMap can display live player markers.

How it works

  1. Connect to the Minecraft server via RCON.
  2. Run list uuids and, for each online player, fetch Pos, Rotation, and Dimension via data get entity "<name>" ….
  3. For each map in MAPS, filter players by dimension and write the matching subset to {WEB_ROOT}/{map}/live/players.json.
  4. Default map names (overworld, nether, end) map to Minecraft dimensions automatically — no MAP_DIMENSIONS env var required. Use MAP_DIMENSIONS only for custom map names or to override those defaults.
  5. On RCON failure, write an empty players array so consumers clear stale player markers.
  6. When the optional marker datapack is enabled, fetch storage bluemap-telemetry:data markers and write per-map live/markers.json.
  7. Repeat every INTERVAL milliseconds.

On startup the daemon ensures {WEB_ROOT}/{map}/live/ exists and seeds markers.json only when the file is missing.

Optional marker datapack

The repository includes an optional vanilla datapack under [datapack/](datapack/) for in-game map markers. Ops store POIs in command storage; the daemon reads that storage over RCON each poll and writes live/markers.json per map.

Enable it by copying the datapack into the world's datapacks folder. Since Minecraft 1.20+, symlinks inside a world are rejected unless explicitly whitelisted in allowed_symlinks.txt at the server root — copying avoids that.

# From a git checkout
cp -a datapack /path/to/world/datapacks/bluemap-telemetry

# Arch Linux package
cp -a /usr/share/bluemap-telemetry/datapack /path/to/world/datapacks/bluemap-telemetry

Re-run the copy after upgrading bluemap-telemetry to pick up datapack changes.

Optional: symlink with allowed_symlinks.txt

If you prefer a symlink (updates automatically on package upgrade), allow it in the server root (same directory as server.jar, not inside the world):

echo '[prefix]/usr/share/bluemap-telemetry' >> /srv/minecraft/allowed_symlinks.txt
ln -s /usr/share/bluemap-telemetry/datapack /srv/minecraft/world/datapacks/bluemap-telemetry

Without that file, the server fails at startup with ContentValidationException: Found forbidden symlinks.

Then run /reload in-game (op) or restart the server.

Open the marker menu (op, as a player):

/function bluemap-telemetry:marker

Or bind Quick Actions in Controls (menu is in #minecraft:quick_actions). Dialogs: Add / List / Update / Rename / Delete / Pin. CRUD also lives under bluemap-telemetry:marker/* with required macro args — see datapack/README.md.

Typed markers need icons served by the web server. Symlink them once into the BlueMap web root (next to index.html, not into BlueMaps assets/):

ln -s /usr/share/bluemap-telemetry/assets/markers /srv/http/bluemap-telemetry
# from a git checkout: ln -s /path/to/repo/assets/markers /srv/http/bluemap-telemetry

Set MARKER_ICON_BASE=bluemap-telemetry in the daemon config (the default). The daemon does not copy icons at runtime; package upgrades update the share directory and the symlink keeps working. Empty type keeps BlueMaps built-in assets/poi.svg.

Verify storage:

/data get storage bluemap-telemetry:data

After the next daemon poll, check {WEB_ROOT}/{map}/live/markers.json for the matching dimension. BlueMap refreshes live markers about every 10 seconds.

See [datapack/README.md](datapack/README.md) for layout and requirements (Minecraft Java 26.2+).

Requirements

  • Bun 1.0+
  • A Minecraft server with RCON enabled
  • A writable map web root with one subdirectory per map (for example /srv/http/maps/overworld)

Build from source

git clone https://git.macaw.me/blue/bluemap-telemetry
cd bluemap-telemetry
bun install
bun run start

For development with auto-reload:

bun run dev

Output format

Each map directory receives the same schema at {WEB_ROOT}/{map}/live/players.json:

{
  "players": [
    {
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Steve",
      "foreign": false,
      "position": { "x": 12.5, "y": 64.0, "z": -8.25 },
      "rotation": { "pitch": 0, "yaw": 0, "roll": 0 }
    }
  ]
}
Field Type Description
players array Online players included for this map
players[].uuid string Player UUID from list uuids
players[].name string Player display name
players[].foreign boolean Always false for players on this server
players[].position object World coordinates (x, y, z)
players[].rotation object View angles (pitch, yaw, roll) from RCON; falls back to zero if parsing fails

Each map's players.json contains only players whose current dimension matches that map. Default map names (overworld, nether, end) are filtered automatically; see MAP_DIMENSIONS below for custom names or overrides.

Environment variables

Variable Default Description
RCON_HOST 127.0.0.1 Minecraft server RCON host
RCON_PORT 25575 RCON TCP port
RCON_PASS (required) RCON password
WEB_ROOT /srv/http/maps Web root containing per-map subdirectories
MAPS overworld,nether,end Comma-separated map directory names under WEB_ROOT
INTERVAL 5000 Poll interval in milliseconds (minimum 1000)
MARKER_ICON_BASE bluemap-telemetry Web-relative path to marker icons (see below)
MAP_DIMENSIONS (optional) Override or extend per-map dimension filters; see below
CONFIG_PATH (optional) Path to a .env-style or JSON config file

Example:

export RCON_HOST=127.0.0.1
export RCON_PORT=25575
export RCON_PASS=your-rcon-password
export WEB_ROOT=/srv/http/maps
export MAPS=overworld,nether,end
export INTERVAL=5000
export MARKER_ICON_BASE=bluemap-telemetry
bun run start

Marker icons

Typed markers reference {MARKER_ICON_BASE}/{type}.svg (for example bluemap-telemetry/home.svg).

Important:

  • That URL is relative to the BlueMap web root (the directory that contains index.html), not WEB_ROOT (map data folders).
  • Do not put them under BlueMaps own assets/ directory — use a separate path so upgrades never collide.
  • The daemon never copies icon files; it only writes the URL into markers.json.

Ship icons live in assets/markers/ (package: /usr/share/bluemap-telemetry/assets/markers/). Symlink them once:

# If BlueMaps web UI is served from /srv/http (adjust to your web root)
ln -s /usr/share/bluemap-telemetry/assets/markers /srv/http/bluemap-telemetry

Then keep MARKER_ICON_BASE=bluemap-telemetry in config (default). If you use a different link name, set MARKER_ICON_BASE to match. Package upgrades refresh /usr/share/.../assets/markers; the symlink keeps working.

MAP_DIMENSIONS

Optional mapping from map name to Minecraft dimension identifier. Each map's players.json lists only players currently in that dimension.

The default map names in MAPS already map to dimensions without this variable:

Map name Default dimension
overworld minecraft:overworld
nether minecraft:the_nether
end minecraft:the_end

Set MAP_DIMENSIONS when you use custom map directory names, or when you need to override a default mapping (for example a non-standard nether map name).

Format: comma-separated map:dimension pairs.

Example (custom map name):

MAPS=overworld,nether_map,end
MAP_DIMENSIONS=nether_map:minecraft:the_nether

Map names must match entries in MAPS. Every map listed in MAPS must resolve to a dimension — either via a default name or an entry in MAP_DIMENSIONS.

Enabling RCON on Arch Linux Minecraft server

RCON is configured in server.properties. This file lives in the server data directory (where eula.txt and world saves are stored), not in the package install path. The exact path depends on how you installed and run the server, but the properties themselves are the same for vanilla, Paper, and Spigot.

Edit server.properties

After the server has been started at least once, open server.properties and set:

enable-rcon=true
rcon.port=25575
rcon.password=choose-a-strong-password
broadcast-rcon-to-ops=false
Property Value Notes
enable-rcon true Required; RCON does not start when false
rcon.port 25575 Default TCP port; change only if you need a non-default port
rcon.password non-empty string Required; blank password prevents RCON from starting
broadcast-rcon-to-ops false Recommended; keeps RCON command output out of in-game op chat

Common Arch installations

Installation Where to find server.properties
minecraft-server (AUR) Server data directory configured for the package (commonly under /srv/minecraft or a path set in the unit/env file)
Paper / Spigot (AUR, e.g. paper, spigot) The directory from which the server JAR is launched — the same folder that contains eula.txt after first run
Manual / custom install Your chosen server working directory

If unsure of the path, search from the service unit or launch script: systemctl cat <minecraft-service> often shows WorkingDirectory= or the data path.

Firewall and remote RCON

When the telemetry daemon runs on the same host as the Minecraft server, bind RCON to localhost and point RCON_HOST at 127.0.0.1. No firewall changes are needed.

When the daemon runs on a different host, allow inbound TCP to rcon.port only from the telemetry machine's IP (for example with ufw or iptables). RCON is not encrypted; avoid exposing it to the public internet.

Restart after changes

server.properties is read at server startup. After editing RCON settings, restart the Minecraft server.

For a systemd-managed service:

sudo systemctl restart <minecraft-service>

Replace <minecraft-service> with your unit name (for example minecraft-server, minecraft@survival, or a custom instance).

Scripts

Script Description
bun run start Run the telemetry daemon
bun run dev Run with file watch / reload (development)
bun run typecheck Type-check with TypeScript
bun run test Run parser and config unit tests
bun run lint Lint and format check (Biome)

Deployment

Arch Linux (AUR)

Install bluemap-telemetry from the AUR. The package depends on bun and installs the application to /usr/lib/bluemap-telemetry/.

# Edit RCON credentials, WEB_ROOT, and (if using typed markers) MARKER_ICON_BASE
sudo nano /etc/bluemap-telemetry/config.env

# Grant the minecraft user write access to your map web root
sudo usermod -aG http minecraft   # example: add to the http group

# Optional: typed marker icons — once, next to BlueMaps index.html (not assets/)
sudo ln -s /usr/share/bluemap-telemetry/assets/markers /srv/http/bluemap-telemetry

sudo systemctl enable --now bluemap-telemetry.service
journalctl -u bluemap-telemetry.service -f

Packaging files live in packaging/Archlinux/. The package installs the optional datapack to /usr/share/bluemap-telemetry/datapack/ and marker icons to /usr/share/bluemap-telemetry/assets/markers/. Publishing a Forgejo release triggers the AUR workflow (requires DEPLOY_TO_AUR_* repository secrets). Release tags may use a v prefix (for example v1.0.0); the AUR pkgver is published without it.

systemd

The unit runs as the minecraft system user (provided by your Minecraft server package, e.g. minecraftd), loads /etc/bluemap-telemetry/config.env, and runs bun run src/main.ts from /usr/lib/bluemap-telemetry. Logs go to stdout/stderr for the journal. All application output uses [info], [warn], and [error] prefixes.

License

MIT — see LICENSE.