Minecraft Welt automatisch neu generieren: eine Abenteuerwelt, die jede Woche frisch ist | MappleBox

Minecraft Welt automatisch neu generieren: eine Abenteuerwelt, die jede Woche frisch ist

Nach ein paar Monaten ist die Hauptwelt abgegrast. Eine Welt, die jeden Montag frisch generiert wird, hat wieder unerforschtes Terrain und Strukturen, die noch niemand geplündert hat. Deine Spieler haben jede Woche einen Grund, rauszuziehen. In diesem Guide zeige ich dir, wie du so eine Minecraft Welt automatisch neu generieren lässt. Dazu gehören Seed-Auswahl (der Seed ist die Startzahl, aus der Minecraft das Terrain berechnet), Pregen (Vorab-Generieren der Landschaft) und Tausch ohne Admin am Rechner. Alles, was du dafür brauchst, liegt als Open-Source-Repo auf GitHub: mapplebox/minecraft-weekly-world. Als Beispiel aus der Praxis dient die Abenteuerwelt auf CobbleBox, meinem Cobblemon-Server (Minecraft 1.21.1, Fabric, Modpack COBBLEVERSE). Das Repo ist die aufgeräumte, konfigurierbare Fassung dieses Setups.

Kurz erklärt

  • Dein Server bekommt eine Zusatzwelt, die sich jeden Montag von selbst durch eine neue Landschaft ersetzt.
  • Nützlich, wenn du einen Fabric-Server auf Minecraft 1.21.1 betreibst und die Hauptwelt abgegrast ist.
  • Du brauchst Zugriff auf den Linux-Rechner deines Servers, die Mods Fabric API, MultiWorld und Chunky, eingeschaltetes RCON und Python 3. Java oder Docker brauchst du nur, wenn du die Mod selbst baust.
  • Mod, Python-Tool und systemd-Timer kommen aus dem Repo minecraft-weekly-world. Du passt im Wesentlichen eine Config-Datei an.
  • Nach dem Einrichten läuft der Tausch automatisch. Neue Regionen nachzurüsten hat auf CobbleBox einen Abend gedauert.

Das Konzept

Die Abenteuerwelt ist eine Zusatzwelt neben der Hauptwelt. Jede Woche bekommt sie einen neuen, zufälligen Seed und damit komplett neues Terrain. Dazu rotiert ein Thema, im Repo heißt das Region. Auf CobbleBox wechseln die Regionen Kanto, Johto, Hoenn und Sinnoh der Reihe nach, die Beispiel-Config im Repo nutzt forest und frontier. Gezählt wird ab einer festen Kalenderwoche, damit die Rotation auch über Silvester sauber weiterläuft. Jede Region hat ihre eigenen Biom-Kopien und kann eigene, dichter gesetzte Strukturen bekommen. Auf CobbleBox sind das die Arenen der jeweiligen Region.

Für die Spieler gilt: Alles, was du in der Abenteuerwelt baust, ist beim nächsten Tausch weg. Was du im Inventar mit zurück in die Hauptwelt nimmst, bleibt dir. Die Welt ist zum Erkunden und Farmen da.

Technisch besteht das Setup aus vier Bausteinen, die alle im Repo liegen:

  • ein Datapack (Konfigurationsdateien, die Minecraft ohne Mod erweitern), das pro Region eine Dimension (eine eigene Welt wie Nether oder End) als Generator definiert. Das baut tools/weekly_world.py build-datapack für dich.
  • eine kleine Fabric-Mod (eine Erweiterung mit eigenem Code) im Ordner mod/, die diese Generatoren in MultiWorld nutzbar macht und Konsolen-Commands zum Anlegen und Löschen der Wochenwelten mitbringt
  • das Python-Tool tools/weekly_world.py mit den Schritten prepare (Vorbereitung) und swap (Tausch)
  • zwei systemd-Timer im Ordner systemd/, die das Tool zur richtigen Zeit starten

Der ehrliche Stand: Das Original läuft auf CobbleBox. Die Mod im Repo baut sauber, die verallgemeinerte Fassung ist aber noch nicht auf einem Live-Server gelaufen. Was genau getestet ist, steht im README unter „Not verified“. Teste das Setup deshalb zuerst auf einer Kopie deines Servers.

