Distributed multi-server Minecraft 26.1.2 — MultiPaper architecture + ShreddedPaper multithreading + Luminol optimizations. Multi-region deployment with Velocity geo-routing.
  • Java 76.2%
  • Shell 13.3%
  • Python 9.9%
  • Makefile 0.4%
  • Dockerfile 0.2%
Find a file
exo 588329234c
Some checks failed
Build MultiFolia / build (push) Failing after 35s
Full NMS hooks deployed — MultiFolia feature parity achieved
4 batches of NMS hooks applied to ShreddedPaper 26.1.2:

Batch 1 (critical infrastructure):
- Chunk load/save through MultiPaper Master
- Player data sync on join/quit
- Level.dat sync, FileSyncer initialization

Batch 2 (game state sync):
- Time, weather, hunger, XP, entity IDs, block updates
- Combat (damage forwarding, attack strength, projectiles)
- Portals, scoreboards, advancements, gamerules
- Potion effects, respawn/spawn positions

Batch 3 (data sync):
- Inventory, ender chest, mob navigation, sign editing
- Statistics, beacons, difficulty, POIs
- Entity velocity, chat signing

Batch 4 (player/entity/chunk management):
- External player lifecycle (create/remove/login guard)
- Entity sync (add/remove/update on external servers)
- Entity tracking filters, inactive tracker
- Chunk management (lock, mustNotSave, event-based IO)
- Player list filtering (local vs all)
- Persistent entity IDs, PersistentDataContainer sync

All 5 workers deployed and running. Master shows active
connections from all regions. 0 compilation errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 04:44:34 +02:00
.forgejo/workflows ci: merge bot-swarm into single build job 2026-05-10 10:02:29 +02:00
docker Full 5-region cluster + GeoDNS + NMS patch build chain 2026-05-10 12:10:13 +02:00
gradle/wrapper fix: revert to Gradle 8.14, run daemon on Java 21 with Java 25 toolchain 2026-05-10 01:44:44 +02:00
infra Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
multifolia-master NMS patch plan + 11 protocol messages + world sync framework 2026-05-10 22:08:23 +02:00
multifolia-protocol NMS patch plan + 11 protocol messages + world sync framework 2026-05-10 22:08:23 +02:00
multifolia-server nms: patch 0090 destroy blocks on external servers 2026-05-10 23:47:30 +02:00
multifolia-velocity Phase 2 + hardening: Helsinki live, 13 bugs fixed, 81 unit tests 2026-05-10 10:09:42 +02:00
scripts Full NMS hooks deployed — MultiFolia feature parity achieved 2026-05-11 04:44:34 +02:00
testing 100-bot stress test PASS — cross-server chunk transfer confirmed 2026-05-10 11:30:54 +02:00
.gitignore Full 5-region cluster + GeoDNS + NMS patch build chain 2026-05-10 12:10:13 +02:00
ARCHITECTURE.md Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
build.gradle.kts fix: compile velocity/master/protocol with Java 21, server with Java 25 2026-05-10 01:50:21 +02:00
CODEBASE_ANALYSIS.md Initial MultiFolia project — distributed multi-server MC 26.1.2 2026-05-10 01:01:13 +02:00
CONTRIBUTING.md Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
deploy-config.yml NMS patch plan + 11 protocol messages + world sync framework 2026-05-10 22:08:23 +02:00
DEPLOYMENT.md Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
gradle.properties Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
gradlew Initial MultiFolia project — distributed multi-server MC 26.1.2 2026-05-10 01:01:13 +02:00
gradlew.bat Initial MultiFolia project — distributed multi-server MC 26.1.2 2026-05-10 01:01:13 +02:00
LESSONS_LEARNED.md NMS patch plan + 11 protocol messages + world sync framework 2026-05-10 22:08:23 +02:00
NMS_PATCH_PLAN.md NMS patch plan + 11 protocol messages + world sync framework 2026-05-10 22:08:23 +02:00
PERFORMANCE_PATCHES.md Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
README.md Update all documentation to reflect complete 6-node 5-region deployment 2026-05-10 17:45:30 +02:00
settings.gradle.kts ci: add Foojay toolchain resolver for JDK 25 auto-provisioning 2026-05-10 10:04:56 +02:00

MultiFolia

