Game record
Game is the record one of these per minigame. It bundles the id, display name, accent colour, GameKind (singleton vs multi-lobby), LobbyConfig, StagingConfig, a PhaseFlow, and optional GameHooks. GameRegistry reads these fields and auto-builds the hub pad, the /conduit join <id> subcommand, and routes engine events into the hook callbacks.
When to use it
Section titled “When to use it”- You’re registering a new minigame and want the standard hub-lobby-arena wiring.
- You want lifecycle hooks (
onJoin,onDamage,onPhase,onButton) routed automatically. - You’re picking between the built-in phase flows or supplying your own.
package me.zlex.conduit.game;
public record Game( String id, Component displayName, int accentColor, GameKind kind, LobbyConfig lobby, StagingConfig staging, PhaseFlow flow, GameHooks hooks) {
public static Builder builder(String id, String displayName);
public static final class Builder { public Builder accent(int argb); public Builder kind(GameKind k); public Builder lobby(LobbyConfig l); public Builder staging(StagingConfig s); public Builder flow(PhaseFlow f); public Builder hooks(GameHooks h); public Game build(); }}GameHooks is a 10-field record of nullable callbacks fired at well-defined moments — onZoneEntry, onPadEntry, onJoin, onLeave, onDamage, onEliminate, onPhase, onButton, onLobbyBuilt, onTearDown. Build via GameHooks.builder() and only wire what you need.
Example
Section titled “Example”import me.zlex.conduit.game.Game;import me.zlex.conduit.game.GameHooks;import me.zlex.conduit.game.GameKind;import me.zlex.conduit.game.GameRegistry;import me.zlex.conduit.game.LobbyConfig;import net.fabricmc.api.ModInitializer;import net.minecraft.world.item.Items;
import java.util.List;
public final class SprintRaceMod implements ModInitializer {
@Override public void onInitialize() { Game game = Game.builder("sprint-race", "Sprint Race") .accent(0xFFFFD700) .kind(GameKind.MULTI_LOBBY) .lobby(LobbyConfig.defaults("SPRINT RACE") .withMaxPlayers(10) .withPad(Items.YELLOW_WOOL) .withType("Race") .withTagline(List.of("First 3 to the finish line win."))) .hooks(GameHooks.builder() .onJoin((inst, p) -> SprintRound.onJoin(inst, p)) .onLeave((inst, p) -> SprintRound.onLeave(inst, p)) .onPhase((inst, prev, next) -> SprintRound.onPhase(inst, prev, next)) .build()) .build();
GameRegistry.register(game); }}- If you don’t supply a
PhaseFlow, the builder picksPhaseFlow.defaultMulti()forMULTI_LOBBYanddefaultSingleton()forSINGLETON. GameHooks.none()is the safe empty-hooks value — easier than nullable-checking every field.- The
accentColorfield is reused for chat highlights, the pad’s particle ring, and the lobby header bar — pick a colour that reads well in all three.