feat: remove spawn timer on singleplayer (#3199)

Resolves #1041 

## Description:

Remove the singleplayer spawn countdown so the game starts when the
player spawns, spawn nations immediately after player spawn, and align
game timer/max-timer timing with the new start point.

Added a singleplayer regression test for spawn-immunity timing
(GameImpl.test.ts) and updated spawn-phase loop tests to use gameType:
GameType.Public where singleplayer behavior is not under test (e.g.
MIRV/AI/Spawn/WinCheck-related suites), eliminating inSpawnPhase()
timeout hangs after the new singleplayer start logic.


https://github.com/user-attachments/assets/c07a585f-1153-490e-88ca-a91fc7ae5756

## 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:
aotumuri
This commit is contained in:
Aotumuri
2026-05-11 12:44:44 -07:00
committed by GitHub
parent 2b04c568fc
commit f1d162825e
46 changed files with 333 additions and 429 deletions
+9 -15
View File
@@ -27,13 +27,11 @@ describe("Spawn execution", () => {
spawnExecutions.push(new SpawnExecution("game_id", playerInfo));
}
const game = await setup(mapName, undefined, players);
const game = await setup(mapName, {}, players);
game.addExecution(...spawnExecutions);
while (game.inSpawnPhase()) {
game.executeNextTick();
}
game.executeNextTick();
game.executeNextTick();
game.allPlayers().forEach((player) => {
const spawnTile = player.spawnTile()!;
@@ -73,13 +71,11 @@ describe("Spawn execution", () => {
spawnExecutions.push(new SpawnExecution("game_id", playerInfo));
}
const game = await setup("half_land_half_ocean", undefined, players);
const game = await setup("half_land_half_ocean", {}, players);
game.addExecution(...spawnExecutions);
while (game.inSpawnPhase()) {
game.executeNextTick();
}
game.executeNextTick();
game.executeNextTick();
// Should spawn fewer than requested when map is too small
expect(
@@ -96,14 +92,12 @@ describe("Spawn execution", () => {
`player_id`,
);
const game = await setup("half_land_half_ocean", undefined, [playerInfo]);
const game = await setup("half_land_half_ocean", {}, [playerInfo]);
game.addExecution(new SpawnExecution("game_id", playerInfo, 10));
game.addExecution(new SpawnExecution("game_id", playerInfo, 20));
while (game.inSpawnPhase()) {
game.executeNextTick();
}
game.executeNextTick();
game.executeNextTick();
expect(game.playerByClientID("client_id")?.spawnTile()).toBe(20);
// Previous territory from first spawn should be relinquished