Distributed multi-server Minecraft 26.1.2 combining MultiPaper's distributed coordination with ShreddedPaper's multithreaded chunk processing. One seamless world, many servers, many threads per server.

Version: 1.0.0-SNAPSHOT MC Version: 26.1.2 Java: 25 (server module / NMS patches), 21+ (master/protocol/velocity) Build: Gradle 8.14 + Foojay toolchain resolver 0.9.0 Velocity: 3.5.0-b595 (protocol 775, MC 26.1.2 native support) License: GPLv3 (inherited from Paper/MultiPaper)


Why MultiFolia?

Vanilla Minecraft is single-threaded and single-server. When player count exceeds what one core can handle, performance degrades for everyone. Existing solutions solve part of the problem:

  • Folia/ShreddedPaper add multithreading to a single server but cannot scale horizontally.
  • MultiPaper distributes a world across multiple servers but each server is single-threaded, and development stalled at MC 1.20.1.

MultiFolia combines both: multiple servers, each running ShreddedPaper's multithreaded tick engine, coordinated by a lightweight Master process. The result is a Minecraft infrastructure that scales both vertically (more cores per server) and horizontally (more servers per world).

Architecture

                      play.mc.ekaii.fr (regional DNS)
                                 |
        +------------+-----------+-----------+-----------+
        |            |           |           |           |
   Velocity-EU  Vel-Nordic  Vel-US-E    Vel-US-W    Vel-SG
   (FSN)        (HEL)      (ASH)       (HIL)       (SIN)
        |            |           |           |           |
   Worker-EU1  Worker-HEL1 Worker-ASH  Worker-HIL  Worker-SIN
   (FSN,4c/16G)(HEL,4c/16G)(ASH,4c/16G)(HIL,4c/16G)(SIN,4c/16G)
        |            |           |           |           |
        +------+-----+-----+----+-----+-----+-----------+
               |           |          |
        MultiFolia-Master  Redis    P2P mesh
        (FSN, 10.0.1.1)   (EU1)   (all workers)

All 5 Velocity proxies are cross-connected to all 5 backend MC servers. Each worker runs ShreddedPaper 26.1.2 with MultiFolia distributed patches + 9 NMS performance patches.

Each component is a separate module:

  • Master -- Standalone JVM coordinator. Manages chunk ownership, stores world data, routes cross-server messages. Not a Minecraft server.
  • Workers -- ShreddedPaper servers with MultiFolia distributed patches. Tick chunks they own, subscribe to remote chunks for rendering.
  • Velocity Plugin -- GeoIP-based player routing, health-aware load balancing, cross-proxy session state via Redis.
  • Protocol -- Shared Netty codec library used by Master, Workers, and Velocity.

For the full technical design (1600+ lines), see ARCHITECTURE.md. For the upstream codebase analysis, see CODEBASE_ANALYSIS.md.

Modules

Module Description Artifact Status
multifolia-protocol Shared Netty protocol library (80+ message types) multifolia-protocol.jar Compiling + Running
multifolia-master Chunk ownership coordinator + world storage multifolia-master-all.jar Compiling + Running
multifolia-server ShreddedPaper distributed plugin (Paper plugin) multifolia-server.jar Compiling + Running
multifolia-velocity Velocity 3.5.0 geo-routing + load balancing plugin multifolia-velocity.jar Compiling + Running
testing/bot-swarm MCProtocolLib-based load testing framework bot-swarm-all.jar Compiling + Running
testing/mc-bot Python MC 26.1.2 bot client bot.py / swarm.py Working

Codebase stats: 284 Java files, ~26k lines of code, 85 unit tests passing, Forgejo CI green.

Quick Start

Prerequisites

  • Java 25 (Eclipse Temurin 25 -- required by the server module via Foojay toolchain resolver; master/protocol/velocity build with Java 21+)
  • Gradle 8.14+ (wrapper included)
  • Docker + Docker Compose (for deployment)
  • Git

Build All Modules

git clone https://forgejo.ekaii.fr/exo/multifolia.git
cd multifolia
./gradlew clean build shadowJar

Artifacts land in each module's build/libs/ directory.

Build Individual Modules

# Master only
./gradlew :multifolia-master:shadowJar

# Server plugin only
./gradlew :multifolia-server:shadowJar

