Lobby engine
LobbyEngine is the small registry that tracks which lobby each player belongs to. It owns the lobbyId → BaseLobby map and the playerId → lobbyId reverse lookup, plus the join / leave / disband operations. The class is intentionally minimal — game logic lives in your BaseLobby subclass and your phase handlers; this is just bookkeeping.
When to use it
Section titled “When to use it”- You’re registering a freshly-built lobby so the engine can look it up by player.
- You need to find “what lobby is this player in” from an event handler.
- You’re disbanding a lobby after the game ends.
package me.zlex.conduit.lobby;
public final class LobbyEngine { public static void register(BaseLobby lobby); public static BaseLobby getById(UUID lobbyId); public static BaseLobby getByPlayer(UUID playerId); public static void join(UUID playerId, UUID lobbyId); public static void leave(UUID playerId); public static void disband(UUID lobbyId); public static Collection<BaseLobby> all();}If the host leaves, the lobby is auto-disbanded — every other player’s reverse-lookup is cleared.
Example
Section titled “Example”import me.zlex.conduit.lobby.BaseLobby;import me.zlex.conduit.lobby.LobbyEngine;import net.minecraft.server.level.ServerPlayer;
import java.util.UUID;
public final class MyLobbyOps {
public static void createForHost(ServerPlayer host) { MyLobby lobby = new MyLobby(UUID.randomUUID(), host.getUUID()); LobbyEngine.register(lobby); }
public static void onPlayerJoined(UUID lobbyId, ServerPlayer p) { LobbyEngine.join(p.getUUID(), lobbyId); }
public static void onPlayerLeft(ServerPlayer p) { LobbyEngine.leave(p.getUUID()); // disbands if they were host }
public static @Nullable MyLobby lobbyOf(ServerPlayer p) { BaseLobby base = LobbyEngine.getByPlayer(p.getUUID()); return base instanceof MyLobby pl ? pl : null; }}- The host’s UUID is the disband trigger — design your “leave” UX accordingly (a confirmation prompt before the host walks out is usually a good idea).
- The class is non-tick, no events; it’s plain state. Wire it into your own join / leave flow.
all()returns the liveCollectionview — iterate but don’t mutate during iteration.