Skip to content

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.

  • 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.

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 live Collection view — iterate but don’t mutate during iteration.