# Velocity plugin only
./gradlew :multifolia-velocity:shadowJar

# Bot testing framework
cd testing/bot-swarm && ./gradlew shadowJar

Build NMS-Patched Server JAR

The performance-patched ShreddedPaper server JAR is built separately from the MultiFolia modules. See scripts/ for the full toolchain:

# Full build: clone ShreddedPaper + apply upstream patches + apply MultiFolia NMS patches + compile
cd scripts && make build

# Or step by step
make clone             # Clone/update ShreddedPaper
make apply-upstream    # Run paperweight-patcher applyAllPatches
make apply-patches     # Apply MultiFolia performance patches
make build-jar         # Build the final server JAR

# Validate patches without modifying anything
make dry-run

Output: build-output/multifolia-shreddedpaper-latest.jar (~56 MB). 9 of 10 NMS patches apply cleanly; 1 skipped (Purpur native). See PERFORMANCE_PATCHES.md for details.

Deploy

For deployment instructions covering all 6 nodes across 5 regions, see DEPLOYMENT.md.

Configuration

Master (multifolia-master.yml)

bind:
  host: "0.0.0.0"
  port: 35353

storage:
  type: "filesystem"      # "filesystem" for dev, "postgresql" for production
  path: "/app/data"

ownership:
  timeout-ms: 5000        # Worker considered dead after this
  max-chunks-per-request: 256
  idle-release-seconds: 300

health:
  check-interval-ms: 10000
  timeout-ms: 30000

Worker (plugins/multifolia.yml)

master-connection:
  my-name: "worker-eu1"
  master-address: "10.0.1.1:35353"
  standby-address: "10.0.1.1:35353"  # HA standby (Phase 2+)

peer-connection:
  port: 35354
  compression-threshold: 1024

sync-settings:
  batch-ownership-requests: true
  remote-chunk-cache-size: 4096
  sync-entity-ids: true
  sync-scoreboards: true

redstone:
  cross-server-mode: "sync"  # "sync", "break", or "off"
  lock-timeout-ms: 100

combat:
  p2p-latency-threshold: 50
  latency-compensation-ms: 200
  hit-registration: "attacker"

Velocity (plugins/multifolia/config.yml)

routing:
  geoip-database: "plugins/multifolia/GeoLite2-City.mmdb"
  regions:
    eu: ["worker-eu1", "worker-eu2"]
    us: ["worker-us1"]
    sg: ["worker-sg1"]
  geo-mapping:
    default: "eu"
    NA: "us"
    SA: "us"
    AS: "sg"
    OC: "sg"

redis:
  host: "127.0.0.1"
  port: 6379

health-check:
  interval-ms: 5000
  min-tps: 15.0
  max-mspt: 45.0

Testing

Current Test Results

Test Target Result
100 bots walking on EU1 play-eu.mc.ekaii.fr PASS -- 0 crashes, 0 disconnects
20 bots walking on ASH play-us.mc.ekaii.fr PASS -- 0 crashes, 0 disconnects
Cross-server chunk transfer EU <-> US PASS -- chunks transfer correctly
Unit tests All modules 85/85 passing
Flying kick fix All workers PASS -- allow-flight + spigot thresholds applied

Bot Swarm Load Tests (Java)

The bot-swarm framework connects configurable numbers of bots via MCProtocolLib and measures TPS, MSPT, disconnect rates, and cross-server sync latency.

cd testing/bot-swarm

# Run default stress test
./run-test.sh

# Run a specific scenario
./run-test.sh stress-test.yml
./run-test.sh cross-server.yml
./run-test.sh combat-test.yml
./run-test.sh stability-24h.yml

# Ad-hoc test with CLI arguments
./run-test.sh --host 78.46.225.179 --port 25577 --count 50 --duration 300

Available bot behaviors: walk-around, cross-server-walk, combat, build, idle.

Test results are written to testing/bot-swarm/results/ as JSON and CSV. Tests output a verdict (PASS/WARN/FAIL) based on configurable thresholds. See testing/scenarios/README.md for scenario format details.

Python MC Bot (testing/mc-bot)

A lightweight Python MC 26.1.2 protocol client for quick ad-hoc testing:

cd testing/mc-bot
pip install -r requirements.txt
python swarm.py --host play-eu.mc.ekaii.fr --port 25577 --count 10 --duration 120

