Zimplex
Dokumentation

Development

Repository-Zugriff und Entwicklungsstart fuer das Team

Das Projekt wird intern ueber den Zimplex Nexus verteilt. Fuer einen echten Entwicklungsstart braucht dein Setup deshalb zuerst Zugriff auf nexus.zimplex.net und danach erst den normalen Build- und Run-Workflow.

Repository-Quelle

Die Artefakte und der projektbezogene Zugriff laufen ueber nexus.zimplex.net. Ohne diese Quelle ist kein vollstaendiger Projektstart moeglich.

Zugangspolitik

Benutzername und Passwort werden nur an Entwickler des Teams herausgegeben. Zugangsdaten gehoeren nicht in das Repository und nicht in die oeffentliche Dokumentation.

  1. Zugang fuer nexus.zimplex.net intern anfordern.
  2. Repository beziehen und die lokalen Nexus-Credentials in deiner Build-Umgebung hinterlegen.
  3. Danach den Gradle-Workflow aus dem Abschnitt Schnellstart verwenden.
Wichtig: Diese Website dokumentiert bewusst nur die Quelle und die Zugriffspolitik. Die konkreten Zugangsdaten werden nur intern verteilt.

Schnellstart

Build, Test, Run und Bundle auf einen Blick

Sobald der Repository-Zugriff steht, laeuft der eigentliche Einstieg ueber Java 25, Gradle und die bekannten Runtime-Verzeichnisse unter build/, config/, data/ und extensions/.

Voraussetzungen

  • Java 25
  • Zugriff auf die Maven-Repositories aus dem Build
  • Schreibrechte fuer build/, config/, data/ und extensions/

Run-Varianten

  • :run startet den normalen Service-Run.
  • :runStandaloneLocal startet bewusst ohne CloudNet-Core-Bootstrap.
  • Unter Windows laufen die Kommandos mit .\gradlew.bat.
