Skip to main content

Minecraft Worlds

Quickstart: Bring a World Up

  1. Create via Web Control Plane (https://mc.drheck.dev) or CLI (ipctl):

    • Web UI (Recommended): Open https://mc.drheck.dev, click + New World, style the world name/MOTD and 64×64 icon, preview/reroll the world seed with the live 2D biome map, and click Create & Provision World.
    • CLI (ipctl):
      sudo /data/minecraft/ipctl create <name> --dns
      
      (Allocates backend IPv6 fd77:7777:5010::1337:3c:d00d:<hex>/64 in /etc/systemd/network/20-wired.network.d/minecraft.conf, configures HAProxy SNI routing in /etc/haproxy/conf.d/minecraft_backends.cfg and /etc/haproxy/minecraft_hosts.map, adds <name>.drheck.dev to /var/unbound/etc/unbound.minecraft.conf on danknasty using a short-lived 5-minute step-ca SSH user certificate, and syncs public A/AAAA records to deSEC.io).
  2. Configure the backend server: In your backend server's server.properties:

    server-ip=fd77:7777:5010::1337:3c:d00d:<hex>
    server-port=25565
    online-mode=true
    

    (Backend servers run with online-mode=true, listening on standard port 25565 on their dedicated ULA IPv6 address).

  3. Start the server: Start via https://mc.drheck.dev (Start button or automatic On-Demand wake-on-join) or sudo systemctl start minecraft@<slug>.service.

  4. Connect: Players connect using <name>.drheck.dev (standard port 25565). Microsoft account authentication takes place directly between the client and the backend server.


Quickstart: Take a World Down

  1. Stop the backend server: Click Stop in https://mc.drheck.dev, send stop in the live web console, or run sudo systemctl stop minecraft@<slug>.service.

  2. What Players See When Offline or Standby (On-Demand): HAProxy intercepts all Multiplayer Server List pings ($\text{state} = 1$) and offline/standby Login joins ($\text{state} = 2$) via /etc/haproxy/minecraft.lua and mc-manager:

    • In the Multiplayer Server List (state = 1): Returns the server's configured custom MOTD and 64×64 server-icon.png (favicon) immediately, with version status badge Standby (Join to Wake) (for ondemand servers) or Offline (for manual servers).
    • When Clicking "Join Server" (state = 2):
      • ondemand Standby: Automatically triggers minecraft@<slug>.service to boot and displays a gold countdown screen (Waking up <Server>... Ready in ~20s!).
      • manual Offline: Immediately disconnects with a clean red screen (<Server> is currently offline. Start at mc.drheck.dev).
  3. Disable or remove router mapping & DNS (Teardown):

    • Temporary takedown (disable in router only):
      sudo /data/minecraft/ipctl route disable <name>
      
    • Complete teardown (release IP, remove HAProxy route, purge DNS):
      sudo /data/minecraft/ipctl delete <name> --dns
      

Architecture & Design Details

1. Unified Endpoint Model

All public and LAN client connections resolve to the single Minecraft Router endpoint pair:

  • IPv4: 10.0.0.113 (NAT port-forwarded from WAN IPv4 :25565 on danknasty)
  • IPv6: fd77:7777:5010::1337:f1ac:d00d:3c (dynamically mapped to GUA <gua_prefix>:1337:f1ac:d00d:3c in public DNS)

Whether connecting via pokelovers.drheck.dev, desertworld.drheck.dev, or any other server subdomain, players connect to this exact IP pair on standard port 25565.

2. Transparent TCP SNI Handshake Routing & Live Ping Injection (HAProxy + mc-manager)

Rather than using an application-level proxy (which breaks vanilla Diffie-Hellman encryption and forces online-mode=false), HAProxy performs transparent pre-handshake packet inspection:

  1. HAProxy listens dual-stack on 10.0.0.113:25565 and [fd77:7777:5010::1337:f1ac:d00d:3c]:25565.
  2. When a player connects, HAProxy peeks at the initial unencrypted Minecraft handshake packet (0x00) via /etc/haproxy/minecraft.lua and extracts the requested hostname (txn.mc_host, e.g. pokelovers.drheck.dev) and handshake state (txn.mc_state: 1 = Status Ping, 2 = Login Join).
  3. For All Multiplayer Server List Pings ($\text{state} = 1$): Each backend uses the rule:
    tcp-request content use-service lua.mc_offline if { var(txn.mc_state) -m int eq 1 } || !{ nbsrv(<slug>) gt 0 }
    
    lua.mc_offline queries mc-manager (http://127.0.0.1:8095/internal/haproxy with STATUS <slug>). If the backend JVM is running, mc-manager queries the backend's live TCP status (0x00) to obtain real-time online player counts and version metadata, then overlays the latest motd from server.properties and favicon from /data/minecraft/<dir>/server-icon.png. This ensures MOTD styling and 64×64 icon changes saved in mc.drheck.dev appear immediately on client Refresh without restarting a running Minecraft server.
  4. For Player Login Joins ($\text{state} = 2$):
    • If the backend server is UP: HAProxy splices the raw TCP stream directly to [fd77:7777:5010::1337:3c:d00d:<hex>]:25565. The client and backend perform native Microsoft/Mojang online-mode=true authentication directly over the spliced TCP connection.
    • If the backend server is DOWN: lua.mc_offline sends JOIN <slug> to mc-manager, which wakes ondemand servers automatically and returns a formatted Minecraft Disconnect packet (0x00).

3. Backend IPv6 Address Scheme & Active Worlds

Each backend Minecraft server is isolated on a dedicated Unique Local Address (ULA) on interface eth77 of ul:

  • Prefix: fd77:7777:5010::1337:3c:d00d:<hex>/64
  • Port: Each server binds to standard port 25565 on its assigned IPv6 address.
  • Active Managed Worlds:
Hex ID Slug / Subdomain Display Name Backend ULA IPv6 Address Lifecycle Mode
1 pokelovers.drheck.dev Poke Lovers fd77:7777:5010::1337:3c:d00d:1/64 ondemand (20G heap)
2 desertworld.drheck.dev ⚔ 𝔇𝔢𝔰𝔢𝔯𝔱 𝔚𝔬𝔯𝔩𝔡 ⚔ fd77:7777:5010::1337:3c:d00d:2/64 ondemand (8G heap)

4. Web Map (BlueMap) & Authentik Gated HTTPS

Interactive 3D web mapping for Minecraft is powered by BlueMap running in standalone watch mode:

  • Service: bluemap-pokelovers.service running from /data/minecraft/poke lovers/bluemap.
    • Automatically updates the rendered 3D map as chunks change in /data/minecraft/poke lovers/world.
    • Serves live map data & Server-Sent Events (SSE) updates on internal port 8100.
  • Reverse Proxy & Authentication: NGINX terminates SSL on port 443 at /etc/nginx/sites-available/pokelovers and gates access behind Authentik ForwardAuth (/outpost.goauthentik.io/auth/nginx).
    • Serves directly at https://pokelovers.drheck.dev.
    • Unauthenticated visitors are automatically redirected to auth.drheck.dev to log in before viewing the 3D map.

5. Network & DNS Automation (ipctl) — Externalized Configs & Short-Lived SSH CA

To prevent dynamic Minecraft world provisioning from mutating code-reviewed host and router configuration files (/etc/systemd/network/20-wired.network, /etc/haproxy/haproxy.cfg, and /home/luke/git/router_config/unbound.conf), /data/minecraft/ipctl (symlinked at /home/luke/bin/ipctl) operates exclusively on dedicated external drop-in and include files:

Subsystem Static Code-Reviewed Base Config (Never Modified by ipctl) Dynamic External File Managed by ipctl Mirror in /data/minecraft/.network/
systemd-networkd (ul) /etc/systemd/network/20-wired.network /etc/systemd/network/20-wired.network.d/minecraft.conf minecraft.network.conf
HAProxy Map (ul) /etc/haproxy/haproxy.cfg /etc/haproxy/minecraft_hosts.map minecraft_hosts.map
HAProxy Backends (ul) /etc/haproxy/haproxy.cfg (loads -f /etc/haproxy/conf.d) /etc/haproxy/conf.d/minecraft_backends.cfg minecraft_backends.cfg
Unbound DNS (danknasty) /home/luke/git/router_config/unbound.conf (has include: "/var/unbound/etc/unbound.minecraft.conf") /var/unbound/etc/unbound.minecraft.conf unbound.minecraft.conf

Programmatic Short-Lived SSH CA Authentication (step-ca $\longrightarrow$ danknasty)

When /data/minecraft/ipctl is invoked with --dns (either interactively or unattended by mc-manager.service after a reboot when no ssh-agent is active):

  1. ipctl generates a fresh ephemeral Ed25519 keypair in a mode-0700 temporary directory (atexit-cleaned).
  2. ipctl requests a 5-minute (--not-after=5m) SSH user certificate for principal luke from the local step-ca container using the webshell-svc JWK provisioner (the same short-lived CA used by webshell.drheck.dev).
  3. danknasty validates the certificate against TrustedUserCAKeys /etc/ssh/drheck_ca_user_key.pub (configured in /etc/sshd_config.d/10-drheck-certs.conf), allowing ipctl to update /var/unbound/etc/unbound.minecraft.conf, run doas unbound-checkconf and doas rcctl restart unbound, and invoke /home/luke/git/router_config/dns_danger_sync.py --force to synchronize public A and AAAA records to deSEC.io.
  4. Both update_dns.py and dns_danger_sync.py (as well as verify_dns.sh) on danknasty recursively follow include: directives in unbound.conf, ensuring all external Minecraft subdomains are automatically included during prefix rotations and deSEC.io synchronization.

Backups & Disaster Recovery

Both the HAProxy router layer and the mc-manager control plane (including all external network, proxy, and DNS mirror files) are integrated into /home/luke/git/backups/ul/scripts/:

  • Control Plane & External Network Backup: /home/luke/git/backups/ul/scripts/backup/mc_manager
    • Archives /data/minecraft/.manager, /data/minecraft/.network, /data/minecraft/ipctl, /usr/local/bin/{mc-manager,mc-runner,mc-seed-render}, /etc/systemd/system/{mc-manager.service,minecraft@.service}, /etc/systemd/network/20-wired.network.d/minecraft.conf, /etc/nginx/sites-available/mc, /etc/haproxy/minecraft.lua, /etc/haproxy/minecraft_hosts.map, and /etc/haproxy/conf.d/minecraft_backends.cfg with 10% par2 parity into /data/backups/services/current/mc_manager/.
  • Control Plane Restore: /home/luke/git/backups/ul/scripts/restore/mc_manager [timestamp]
  • Router Backup & Restore: /home/luke/git/backups/ul/scripts/backup/minecraft_router and /home/luke/git/backups/ul/scripts/restore/minecraft_router [timestamp]

6. Minecraft Server Manager & On-Demand Architecture (Production Architecture)

Production Control Plane: The unified web control plane at https://mc.drheck.dev (bound to [fd77:7777:5010::1337:f1ac:d00d:3c00]:8095 behind Nginx and Authentik ForwardAuth) manages all Minecraft worlds on ul, automates ipctl networking and systemd lifecycle management, wakes sleeping servers on-demand via HAProxy when players join, streams live PTY server consoles, and provides an integrated Seed Preview Studio and Text, MOTD, Color Gradient & 8-Bit Pixel Icon Studio.

6.1 Canonical Definition of a "Server"

Every managed Minecraft world on ul is a self-contained unit consisting of five standardized components:

$$\text{Server}(\text{slug}) = \left\lbrace\text{Directory}, \quad \text{Manifest } (\texttt{server.json}), \quad \text{Network } (\texttt{ipctl}), \quad \text{Units } (\texttt{systemd}), \quad \text{Lifecycle Policy}\right\rbrace$$

Component Path / Identifier Description
1. Dedicated Directory /data/minecraft/<dir_name>/ Holds server.json, server .jar / libraries, mods/ or plugins/, server.properties, server-icon.png, whitelist.json, ops.json, world/, and optional bluemap/. Existing worlds in /data/minecraft/* can be adopted in-place without moving files.
2. Declarative Manifest /data/minecraft/<dir_name>/server.json Stores the human display name, DNS slug (<slug>), loader type (paper, vanilla, fabric, neoforge, forge, custom), Minecraft version, JVM path (/usr/lib/jvm/default/bin/java), heap size (memory_min/memory_max), seed, and start_mode (manual, ondemand, always).
3. Network & DNS (ipctl) fd77:7777:5010::1337:3c:d00d:<hex>/64 Dedicated internal IPv6 address on eth77 in /etc/systemd/network/20-wired.network.d/minecraft.conf, bound in server.properties (server-ip= and server-port=25565), mapped in /etc/haproxy/minecraft_hosts.map + /etc/haproxy/conf.d/minecraft_backends.cfg, and published as <slug>.drheck.dev in /var/unbound/etc/unbound.minecraft.conf on danknasty and deSEC.io.
4. Dedicated systemd Service & PTY Wrapper minecraft@<slug>.service (via /usr/local/bin/mc-runner) Runs the server JVM inside a managed pseudo-terminal (PTY) with a 1,000-line ring buffer and UNIX domain socket /run/mc-manager/<slug>.sock, enabling real-time WebSocket log streaming and console command injection (SendRunnerCommand) as well as graceful save-all + stop on shutdown.
5. Lifecycle Policy manual | ondemand | always Controls when the server consumes RAM on ul (see Section 6.2).
Click to expand example /data/minecraft/desertworld/server.json manifest
{
  "slug": "desertworld",
  "display_name": "⚔ 𝔇𝔢𝔰𝔢𝔯𝔱 𝔚𝔬𝔯𝔩𝔡 ⚔",
  "dir_name": "desertworld",
  "domain": "desertworld.drheck.dev",
  "ipv6": "fd77:7777:5010::1337:3c:d00d:2",
  "hex_id": "2",
  "port": 25565,
  "start_mode": "ondemand",
  "idle_timeout_minutes": 20,
  "type": "paper",
  "mc_version": "1.21.4",
  "jar_file": "server_26.3.jar",
  "java_bin": "/usr/lib/jvm/default/bin/java",
  "memory_min": "8G",
  "memory_max": "8G",
  "seed": "4900633019313953717",
  "admins": [],
  "created_at": "2026-10-10T18:03:46-04:00"
}

6.2 Resource Management & Server Lifecycle Modes

Because each active Minecraft JVM allocates $8\text{--}20\text{ GiB}$ of pinned heap memory (-Xms = -Xmx with +AlwaysPreTouch), running all $25+$ worlds in /data/minecraft simultaneously is impossible. Each server is assigned one of three lifecycle modes:

  1. manual (Cold / Archived):
    • minecraft@<slug>.service is disabled and stopped ($0\text{ GiB}$ RAM).
    • Only starts when explicitly clicked in the Web UI.
    • When stopped, HAProxy returns <name> is currently offline. Start at mc.drheck.dev.
  2. ondemand (Wake-on-Join + Idle Auto-Stop):
    • Stopped by default ($0\text{ GiB}$ RAM).
    • Automatically started when a player clicks Join Server in Minecraft (intercepted by HAProxy Lua $\longrightarrow$ mc-manager).
    • Automatically stopped (save-all $\longrightarrow$ stop) once $0$ players have been online continuously for $T_{\text{idle}}$ minutes (default $20\text{ min}$).
  3. always (Pinned Production):
    • minecraft@<slug>.service is enabled and active across host reboots (systemctl enable --now).
    • Used for primary worlds that should remain online $24/7$ regardless of player count.

6.3 HAProxy On-Demand Wake-on-Join & Live Status Ping Architecture

The Minecraft protocol sends a Handshake packet (0x00) at the start of every TCP connection containing a Next State VarInt:

  • $\text{Next State} = 1$ (Status Ping): Sent when a client refreshes their Multiplayer Server List.
  • $\text{Next State} = 2$ (Login Join): Sent only when a player clicks Join Server.

/etc/haproxy/minecraft.lua extracts both txn.mc_host and txn.mc_state and delegates status pings and offline joins to mc-manager (http://127.0.0.1:8095/internal/haproxy):

$$\text{Client Packet } (\texttt{0x00}) \longrightarrow \begin{cases} \text{state} = 1 \text{ (Status Ping)} & \longrightarrow \text{Return live JSON MOTD + } \texttt{server-icon.png} \text{ from } \texttt{mc-manager} \text{ without waking} \\ \text{state} = 2 \text{ (Login Join)} & \longrightarrow \text{If } \texttt{ONLINE}\text{: TCP splice to backend; if } \texttt{ondemand}\text{: wake server + return countdown} \end{cases}$$

State Machine for Managed Worlds

Server State Multiplayer List Ping (state = 1) MOTD & Icon Player Clicks "Join Server" (state = 2)
SLEEPING (ondemand) Configured custom MOTD (or §e<name> §7[Standby] — §aClick Join to wake server!) + server-icon.png + version badge Standby (Join to Wake) HAProxy Lua sends JOIN <slug> to mc-manager, starts minecraft@<slug>.service, and disconnects client with: "⚡ Waking up <name>... Server is starting on-demand. Please reconnect in ~20 seconds!"
STARTING Configured custom MOTD + server-icon.png + version badge Starting... Disconnects client with: "⏳ <name> is currently booting up! Please wait ~15 seconds and try connecting again."
ONLINE Live player count & sample from backend JVM overlaid with latest custom MOTD (server.properties) and server-icon.png (favicon) Native TCP splice to [fd77:7777:5010::1337:3c:d00d:<hex>]:25565 with full Microsoft online-mode=true auth
OFFLINE (manual) Configured custom MOTD + server-icon.png + version badge Offline Disconnects client with: "<name> is currently offline. Start it from https://mc.drheck.dev"

Idle Shutdown Timer

For any running server in ondemand mode, mc-manager tracks the time since the last player disconnected ($N_{\text{players}} = 0$). When:

$$t_{\text{empty}} \ge T_{\text{idle}} \quad (\text{default } 20\text{ min})$$

mc-manager issues save-all and stop via the /run/mc-manager/<slug>.sock PTY socket and stops minecraft@<slug>.service, freeing the JVM heap until the next join request.


6.4 Web Control Plane (https://mc.drheck.dev)

The web frontend is served over HTTPS behind Nginx + Authentik ForwardAuth and provides two primary workspaces designed with a clean, hardware-ops dark interface:

1. Existing Servers Dashboard & Live PTY Console

  • Server Sidebar & Status Header:
    • Displays every registered server with its 64×64 pixel icon, live state badge (ONLINE, STANDBY, OFFLINE), endpoint (<slug>.drheck.dev), IPv6 address, heap allocation, and lifecycle mode (On-Demand, Always On, Manual).
    • One-Click Controls: Start Server, Restart, Stop, and + Provision Network / DNS (if not yet allocated).
  • Live Server Console (mc-runner WebSocket Stream):
    • Connects via WebSocket (/api/servers/<slug>/console/ws) to /run/mc-manager/<slug>.sock, streaming the 1,000-line PTY ring buffer and real-time server stdout/stderr lines.
    • Allows admins to send console commands (say, op, whitelist, time set, gamemode, /give, etc.) directly to the server's stdin (leading / is automatically stripped because the server console expects bare commands).
  • Configuration, Text/MOTD Studio, Icon Studio, Whitelist & Operators Panels:
    • Edit Display Name, MOTD, Start Mode, Idle Timeout, Min/Max Heap, Jar File, Gamemode, Difficulty, Max Players, View Distance, Level Seed, server-icon.png, whitelist.json, and ops.json.

2. Minecraft Text, MOTD, Color Gradient & 8-Bit Pixel Icon Studio

Built directly into both the + New World screen and the Configuration panel of every existing server:

  • Unicode Font Converter (Copy/Paste Safe):
    • Converts text into Minecraft Java Edition font variants without resource packs: Small Caps (ꜱᴍᴘ), Gothic / Fraktur (𝔖𝔲𝔯𝔳𝔦𝔳𝔞𝔩), Double-Struck (𝕊𝕦𝕣𝕧𝕚𝕧𝕒𝕝), Full-Width (SMP), and Monospace.
    • Includes one-click Java-Safe Decorative Symbols & Borders: ⚔, ◆, ★, ⚡, 👑, ☠, ✦, ❖, », «, and ⚔ ... ⚔.
  • § Color Gradient & Formatting Code Builder:
    • Interpolates any two RGB colors (Gradient Start $\longrightarrow$ Gradient End) across the input string and maps each character to the nearest native Minecraft color code (§0–§f), combined with optional §l (Bold), §o (Italic), §n (Underline), §m (Strikethrough), or §k (Obfuscated).
    • Can be applied with one click to either MOTD (server.properties) or Display Name (server.json), with a real-time Minecraft Multiplayer Server List Preview rendering § codes and the 64×64 icon side-by-side.
  • 8-Bit Pixel Icon & Badge Generator (64×64 server-icon.png):
    • Generates crisp 64×64 pixel-art server icons in the browser using 6 Minecraft material themes (Stone, Dirt & Grass, Diamond, Glowstone, Nether, Enchanted Glint), 7 pixel-art stamps (Sword, Pickaxe, Creeper, Crown, Heart, Star, Pokéball), and 1–3 character 8-bit bitmap text with 3D drop shadows, or accepts any custom uploaded PNG/JPG/WebP image (auto-cropped and resampled to 64×64).

3. Interactive Seed Preview Studio (cubiomes Native Renderer)

  • Uses /usr/local/bin/mc-seed-render (compiled against cubiomes) on ul to render a 2D biome map ($\pm 2048$ blocks around $(0,0)$) and locate nearest structures (Village, Ancient City, Mansion, Monument, Outpost, Stronghold, Ruined Portal) in $< 50\text{ ms}$ per seed.
  • Supports Roll Random Seed and interactive biome legend inspection prior to provisioning a new world.

6.5 Authentik Gate, RBAC & Automatic /op (ops.json) Synchronization

Access to https://mc.drheck.dev is gated at the Nginx perimeter via Authentik ForwardAuth (X-Authentik-Username), and mc-manager maps authenticated identities via /data/minecraft/.manager/users.json:

$$\text{Authentik SSO } (\texttt{auth.drheck.dev}) \longrightarrow \text{Nginx ForwardAuth } (\texttt{X-Authentik-Username}) \longrightarrow \texttt{mc-manager} \text{ RBAC + } \texttt{ops.json} \text{ Sync}$$

  • Global Admins (global_admin: true, e.g., luke): Full access to create servers, provision network/DNS, manage the Users & Operators Registry (with live Mojang API username $\longrightarrow$ UUID lookup), and administer all worlds.
  • Per-Server Admins (server.json admins): Full control to start/stop/restart, access the live console, and edit configuration/whitelist/icon on their assigned worlds.
  • Automatic ops.json Synchronization: Adding a user as a Global Admin or Server Admin automatically syncs their Mojang UUID and username into ops.json (Level 4 operator with bypassesPlayerLimit: true).

6.6 Server-Side Quality-of-Life (QoL) Datapack Library & Non-Agentic Modrinth Updater

All server-side Quality-of-Life (QoL), building, and world-generation datapacks (world/datapacks/*.zip) run 100% on the server so players connect with a standard Vanilla Minecraft client without installing any client-side mod loader.

Curated Server-Side Datapack Library (/data/minecraft/datapacks/)

Both the + Create New Server studio and every server's QoL Mods & Datapacks tab in https://mc.drheck.dev include a 16-pack verified library plus live Modrinth v2 search:

Category Datapack / QoL Mod Modrinth Slug / Source Default Bundle Description Survival QoL Graves (Ketket) ketket-graves PokeLovers Preset Spawns a grave on death storing inventory and XP safely until retrieved. Survival QoL Fast Leaf Decay fast_leaf_decay PokeLovers Preset Leaves decay rapidly after chopping down tree logs. Survival QoL Craftable Invisible Item Frames invisframes (local) PokeLovers Preset Adds crafting recipes for invisible item frames and glow invisible item frames. Survival QoL Player Drops Head (Jodek) player-drops-head PokeLovers Preset Players drop their textured head item when killed. Survival QoL Shulkers Drop Two Shells (Jodek) two-shulker-shells-drop PokeLovers Preset Every Shulker guarantees 2 Shulker Shells on death. Survival QoL All Mob Heads (Jodek) mob-heads Optional Mobs have a balanced chance to drop their decorative head (including variants). Survival QoL Veinminer veinminer Optional Mine entire connected ore veins at once while sneaking with a pickaxe. Survival QoL Timber Strike timber-strike Optional Fells connected tree logs in one chop using an axe. Survival QoL Call Your Horse call-your-horse Optional Whistle to summon your tamed horse, donkey, or mule from nearby chunks. Survival QoL Mineable Spawners mineable-spawner Optional Pickaxes enchanted with Silk Touch can mine and relocate Monster Spawners. Building & Utility Armor Stand Arms armor-stand-arms Optional Gives Armor Stands arms by default and enables pose customization. Building & Utility MasterCutter (Wood Stonecutter) mastercutter Optional Adds Stonecutter recipes for all wood planks, stairs, slabs, and copper blocks. Building & Utility Day Counter daycounter Optional Displays and tracks in-game world days survived on the scoreboard/actionbar. Building & Utility AFK Announcer & Display afk-announcer Optional Automatically marks idle players as AFK in the tab list and chat. Worldgen & Structures Dungeons and Taverns dungeons-and-taverns Optional Overhauls vanilla structures and adds Vanilla-friendly taverns, shrines, and dungeons. Worldgen & Structures Terralith terralith Optional Adds 95+ vanilla-block biomes, canyons, and caves with zero client mods required.

Non-Agentic Deterministic Update Pipeline (Web UI, CLI & Weekly systemd Timer)

Datapacks are updated deterministically without any AI agent involvement by querying the Modrinth v2 REST API (/v2/version_file/<sha1> and /v2/project/<slug>/version?loaders=["datapack"]), verifying the downloaded archive against Modrinth's published SHA-1 digest, replacing the old .zip atomically in world/datapacks/, and issuing reload over /tmp/mc-runner-<slug>.sock if the server is online:

$$\text{On-Disk }\texttt{.zip}\text{ SHA-1} \longrightarrow \texttt{api.modrinth.com/v2} \longrightarrow \text{SHA-1 Verified Download} \longrightarrow \text{Atomic Swap + }\texttt{/reload}$$

    Web UI (https://mc.drheck.dev): Open any server $\longrightarrow$ QoL Mods & Datapacks tab $\longrightarrow$ click ↻ Check Modrinth Updates or ⬆ Update All Installed Datapacks. Manual CLI Check / Update:
    # Check all servers for available Modrinth datapack updates (read-only):
    /usr/local/bin/mc-manager -check-datapacks
    
    # Download, SHA-1 verify, and apply all available Modrinth datapack updates across all servers:
    /usr/local/bin/mc-manager -update-datapacks
    
    Automated Weekly systemd Timer (mc-datapack-update.timer):
      /etc/systemd/system/mc-datapack-update.timer triggers /etc/systemd/system/mc-datapack-update.service every Sunday at 04:15 EDT, keeping all server datapacks and /data/minecraft/datapacks/ up to date automatically.