Refactor: use promises instead of callbacks for joining a game (#3452)

## Description:

Simplifies the interface a bit.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2026-03-17 10:08:30 -07:00
committed by GitHub
parent dd2c239aa1
commit cce46ef126
2 changed files with 131 additions and 124 deletions
+28 -19
View File
@@ -64,15 +64,24 @@ export interface LobbyConfig {
gameRecord?: GameRecord;
}
export interface JoinLobbyResult {
stop: (force?: boolean) => boolean;
prestart: Promise<void>;
join: Promise<void>;
}
export function joinLobby(
eventBus: EventBus,
lobbyConfig: LobbyConfig,
onPrestart: () => void,
onJoin: () => void,
): (force?: boolean) => boolean {
): JoinLobbyResult {
// Mutable clientID state — assigned by server (multiplayer) or derived from gameStartInfo (singleplayer)
let clientID: ClientID | undefined;
let resolvePrestart: () => void;
let resolveJoin: () => void;
const prestartPromise = new Promise<void>((r) => (resolvePrestart = r));
const joinPromise = new Promise<void>((r) => (resolveJoin = r));
console.log(`joining lobby: gameID: ${lobbyConfig.gameID}`);
const userSettings: UserSettings = new UserSettings();
@@ -105,17 +114,17 @@ export function joinLobby(
message.gameMapSize,
terrainMapFileLoader,
);
onPrestart();
resolvePrestart();
}
if (message.type === "start") {
// Trigger prestart for singleplayer games
onPrestart();
resolvePrestart();
console.log(
`lobby: game started: ${JSON.stringify(message, replacer, 2)}`,
);
// Server tells us our assigned clientID (also sent on start for late joins)
clientID = message.myClientID;
onJoin();
resolveJoin();
// For multiplayer games, GameStartInfo is not known until game starts.
lobbyConfig.gameStartInfo = message.gameStartInfo;
createClientGame(
@@ -176,19 +185,19 @@ export function joinLobby(
}
};
transport.connect(onconnect, onmessage);
return (force: boolean = false) => {
if (!force && currentGameRunner?.shouldPreventWindowClose()) {
console.log("Player is active, prevent leaving game");
return false;
}
console.log("leaving game");
currentGameRunner = null;
transport.leaveGame();
return true;
return {
stop: (force: boolean = false) => {
if (!force && currentGameRunner?.shouldPreventWindowClose()) {
console.log("Player is active, prevent leaving game");
return false;
}
console.log("leaving game");
currentGameRunner = null;
transport.leaveGame();
return true;
},
prestart: prestartPromise,
join: joinPromise,
};
}