Was du brauchst

  • einen Minecraft-Server 1.21.1 mit Fabric Loader 0.16.0 oder neuer. Den Installer findest du auf fabricmc.net/use/server.
  • die Mods Fabric API, MultiWorld und Chunky, jeweils in der Fabric-Version für 1.21.1, im Ordner mods/
  • RCON, also die Fernsteuerung für die Server-Konsole, eingeschaltet in der server.properties
  • Python 3.9 oder neuer auf dem Rechner, der RCON erreicht und die Server-Dateien lesen kann. Das Tool braucht nur die Standardbibliothek, du installierst also keine Pakete.
  • einen Linux-User mit systemd für die Timer
  • Java 21 oder Docker nur, wenn du die Mod selbst baust oder für Vanilla-Terrain einmal die Biom-Liste erzeugst (siehe Schritt 4)

Läuft bei dir auch C2ME, lass den Lock-Mixin der Mod eingeschaltet. Warum, liest du im Guide zum C2ME Watchdog Crash.

In den Beispielen liegt der Server unter /srv/minecraft mit dem Weltordner world und das Repo unter ~/minecraft-weekly-world. So erwarten es auch die Beispiel-Config und die systemd-Units. Liegt bei dir etwas woanders, passt du die Pfade an.

Schritt 1: RCON einschalten

Das Tool schickt alle Befehle per RCON an den Server. Öffne die server.properties im Server-Ordner und setz diese drei Werte. Das Passwort denkst du dir selbst aus, 25575 ist der Standard-Port:

enable-rcon=true
rcon.port=25575
rcon.password=<dein-rcon-passwort>

Nach einem Neustart steht im Server-Log eine Zeile wie RCON running on 0.0.0.0:25575. Gib den RCON-Port nicht im Router oder in der Firewall nach außen frei. Das Tool läuft auf demselben Rechner oder im selben Netz und braucht den Port nur lokal.

Schritt 2: Repo holen und die Mod installieren

Klon das Repo in dein Home-Verzeichnis:

cd ~
git clone https://github.com/mapplebox/minecraft-weekly-world.git
cd minecraft-weekly-world

Eine Datapack-Dimension hat einen Haken: Sie teilt sich den Seed mit der Hauptwelt. Für neues Terrain jede Woche brauchst du also echte Zusatzwelten mit eigenem Seed. Die liefert MultiWorld. Dessen -g-Option kennt aber nur die eingebauten Generatoren (NORMAL, NETHER, END, FLAT, VOID) und solche, die eine andere Mod per Java registriert. Genau das übernimmt die Mod aus dem Repo. Sobald eine Dimension <namespace>:weekly_* geladen wird, holt sie sich deren Chunk-Generator und meldet ihn bei MultiWorld an. Der Aufruf läuft per Reflection (die Mod sucht die passende Funktion erst zur Laufzeit), damit sie beim Kompilieren nicht von MultiWorld abhängt.

Falls im Repo unter Releases eine fertige Jar liegt, nimm die. Sonst baust du die Mod selbst. Mit Docker brauchst du dafür weder Java noch Gradle lokal. Der Befehl baut im offiziellen Gradle-Image mit JDK 21, legt den Gradle-Cache im Projektordner ab und sorgt mit -u dafür, dass die erzeugten Dateien deinem User gehören:

cd ~/minecraft-weekly-world/mod
docker run --rm \
  -u $(id -u):$(id -g) \
  -e GRADLE_USER_HOME=/work/.gradle \
  -v "$PWD":/work -w /work \
  gradle:8.12-jdk21 \
  gradle build --no-daemon
# fertige Jar: build/libs/weeklyworld-1.0.0.jar

Mit einem lokalen JDK 21 reicht im Ordner mod/ ein ./gradlew build, der Gradle Wrapper liegt im Repo. Schlägt der Build fehl, mach im Repo ein Issue auf.

Kopier die Jar in den mods/-Ordner des Servers und starte ihn einmal:

cp build/libs/weeklyworld-1.0.0.jar /srv/minecraft/mods/