./gradlew :minigames-server:test
./gradlew :minigames-server:run
./gradlew :minigames-server:assemble
./gradlew :minigames-server:assembleStandaloneLocal
java -jar application.jar --migrate-stats-to-cloudnet
  1. Tests oder Run ueber Gradle ausfuehren.
  2. config/minigames.conf und optional config/extensions/*.conf pruefen.
  3. Bei Bundle-Deployments aus dem erzeugten Zielverzeichnis starten.
  4. Fuer CloudNet-Migrationen das gebaute Bundle-Verzeichnis als Arbeitsbasis verwenden.

Grundlagen

Core, Module und das Laufzeitmodell der Engine

Die Engine sitzt nicht isoliert in einem eigenen Monorepo, sondern erweitert das bestehende Minestom-Setup. Ein Prozess hostet genau eine aktive MatchSession und faehrt nach Match-Ende kontrolliert herunter.

minigames-extension-api

Oeffentliche SPI fuer Erweiterungen, Services und Spielmodi.

minigames-server

Server-Main, Match-System, Stats-Backends und Bundle-Build.

minigames-extension-cloudnet

Eingebaute CloudNet-Anbindung fuer Service-State und Startup-Infos.

minigames-extension-perms

Permissions-Extension mit Provider-Kette und LuckPerms-Bootstrap.

Bootstrap in Kurzform

  1. Minestom startet und fuehrt MinestomPvP.init(true, false) genau einmal aus.
  2. Die Gesamt-Config wird geladen und validiert.
  3. Optional werden CloudNetAccess und ein DatabaseProvider aufgeloest.
  4. Das Stats-Backend wird zwischen JDBC und CloudNet ausgewaehlt.
  5. Template-Registry, Setups und Runtime-Services werden aufgebaut.
  6. Extensions, Commands und anschliessend der eigentliche Service-Start folgen.
Laufzeitmodell: Ein Prozess hostet genau eine MatchSession mit einer neutralen Lobby-Instance und hoechstens einer aktiven Match-Instance. Ein In-Process-Reset fuer die naechste Runde ist nicht vorgesehen.

Gameplay

Match-Phasen, Spielerfluss und Sieglogik

Oeffentlich arbeitet die Engine mit den Game-Phasen Lobby, Preparation, Ingame und End. Intern mappt der Core diese auf seinen Session-Lifecycle und steuert damit Join-Logik, Map-Aufloesung, Respawn und Match-Ende.

Lobby Preparation Ingame End

Vor Match-Start

  • Spieler joinen zunaechst in eine neutrale Lobby-Instance.
  • Bis max-players werden Spieler kompetitiv markiert, weitere Spieler sind Spectator.
  • In der Lobby liegen Selector-Items fuer Kits und optional Map-Voting bereit.
  • Faellt die Mindestspielerzahl waehrend der Vorbereitung, springt die Session auf Lobby zurueck.

Ab Match-Start

  • Die finale Map wird direkt vor Ingame aufgeloest.
  • Das gewaehlt oder erzwungene Setup wird ueber den WorldLoader geladen.
  • Nur kompetitive und noch online befindliche Spieler kommen in die Runde.
  • Neue Joins waehrend laufender oder endender Matches werden sofort Spectator.

FFA

  • Jeder spielt fuer sich.
  • Spawns rotieren ueber ffa-spawns.
  • Friendly Fire ist kein Thema.

TEAM

  • Spieler werden automatisch ins aktuell kleinste Team verteilt.
  • Bei Gleichstand entscheidet die Team-ID lexikographisch.
  • Friendly Fire wird blockiert.
Thema Wesentliches Verhalten
VictoryMode LAST_ALIVE oder SCORE_LIMIT
RespawnMode ELIMINATION oder DELAYED; LAST_ALIVE + DELAYED ist ungueltig
Match-Ende Siegbedingung, Zeitlimit, leeres Match oder /mg end
/mg /start /forcemap <mapId> /setup ...

Betrieb

Konfiguration, Permissions, CloudNet und Deployment

Im Betrieb greifen Konfiguration, Startup-Modus, Permissions, CloudNet-Bridge und Bundle-Struktur direkt ineinander. Fuer lokale Tests gibt es einen bewusst abgespeckten Standalone-Modus.

Konfigurationsdateien

config/minigames.conf, config/extensions/cloudnet.conf und config/extensions/perms.conf bilden den Standardzustand.

CloudNet

Optional. Ohne verfuegbare CloudNet-Klassen laeuft der Server lokal weiter, nur ohne Bridge-Zugriffe und CloudNet-Database-Provider.

Permissions

Provider-Reihenfolge: Op-Umgebungsvariable, LuckPermsMinestom und danach LuckPermsProvider.

Bundle-Ziel

minigames-server/build/bundle ist das vorgesehene Deployment-Artefakt.

Bereich Wichtig fuer den Betrieb
runtime.mode service fuer normalen Betrieb, standalone-local fuer lokalen Offline-Run ohne CloudNet-Core-Bootstrap
server.forwarding-mode modern braucht ein gesetztes velocity-secret
stats.backend auto, jdbc oder cloudnet
Permissions Wichtige Nodes: minigames.command.reload, .start, .forcemap, .setup, .end, .stats.*
config/
|-- minigames.conf
|-- extensions/
|   |-- cloudnet.conf
|   `-- perms.conf

Bundle:
|-- application.jar
|-- config/
|-- extensions/
|-- data/
`-- luckperms/
  1. :minigames-server:test ausfuehren.
  2. :minigames-server:assemble bauen.
  3. Config-Differenzen, Setups und Permissions pruefen.
  4. JARs und Konfiguration ins Ziel deployen.
  5. Bei Bedarf Stats ueber java -jar application.jar --migrate-stats-to-cloudnet migrieren.
Website: Diese Doku bleibt statisch und kann direkt ueber GitHub Pages aus dem Repository-Root gehostet werden.

API Reference

MinigamesExtensionContext

Das ist der zentrale Einstiegspunkt fuer Spielmodi und Extensions. Von hier aus werden alle relevanten Runtime-Services und Infrastrukturzugaenge bezogen.

phaseController()
gameSetupRegistry()
setupService()
matchRuntime()
matchQuery()
matchSessionEvents()
playerIdentityService()
inventoryService()
countdownService()
itemSpawnerService()
kitService()
perkService()
lobbySelectionService()
particleService()
mobService()
statsService()
templateRegistry()
cloudNetAccess()

phaseController()

Gibt den Einstieg in die feste Game-Phasensteuerung frei und verbindet Extensions mit Lobby, Preparation, Ingame und End.

gameSetupRegistry() / setupService()

gameSetupRegistry() stellt die laufende Map-Registry bereit, setupService() die persistente Quelle mit Editor- und Publish-API.

matchRuntime() / matchQuery()

matchRuntime() liefert die aktuelle Runtime, sofern bereits eine Session existiert. matchQuery() ist die read-only Sicht auf Teilnehmer, Setup, Phasen und Combat-Abfragen.

matchSessionEvents()

Lose gekoppelte Beobachtung fuer Match-Erzeugung, Lobby-Start, Preparation-Start, Match-Start, Eliminierung, Match-Ende und geplanten Shutdown.

playerIdentityService() / inventoryService()

Spieleridentitaet, DisplayName und Skin lassen sich zur Laufzeit aendern; GUI-Menus werden ueber den Inventory-Service mit Builder und Hooks erstellt.

countdownService()

Erzeugt wiederverwendbare Countdowns mit IDs, Start-, Tick-, Complete- und Cancel-Callbacks.

itemSpawnerService()

Deckt Generator-Szenarien mit Stages, Spawn-Modi und manueller Stage-Steuerung ab.

kitService() / perkService()

Kits liefern feste Loadouts, Perks freie Runtime-Boni mit Apply- und Remove-Hooks.

lobbySelectionService()

Fuehrt den pre-game State fuer Kitwahl, Map-Votes, forcedMap und finale Kartenauflosung.

statsService() / templateRegistry() / cloudNetAccess()

Diese Getter verbinden die Erweiterung mit Persistenz, Template-Metadaten und optionaler CloudNet-Bridge.

Wichtig: Das bekannte GameModeContext bleibt kompatibel, ist intern aber logisch in Query- und Control-Sicht getrennt. Neue Integrationen sollten die schlankeren APIs bevorzugen.

API Reference

GamePhaseController / PhaseManager

Der Controller steuert die oeffentlichen Game-Phasen. Die vorhandene Dokumentation nennt nur einen Teil der exakten Methodennamen explizit; deshalb ist diese Referenz hier bewusst verhaltensorientiert aufgebaut.

aktuelle Phase lesen
Phase-Definitionen lesen
Listener fuer Phasenwechsel registrieren
Preparation aktivieren
Ingame aktivieren
End aktivieren
Preparation -> Lobby
advancePhase()

Phasen lesen

Der Controller liefert sowohl die aktuelle Game-Phase als auch die zugehoerigen Definitionen fuer Anzeige, Dauer, Join-Verhalten und CloudNet-State.

Phasenwechsel abonnieren

Extensions koennen Listener fuer Phasenwechsel registrieren und darauf Telemetrie, UI oder mode-spezifische Logik aufsetzen.

Transitionen

Direkte Wechsel sind auf Preparation, Ingame und End ausgelegt. Die Rueckkehr Preparation -> Lobby ist erlaubt; Rueckspruenge aus Ingame oder End nicht.

advancePhase()

Durchlaeuft die feste Standard-Reihenfolge Lobby -> Preparation -> Ingame -> End und ist der sauberste Weg, um die vorgesehene Match-Folge beizubehalten.

API Reference

SetupService

Der SetupService ist die persistente Schicht fuer admin-gepflegte Maps. Er sitzt vor der Runtime-Registry und verbindet Dateisystem, Edit-Sessions und Runtime-Publishing.

storedSetups()
find(id)
create(id)
edit(id)
save(session)
publish(id)
publishAll()
setupDirectory(id)

storedSetups() / find(id)

Liest bereits gespeicherte Setups aus dem Dateisystem und liefert die persistente Sicht auf Maps, Spawns, Marker und Metadaten.

create(id) / edit(id)

Oeffnet neue oder bestehende Edit-Sessions. Dort lassen sich Display-Name, Template-IDs, Weltquelle, Spectator-Spawns, Player-Spawns, Team-Spawns, Item-Spawns und Metadaten mutieren.

save(session) / publish(id) / publishAll()

save(session) schreibt nur auf Platte. publish(id) und publishAll() registrieren Setups zusaetzlich sofort fuer die laufende Runtime.

setupDirectory(id)

Loest das Zielverzeichnis eines Setups auf, zum Beispiel fuer Weltquellen, Schematic-Dateien oder weitere assets im Setup-Kontext.

API Reference

InventoryService

Der Inventory-Service baut GUI-Menus fuer Kitwahl, Voting oder Admin-Steuerung, ohne dass Extensions direkt an eine konkrete GUI-Library gekoppelt werden.

title(...)
item(slot, itemStack)
fill(itemStack)
cancelAllClicks(...)
closeOnClick(...)
globale Click-Handler
slot-spezifische Click-Handler
Open-, Close- und Item-Change-Handler

InventoryView:
inventory()
open(player)
setItem(slot, itemStack)

Builder API

Mit title(...), item(...) und fill(...) wird das Menu selbst aufgebaut. cancelAllClicks(...) und closeOnClick(...) steuern das generelle Klickverhalten.

Lifecycle-Hooks

Globale und slot-spezifische Click-Handler sowie Open-, Close- und Item-Change-Hooks erlauben es, Menus in Gameplay- und Admin-Flows einzubetten.

InventoryView

inventory() liefert das gebaute Inventory, open(player) oeffnet es fuer einen Spieler und setItem(slot, itemStack) aktualisiert Slots waehrend der Laufzeit.

API Reference

CountdownService

Der Countdown-Service erzeugt wiederverwendbare Countdowns per ID und eignet sich fuer Vorbereitung, Sonderereignisse oder mode-spezifische Eventfenster.

Builder:
durationSeconds(...)
listener(...)
onStart(...)
onTick(...)
onComplete(...)
onCancel(...)

CountdownHandle:
start()
cancel()
restart()
running()
remainingSeconds()

Service:
find(id)
countdowns()

Builder

Der Builder definiert Dauer und Listener. Darueber haengst du Start-, Tick-, Complete- und Cancel-Logik an einen eindeutig adressierbaren Countdown.

Lifecycle-Callbacks

onStart(...), onTick(...), onComplete(...) und onCancel(...) kapseln die Match- oder UI-Reaktionen pro Statuswechsel.

CountdownHandle

Mit start(), cancel() und restart() steuerst du die Laufzeit. running() und remainingSeconds() liefern den aktuellen Zustand.

find(id) / countdowns()

Der Service kann Countdowns spaeter wieder finden oder als komplette Sammlung fuer Monitoring, Debugging oder zentrale Steuerung bereitstellen.

API Reference

ItemSpawnerService

Der ItemSpawner-Service deckt Generator-Szenarien wie Single-Drops, spaetere Item-Upgrades und gezielte Give-to-Nearby-Mechaniken ab.

Stage:
id
itemStack
amountPerSpawn
interval
unlockAfter

Spawn-Modi:
GROUND_DROP
GIVE_TO_NEARBY_PLAYERS

Runtime:
setStage(...)
clearStageOverride()
spawnNow()
start()
stop()

Stages

Ein Spawner ist als Stage-Folge aufgebaut. Jede Stage definiert Item, Menge, Spawn-Intervall und den Zeitpunkt, ab dem sie aktiviert wird.

Builder-Konfiguration

Freie Konfiguration fuer Instance, Position, Pickup-Delay, Initial-Velocity und Merge-Verhalten erlaubt sehr unterschiedliche Generator-Typen.

Runtime-Steuerung

start() und stop() steuern laufende Generatoren. spawnNow() erzwingt einen sofortigen Drop. setStage(...) und clearStageOverride() setzen manuelle Stage-Wechsel.

Spawn-Modi

GROUND_DROP legt Items in die Welt, GIVE_TO_NEARBY_PLAYERS gibt sie in einem definierten Radius direkt an Spieler aus.

API Reference

KitService und PerkService

Beide Services kapseln spielmodus-spezifische Spielerzustaende, aber mit unterschiedlicher Starrheit: Kits liefern feste Loadouts, Perks freie Runtime-Boni.

KitService

builder(id), register(definition), find(id), kits(), apply(player, id|definition)

Kits enthalten Inventory-Slots, Equipment, Potion-Effekte und freie Metadaten. Die Flags clearInventory und clearEffects steuern, wie aggressiv alte Zustaende ueberschrieben werden.

PerkService

register(...), find(...), perks(), active(player), apply(player, ...), remove(player, ...), removeAll(player)

Perks bestehen aus ID, optionalem Display-Namen, Beschreibung, Metadaten und den Hooks onApply und onRemove. Damit lassen sich Bonus-Items, Tags, Effekte oder freie Runtime-Flags kapseln.

Lobby-Integration: Die eingebaute Lobby zeigt nur Kits, deren IDs im Template unter allowed-kit-ids freigegeben sind.

API Reference

StatsService

Der StatsService ist die oeffentliche Persistenz-SPI. Im aktuellen Stand kann die Engine zwischen JDBC und CloudNet-Dokumenten als Backend umschalten.

recordMatch(MatchRecord)
loadPlayerTotals(UUID playerUuid)
loadTeamTotals(String templateId, String teamId)

recordMatch(MatchRecord)

Persistiert Match-Kopfdaten, beteiligte Spieler, Team-Stats und Aggregatwerte. Der Write erfolgt genau einmal pro Match-ID beim Match-Ende.

loadPlayerTotals(...) / loadTeamTotals(...)

Laden aggregierte Spieler- oder Teamwerte und bilden damit die Grundlage fuer Kommandos wie /mg stats oder mode-spezifische Auswertungen.

Backends

Moeglich sind SqlStatsService und CloudNetDocumentStatsService. auto bevorzugt CloudNet und faellt sonst auf JDBC zurueck.

Aktuelle Stat-Keys

Der Core verwendet derzeit unter anderem kills, deaths, assists, damage_dealt, damage_taken, hits, wins, losses, draws und score.