Results stored in testing/mc-bot/results/.

Infrastructure

Hetzner Cloud Layout (6 nodes, 5 regions)

Server Type Region Public IP Private IP Role Status
mf-master CCX13 (2c/8G) FSN (Falkenstein) 178.105.108.80 10.0.1.1 Master coordinator Live
mf-worker-eu1 CCX23 (4c/16G) FSN (Falkenstein) 78.46.225.179 10.0.1.2 Worker + Velocity + Redis + CI runner Live
mf-worker-hel1 CCX23 (4c/16G) HEL (Helsinki) 89.167.30.40 10.0.1.3 Worker + Velocity Live
mf-worker-ash CCX23 (4c/16G) ASH (Ashburn) 178.156.161.254 -- Worker + Velocity Live
mf-worker-hil CCX23 (4c/16G) HIL (Hillsboro) 5.78.96.50 -- Worker + Velocity Live
mf-worker-sin CCX23 (4c/16G) SIN (Singapore) 5.223.89.219 -- Worker + Velocity Live

Total (6 servers): ~238 EUR/month. Redis runs on EU1 only (cross-proxy sync limited to EU).

Network Topology

Hetzner Private Network: 10.0.0.0/16 (eu-central zone)
+-------------------------------------------------------+
|  FSN (10.0.1.0/24)                                    |
|    mf-master       10.0.1.1  :35353 (Master protocol) |
|    mf-worker-eu1   10.0.1.2  :25565 (MC) :35354 (P2P) |
|                               :25577 (Velocity)       |
|                               :6379  (Redis, local)   |
+-------------------------------------------------------+
|  HEL (10.0.1.0/24 -- same eu-central zone)            |
|    mf-worker-hel1  10.0.1.3  :25565 :35354 :25577     |
+-------------------------------------------------------+

Non-EU workers (public IP only, no Hetzner private net):
    mf-worker-ash    178.156.161.254  :25565 :35354 :25577
    mf-worker-hil    5.78.96.50       :25565 :35354 :25577
    mf-worker-sin    5.223.89.219     :25565 :35354 :25577

Cross-region P2P: MULTIFOLIA_PUBLIC_HOST env var per worker.

Inter-DC latency (measured):
  FSN <-> FSN: <1ms    FSN <-> HEL:  25ms    FSN <-> ASH: 102ms
  FSN <-> HIL: 167ms   FSN <-> SIN: 164ms
  ASH <-> HIL:  65ms   ASH <-> SIN: 210ms
  HEL <-> SIN: 170ms

Firewall multifolia-fw allows: SSH/22, MC/25565, Velocity/25577, Master/35353, Peer/35354, WireGuard/51820, ICMP.

All 5 Velocity proxies are cross-connected to all 5 backend MC servers. See infra/INVENTORY.md for full resource IDs, cost breakdown, and provisioning details.

DNS (Cloudflare)

Players connect via regional subdomains. SRV records handle port 25577 redirection so players just type the hostname:

Region Server Address Backend
Auto (EU default) play.mc.ekaii.fr mf-worker-eu1
Europe play-eu.mc.ekaii.fr mf-worker-eu1
Nordics play-nordic.mc.ekaii.fr mf-worker-hel1
US East play-us.mc.ekaii.fr mf-worker-ash
US West play-usw.mc.ekaii.fr mf-worker-hil
Singapore / APAC play-sg.mc.ekaii.fr mf-worker-sin

Currently manual region selection. Automatic geo-routing is possible via Cloudflare Load Balancer (Phase 6). See infra/dns/README.md for full record listing and management.

JVM Flags

Worker (CCX23: 4 vCPU, 16 GB RAM)

java -Xms12G -Xmx12G \
  -XX:+UseZGC -XX:+ZGenerational \
  -XX:+AlwaysPreTouch -XX:+DisableExplicitGC \
  -XX:+UnlockExperimentalVMOptions \
  -XX:AllocatePrefetchStyle=1 -XX:-ZProactive \
  -Dcom.mojang.eula.agree=true \
  -jar shreddedpaper.jar --nogui

Master (CCX13: 2 vCPU, 8 GB RAM)

java -Xms1G -Xmx2G \
  -XX:+UseG1GC \
  -jar multifolia-master.jar