Beim ersten Start schreibt die Mod ihre Config nach config/weeklyworld.json:

{
  "generators": [],
  "autoDiscover": true,
  "generatorPrefix": "weekly_",
  "worldPrefix": "weekly_",
  "multiworldNamespace": "multiworld",
  "lookupCacheLock": true
}
  • autoDiscover meldet jede geladene Dimension <namespace>:weekly_* als Generator an. Ausgenommen sind minecraft: und MultiWorlds eigener Namespace, damit die Wochenwelten selbst nicht doppelt auftauchen. Heißen deine Dimensionen anders, trägst du ihre IDs unter generators ein.
  • worldPrefix sorgt dafür, dass die Commands nur Welten anlegen und löschen, deren ID mit weekly_ beginnt. So löscht ein Tippfehler im Script nie eine andere MultiWorld-Welt.
  • lookupCacheLock ist der C2ME-Fix. Ohne C2ME kannst du ihn auf false setzen. Änderungen wirken erst nach einem Neustart.

Dazu kommen drei Konsolen-Commands. MultiWorlds eigenes /mw create will einen Spieler als Absender, der Reset läuft aber nachts, wenn niemand online ist. Die Commands verlangen deshalb Permission Level 4 (die höchste Admin-Stufe) und sind für Konsole und RCON gedacht:

/weeklyworld create <id> <generator> <seed>   z. B. /weeklyworld create weekly_test weeklyworld:weekly_forest 12345
/weeklyworld delete <id>
/weeklyworld generators

Die angelegte Welt heißt danach multiworld:<id>, also zum Beispiel multiworld:weekly_test. Für das Löschen öffnet die Mod die Welt über Fantasy (die Library, auf der MultiWorld aufsetzt) und löscht deren Handle. MultiWorlds eigener Delete funktioniert nämlich nur bei geladenen Welten. Datapack-Dimensionen laden vor dem Moment, in dem MultiWorld seine gespeicherten Welten wieder öffnet. Deshalb finden die Wochenwelten auch nach einem Restart ihren Generator.

Schritt 3: Das Tool konfigurieren

Leg aus der Beispiel-Config deine eigene an und hinterleg das RCON-Passwort in einer Datei, die nur du lesen kannst:

cd ~/minecraft-weekly-world/tools
cp config.example.json config.json
echo '<dein-rcon-passwort>' > .rcon_password && chmod 600 .rcon_password
# alternativ: export WEEKLY_WORLD_RCON_PASSWORD=...