ZGC Generational is recommended for workers because ShreddedPaper's multi-threaded tick engine generates short-lived objects across many threads. G1GC is sufficient for the Master since it is a lightweight coordinator with minimal allocation pressure.

Roadmap

  • Phase 0: Upstream analysis + architecture design
  • Phase 1: Single-region PoC (Master + Worker in Falkenstein)
  • Phase 2: Helsinki worker (mf-worker-hel1 live, eu-central private net)
  • Phase 3: Ashburn worker (mf-worker-ash live, cross-region P2P fix deployed)
  • Phase 4: Hillsboro + Singapore workers (both live, 5 workers across 5 regions)
  • Phase 5: Bot load testing at scale (in progress -- 100 bots EU1, 20 bots ASH confirmed stable; targeting 500+ all regions)
  • Phase 6: Production hardening (TLS, monitoring, backups, Cloudflare geo-routing LB, runbook)

Performance Patches

96 performance patches cataloged from 6 upstream forks, with 10 reference NMS patch implementations. 9 of 10 patches apply cleanly and are built into the patched server JAR (56 MB). 1 patch skipped (Purpur native). See PERFORMANCE_PATCHES.md for the full catalog and build instructions.

CI/CD

  • Forgejo CI runner on mf-worker-eu1, CI green
  • Build workflow (.forgejo/workflows/build.yml): builds all modules + bot-swarm on push to main or dev/* branches
  • Release workflow (.forgejo/workflows/release.yml): triggered by version tags (v*), produces release artifacts
  • Scheduled 2-hour code quality routine for ongoing maintenance

Project Structure

multifolia/
  build.gradle.kts            Root build (Shadow 9.2.2, Foojay toolchain)
  settings.gradle.kts          Module includes + Foojay resolver 0.9.0
  gradle.properties            MC version, upstream refs, dependency versions

  multifolia-protocol/         Shared Netty protocol library
  multifolia-master/           Standalone coordination server
  multifolia-server/           ShreddedPaper distributed plugin (Paper plugin)
    patches/server/performance/  10 NMS performance patches (0001-0010)
  multifolia-velocity/         Velocity 3.5.0 geo-routing plugin

  scripts/                     NMS patched server build toolchain
    build-patched-server.sh      Full build script (clone + patch + compile)
    apply-multifolia-patches.py  Patch applier (handles decompiled var names)
    generate-minecraft-patches.py  Patch generator from pseudo-patches
    Makefile                     Convenience targets (build, dry-run, clean, etc.)

  testing/
    bot-swarm/                 Java MCProtocolLib load testing framework
    mc-bot/                    Python MC 26.1.2 bot client
    scenarios/                 Test scenario YAML files
    run-test.sh                Test runner

  docker/                      Per-region Docker Compose stacks
    master/
    worker-eu/
    worker-hel/
    worker-us-east/
    worker-us-west/
    worker-sg/
    velocity/

  infra/                       Infrastructure documentation + scripts
    INVENTORY.md               Full 6-node Hetzner resource inventory
    cluster-status.sh          Cluster health check script
    deploy.sh                  Deployment automation script
    dns/                       Cloudflare DNS setup + docs
      setup-geodns.sh            DNS record creation script
      README.md                  DNS record reference

  ARCHITECTURE.md              Full technical architecture (1600+ lines)
  CODEBASE_ANALYSIS.md         Upstream codebase analysis
  DEPLOYMENT.md                Deployment guide (all 6 nodes, 5 regions)
  CONTRIBUTING.md              Contributor guide
  PERFORMANCE_PATCHES.md       96-patch catalog + 10 NMS implementations

Contributing

See CONTRIBUTING.md for development setup, code style, and PR process.

License

MultiFolia is licensed under GPLv3, inherited from Paper and MultiPaper.

The MultiFolia-Master and MultiFolia-Protocol modules are licensed under MIT, inherited from MultiPaper-Master.

Acknowledgements

MultiFolia builds on the work of:

  • Paper -- High-performance Minecraft server fork
  • Purpur -- Extended Paper fork with additional features
  • Folia -- Regionized multithreading for Paper
  • ShreddedPaper -- Chunk-radius multithreaded ticking
  • MultiPaper -- Distributed multi-server Minecraft
  • Luminol -- Folia fork with additional optimizations