In der config.json sind diese Schlüssel am wichtigsten:

  • server_root und level_name: Server-Ordner und Name des Weltordners. Aktive Spieler zählt das Tool über die Dateien in <level_name>/stats/*.json.
  • rcon: Host, Port und entweder password_env (Name der Umgebungsvariable) oder password_file (relativ zur Config).
  • timezone: die Zeitzone, nach der das Tool die Kalenderwoche bestimmt, etwa Europe/Berlin.
  • datapack: Namespace (Standard weeklyworld), Ausgabedatei und sources, also wo das Tool Biome, Tags und Strukturen liest. Der erste Treffer gewinnt: Welt-Datapacks, globale Datapacks, Mod-Jars, Vanilla-Jar. Die Vanilla-Daten liegen in versions/1.21.1/server-1.21.1.jar oder in der Bundler-server.jar. Liegt deine Vanilla-Jar woanders, passt du den Pfad an.
  • regions: ein Eintrag pro Region mit biome_namespaces, exclude_biomes, exclude_structures, required_structures und extra_structures. Mehr dazu in Schritt 4.
  • rotation und rotation_start: Reihenfolge der Regionen und die ISO-Kalenderwoche der ersten Region, zum Beispiel 2026-W41.
  • tries: Anzahl der Seeds pro Prepare. Lass den Wert bei 5, warum, steht unten bei den Problemen.
  • radius, camp, spawn, announce und after_swap_commands: Spielfläche, Ankunftspunkt, Rückkehrpunkt für Spieler in der alten Welt, Chat-Ankündigung und eigene Befehle nach dem Tausch.

Schritt 4: Regionen festlegen und das Datapack bauen

Jede Region wird eine Datapack-Dimension, zum Beispiel weeklyworld:weekly_forest. Sie nutzt den Generator der Overworld, ersetzt aber jedes Biom durch eine Kopie im eigenen Namespace, also unter einem eigenen Namens-Präfix. Die Kopie von minecraft:plains heißt in der Region forest dann weeklyworld:forest/minecraft/plains. Auf CobbleBox mit Terralith sind das 148 Overworld-Biome pro Region. Im Datapack landet jede Kopie unter diesem Pfad:

data/<namespace>/worldgen/biome/<region>/<original-namespace>/<pfad>.json

# Beispiel:
data/weeklyworld/worldgen/biome/forest/minecraft/plains.json
data/weeklyworld/dimension/weekly_forest.json

Jede Kopie muss außerdem in jedem Biom-Tag landen, in dem das Original steckt. Ein Biom-Tag ist eine benannte Liste von Biomen. Mob-Spawns, bei COBBLEVERSE auch die Cobblemon-Spawns, und viele Strukturen wie Dörfer oder Ruinen fragen nämlich Biom-Tags ab. Fehlen die Kopien dort, bleibt deine neue Welt leer. Das Tool durchsucht alle Quellen aus datapack.sources, löst Tags in Tags auf und trägt jede Kopie mit "replace": false in die Tags ihres Originals ein.

Mit den Kopien steuerst du auch, welche Strukturen wo auftauchen. Strukturen, die Biome direkt beim Namen nennen, landen nicht in den Kopien. So hält CobbleBox die normalen COBBLEVERSE-Arenen aus der Abenteuerwelt raus. Stattdessen bekommt jede Region eigene Kopien der passenden Strukturen mit dichterem Abstand (Spacing 20, Separation 8 Chunks, also Kartenstücke von 16 × 16 Blöcken). Das war nötig, weil die Originale mit ihren 40 Chunks Abstand in einem Test bei 0 von 20 Seeds alle innerhalb von 1.000 Blöcken lagen. In der Config sieht so eine dichtere Kopie so aus:

"forest": {
  "biome_namespaces": ["minecraft"],
  "exclude_biomes": ["minecraft:desert", "minecraft:badlands"],
  "required_structures": ["minecraft:pillager_outpost"],
  "extra_structures": {
    "forest_village": {
      "like": "minecraft:village_taiga",
      "biomes": ["minecraft:forest", "minecraft:birch_forest", "minecraft:taiga"],
      "spacing": 20,
      "separation": 8
    }
  }
}
  • biome_namespaces legt fest, welche Biome kopiert werden. ["*"] heißt alle, ["minecraft"] nur die Vanilla-Biome.
  • exclude_biomes nimmt Biome ganz aus der Region.
  • required_structures sind die Pflicht-Strukturen, nach denen das Tool den Seed auswählt. Die extra_structures zählen automatisch dazu.
  • extra_structures sind dichtere Kopien vorhandener Strukturen, die nur in dieser Region spawnen. Die genannten Biome müssen in der Region kopiert werden.
  • exclude_structures pinnt eine Struktur, die ihre Biome über einen Tag angibt, auf ihre Original-Biome. Sonst erreicht sie die Kopien über den Tag doch. Das ändert die Strukturdatei für alle Dimensionen.

Mit einer Terrain-Mod wie Terralith steht die Biom-Liste direkt in deren overworld.json, dann musst du nichts weiter tun. Bei Vanilla-Terrain gibt es in der Server-Jar keine eigene overworld.json. Der Overworld-Generator steht in worldgen/world_preset/normal.json und verweist nur auf das eingebaute Biom-Preset, die eigentliche Liste steckt im Code. Das Preset liest das Tool selbst aus. Die Biom-Liste erzeugst du einmal mit dem Datengenerator der Vanilla-Server-Jar (dafür brauchst du Java 21). Führ den Befehl im Server-Ordner aus und trag den absoluten Pfad der Datei in der Config unter datapack.overworld_biome_parameters ein, denn relative Pfade sucht das Tool im Ordner tools/:

java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports
# Ergebnis: /srv/minecraft/generated/reports/biome_parameters/minecraft/overworld.json

Findest du die Vanilla-Jar für datapack.sources nicht, hilft find /srv/minecraft -name '*.jar' -path '*server*'. Die Bundler-Datei server.jar geht auch, das Tool öffnet sie selbst.

Dann baust du das Datapack. Der erste Lauf mit --dry-run zeigt nur, was entstehen würde:

cd ~/minecraft-weekly-world/tools
python3 weekly_world.py build-datapack --dry-run
python3 weekly_world.py build-datapack
# schreibt world/datapacks/weekly_world.zip

Alles landet in einer einzigen Zip-Datei unter world/datapacks/, damit du beim Hochladen eine Datei schiebst und dich nicht mit hunderten Einzeldateien herumschlägst. Die pack.mcmeta darin hat "pack_format": 48, das ist das Datapack-Format von Minecraft 1.21.1. Vor dem Schreiben prüft das Tool die erzeugten Dateien, zum Beispiel ob jede Struktur das Feld spawn_overrides hat.

Danach startest du den Server neu. Worldgen, also Dimensionen, Biome und Strukturen, liest Minecraft nur beim Start, ein /reload reicht nicht. Im Log muss pro Region eine Zeile wie MultiWorld generator registered: weeklyworld:weekly_forest stehen.

Für den Ankunftspunkt liegt im Repo ein einfaches Beispiel-Camp aus Vanilla-Blöcken. Kopier examples/camp-datapack/ nach world/datapacks/ und lass camp.function auf weeklyworld:camp_build stehen. Willst du kein Camp, setz camp.function auf null.

Schritt 5: Prepare, also den besten Seed finden

Liegen die Pflicht-Strukturen der Region 6.000 Blöcke entfernt, ist die Woche gelaufen, auch wenn der Seed sonst gut aussieht. prepare legt deshalb mehrere Welten mit zufälligem Seed an, maximal tries Stück mit IDs wie weekly_2026w42_1, und misst jede mit /locate structure. Der Befehl findet Strukturen, ohne Chunks zu laden, und ist dadurch schnell. Gewinner ist der Seed, bei dem die am weitesten entfernte Pflicht-Struktur am nächsten an 0/0 liegt. Alle anderen Welten werden sofort wieder gelöscht. Passt ein Seed schon in die Fläche, die die Spielerzahl verlangt, hört das Tool früher auf. Per RCON schickt es dafür diese Befehle:

weeklyworld create weekly_2026w42_1 weeklyworld:weekly_forest <seed>
execute in multiworld:weekly_2026w42_1 positioned 0 80 0 run locate structure minecraft:pillager_outpost
weeklyworld delete weekly_2026w42_1

Die Größe der Spielfläche hängt an der Spielerzahl: rund 500 × 500 Blöcke pro aktivem Spieler der letzten 7 Tage, in Schritten von 250, mindestens 1.000 und höchstens 4.000 Blöcke Radius. Auf CobbleBox kommt die Obergrenze von der World Border (dem Weltrand) bei ±5.000, die für alle Dimensionen gilt. Reicht der Radius nicht für alle Pflicht-Strukturen, wird er vergrößert. Dabei kommen 64 Blöcke Rand dazu, damit auch die Gebäude selbst mit generiert werden. Passt dann immer noch nichts unter 4.000, bleibt die alte Welt eine weitere Woche offen. Alle diese Werte stehen in der Config unter radius.

Danach pregeneriert das Tool die Fläche mit Chunky (einer Mod, die Chunks vorab erzeugt). Als Welt gibst du Chunky die volle ID mit dem Namespace multiworld: an:

chunky world multiworld:weekly_2026w42_1
chunky center 0 0
chunky shape square
chunky radius 1500
chunky start
chunky progress

Per chunky progress wartet das Tool, bis keine Aufgabe mehr läuft. Auf CobbleBox schafft Chunky dabei rund 380 Chunks pro Sekunde. Zum Schluss baut das Tool das Camp als Ankunftspunkt. Es sucht sich den Punkt nahe 0/0, der mindestens 128 Blöcke (camp.clearance) von jeder Pflicht-Struktur entfernt ist, und führt dort die Camp-Funktion aus. Der erste Versuch auf CobbleBox ohne diesen Abstand hat das Camp mitten in eine Arena 30 Blöcke weiter geschnitten. Das CobbleBox-Camp ist größer als das Beispiel im Repo: Plattform, Lagerfeuer, zwei Heilmaschinen, Bänke, Laternen und ein NPC (eine vom Server gesteuerte Figur).

📸 [Screenshot: Camp in der Abenteuerwelt mit Lagerfeuer, Heilmaschinen und NPC, Lion fügt ein]

Bevor du dich auf den Timer verlässt, probier die Schritte von Hand. status zeigt dir den Zustand, die Spielerzahl, den Radius und die Region der kommenden Woche. --dry-run gibt die RCON-Befehle nur aus, ohne sie zu senden:

python3 weekly_world.py status
python3 weekly_world.py prepare --dry-run
python3 weekly_world.py prepare            # optional: --region forest --radius 1500

Ein zweiter Lauf in derselben Woche macht nichts. Der Zustand liegt in weekly_world_state.json mit den Feldern current, next und history. Eine Lock-Datei mit der Prozess-ID verhindert, dass zwei Prepares gleichzeitig laufen.

Schritt 6: Swap, also die Welten tauschen

Der Tausch ist kurz. Zuerst holt swap alle Spieler, die noch in der alten Welt stehen, zum Rückkehrpunkt aus spawn in der Config. at @s steht dabei vorn, weil if dimension die Dimension der aktuellen Position prüft. in <dimension> legt fest, in welche Dimension tp teleportiert:

execute as @a at @s if dimension multiworld:weekly_2026w41_2 in minecraft:overworld run tp @s 0.5 80 0.5
weeklyworld delete weekly_2026w41_2

Dann löscht das Tool die alte Welt, führt deine after_swap_commands aus und kündigt die neue Woche per tellraw im Chat an. In beiden kannst du die Platzhalter {world}, {region}, {x}, {y}, {z}, {week}, {seed} und {radius} nutzen. Läuft noch ein Prepare, wartet swap bis zu swap_wait_for_prepare_s Sekunden. Wurde nichts vorbereitet, bleibt die aktuelle Welt. Von Hand startest du den Tausch mit:

python3 weekly_world.py swap --dry-run
python3 weekly_world.py swap

Schritt 7: Der Zeitplan mit systemd

Die Units im Ordner systemd/ starten Prepare sonntags um 23:00 und Swap montags um 05:00. Ein systemd-Timer ist eine Art Wecker unter Linux, der einen Service regelmäßig startet. Die Units laufen als User-Units, du brauchst also kein root für den Betrieb:

mkdir -p ~/.config/systemd/user
cp ~/minecraft-weekly-world/systemd/*.service ~/minecraft-weekly-world/systemd/*.timer ~/.config/systemd/user/
# Pfade in den .service-Dateien anpassen, falls das Repo nicht unter ~/minecraft-weekly-world liegt
systemctl --user daemon-reload
systemctl --user enable --now weekly-world-prepare.timer weekly-world-swap.timer
sudo loginctl enable-linger "$USER"

Ohne enable-linger läuft die systemd-Instanz deines Users und damit die Timer nur, solange du eingeloggt bist. Mit Linger startet sie beim Booten und läuft weiter, wenn du dich abmeldest. Persistent=true in den Timern holt verpasste Läufe nach einer Downtime nach. Das RCON-Passwort kannst du statt in .rcon_password auch als WEEKLY_WORLD_RCON_PASSWORD=... in ~/.config/weekly-world.env ablegen (mit chmod 600), die Units lesen diese Datei ein.

Plane einen Server-Restart vor dem Swap ein, auf CobbleBox läuft der täglich nachts. MultiWorld lädt gespeicherte Welten beim Start wieder, und der Restart gibt die geleakten Threads frei (siehe unten). Auf CobbleBox hängt der Ablauf übrigens an einem bestehenden systemd-Timer, der sowieso Server-Daten synchronisiert und bei jedem Lauf die Uhrzeit prüft. Dort kommt sonntags um 18:00 noch eine Warnung an alle Spieler in der Abenteuerwelt dazu. Die Kalenderwoche für die neue Welt rechnet das Tool am Sonntag schon auf den folgenden Montag um.

Schritt 8: Der Eingang für deine Spieler

Wie Spieler in die Welt kommen, regelt das Tool bewusst nicht. Auf CobbleBox kommen Spieler über einen NPC am Spawn in die Welt, den Expeditionsleiter. Er öffnet ein GUI-Fenster (ein Menü mit Buttons), das auch per /abenteuer erreichbar ist. „Reisen“ bringt dich zum Camp der aktuellen Woche. Das klappt nur, wenn du höchstens 8 Blöcke vom NPC entfernt stehst und die Welt freigeschaltet ist. „Zurück zum Spawn“ bringt dich in die Hauptwelt. Der NPC im Camp öffnet dasselbe Fenster, du kommst also auf demselben Weg zurück.

📸 [Screenshot: Expeditionsleiter am Spawn mit geöffnetem Reise-Fenster, Lion fügt ein]

Für deinen eigenen Eingang speichert die Beispiel-Config nach jedem Swap Welt und Ankunftspunkt im Command Storage weeklyworld:current. Eine Makro-Funktion in deinem Datapack kann die Spieler damit hinbringen, zum Beispiel data/<dein-namespace>/function/travel.mcfunction:

# Aufruf: function <dein-namespace>:travel with storage weeklyworld:current
$execute in $(world) run tp @s $(x) $(y) $(z)

Die Funktion hängst du an einen NPC, ein Schild oder einen Befehl deiner Wahl. Den Rückweg baust du genauso mit execute in minecraft:overworld run tp @s ....

So prüfst du, ob es läuft

  • Im Server-Log stehen nach dem Start RCON running on ..., pro Region MultiWorld generator registered: weeklyworld:weekly_<region> und mit eingeschaltetem Lock Lookup cache lock: active.
  • In der Server-Konsole listet weeklyworld generators alle Generatoren auf.
  • Ein Testlauf von Hand: weeklyworld create weekly_test weeklyworld:weekly_forest 12345 in der Konsole, dann im Spiel als OP /execute in multiworld:weekly_test run tp @s 0 120 0. Du solltest in der Landschaft der Region landen. Danach wieder raus und weeklyworld delete weekly_test.
  • python3 weekly_world.py status zeigt Spielerzahl, Radius und die Region der kommenden Woche. Nach einem Prepare steht die neue Welt unter next, nach einem Swap unter current.
  • systemctl --user list-timers zeigt die beiden Timer mit dem nächsten Termin, loginctl show-user "$USER" --property=Linger sollte Linger=yes ausgeben.
  • Die Ausgabe der Läufe liest du mit journalctl --user -u weekly-world-prepare.service und journalctl --user -u weekly-world-swap.service.

Was schiefging

MultiWorld leakt Threads bei jedem Create und Delete

Die erste Version hat 40 Seeds getestet. Jede Probe ist eine echte MultiWorld-Welt. Jedes Erstellen und Löschen lässt Threads zurück (parallele Arbeitsstränge eines Programms), die erst ein Restart freigibt. Nach 40 Versuchen war der Server bei „unable to create native thread“. Auf CobbleBox laufen deshalb nur noch 5 Versuche pro Woche. Das reicht, weil mit den dichter gesetzten Arena-Kopien schon die ersten Seeds passen. Im Repo steht tries deshalb auf 5, und das Tool warnt ab einem Wert über 10. Halte die Anzahl der Versuche klein, setz deine Pflicht-Strukturen dicht genug und plane den Tausch nach einem Restart.

systemd killt Hintergrund-Jobs eines Oneshot-Service

Am 12.10. fand der Swap nicht statt, ein Spieler hat es gemeldet. Vereinfacht gesagt: Linux hat den Vorbereitungs-Job jedes Mal abgeräumt, bevor er fertig war. Der Timer startet einen Service vom Typ oneshot (läuft einmal und beendet sich). Dieser hat das Prepare als „detached“ Prozess im Hintergrund gestartet. Sobald der Oneshot fertig ist, räumt systemd seine ganze cgroup ab, inklusive aller Kindprozesse. Eine cgroup ist die Gruppe aller Prozesse eines Dienstes. Das Prepare starb also jede Stunde nach wenigen Sekunden, zurück blieben ein leeres Log und eine verwaiste Lock-Datei. Zwei andere Hintergrund-Jobs hatten denselben Bug.

Im Repo ist das auf zwei Wegen gelöst. Die mitgelieferte weekly-world-prepare.service führt Prepare direkt als Oneshot aus und wartet mit TimeoutStartSec=4h, bis es fertig ist. Startest du Prepare aus einem eigenen Script heraus, nimm prepare --background. Das startet den Job per systemd-run --user als eigene transiente Unit, und die läuft in ihrer eigenen cgroup weiter. Vereinfacht macht das Tool dabei Folgendes:

import subprocess

def spawn_background(unit, cmd, log):
    """Startet einen Job, der den Oneshot-Service überlebt."""
    subprocess.run([
        "systemd-run", "--user", "--collect",
        "--unit", unit,
        "-p", f"StandardOutput=append:{log}",
        "-p", f"StandardError=append:{log}",
        *cmd,
    ], check=True)

spawn_background("weekly-world-prepare-1",
                 ["python3", "weekly_world.py", "--config", "config.json", "prepare"],
                 "weekly_world_state_prepare.log")

Außerdem steht in der Lock-Datei jetzt die Prozess-ID. Ist der Prozess weg, übernimmt der nächste Lauf den Lock, und eine verwaiste Lock-Datei blockiert nichts mehr.

Worldgen lädt nur beim Serverstart

Biome, Dimensionen, Strukturen und Structure Sets sind Worldgen-Registries (die Bausteine der Weltgenerierung). Die liest Minecraft nur beim Start, ein /reload hilft nicht. Neue Regionen kommen also so ins Spiel: Region in config.json unter regions ergänzen, in rotation eintragen, build-datapack neu laufen lassen und den nächsten Restart abwarten. Auf CobbleBox kamen Johto, Hoenn und Sinnoh an einem Abend dazu und waren nach dem nächsten Restart verfügbar.

Datapack-JSON vor dem Restart prüfen

Weil Worldgen-Fehler erst beim Start auffallen, blockiert ein kaputtes Datapack den ganzen Server. So lief es bei den eigenen Strukturen: Ihnen fehlte das Feld spawn_overrides, das Minecraft bei jeder Struktur verlangt, auch wenn es leer ist. Der Server startete deshalb nicht. Seitdem setzt das Script es immer mit st.setdefault("spawn_overrides", {}), und vor jedem Restart wird das JSON validiert. Das Tool im Repo prüft seine Ausgabe beim Bauen. Teste ein neues Datapack trotzdem zuerst auf einer Kopie deines Servers und schau nach dem Start auf die Zeilen MultiWorld generator registered.

Selbst ausprobieren

Kurz nach dem ersten Start der Abenteuerwelt gab es außerdem Watchdog-Crashes durch C2ME. Der Watchdog stoppt den Server, wenn er zu lange hängt. Wie du so einen Crash im Stack Trace (der Fehlerliste, die zeigt, wo es knallt) findest und mit einem kleinen Mixin fixt, liest du im Guide zum C2ME Watchdog Crash. Ein Mixin ist ein kleiner Patch, der beim Start den Code einer anderen Mod verändert. Die Mod aus dem Repo bringt diesen Fix schon mit.

Code, Beispiel-Config und systemd-Units findest du im Repo mapplebox/minecraft-weekly-world auf GitHub. Wenn du die Abenteuerwelt in Aktion sehen willst, schau auf CobbleBox vorbei: Die Serveradresse ist 2mc.mapplebox.de, der Expeditionsleiter steht am Spawn. Falls du noch gar keinen Server hast, fang mit meinem Guide Cobblemon Server erstellen an. Dort zeige ich dir das Hosting mit dem Pelican Panel (eine Weboberfläche für Game-Server). Die Rotation auf CobbleBox läuft seit Kalenderwoche 41 mit Kanto als erster Region.

Guide teilen

Hat dir der Guide geholfen? Dann spendier mir gern einen Kaffee auf Ko-fi. Damit bleibt MappleBox werbefrei.

Ähnliche Beiträge