mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-08-18 17:53:29 +00:00
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:
@@ -18,20 +18,13 @@ describe("MIRVExecution", () => {
|
||||
beforeEach(async () => {
|
||||
game = await setup(
|
||||
"big_plains",
|
||||
{
|
||||
infiniteGold: true,
|
||||
instantBuild: true,
|
||||
},
|
||||
{ infiniteGold: true, instantBuild: true },
|
||||
[
|
||||
new PlayerInfo("player", PlayerType.Human, "client_id1", "player_id"),
|
||||
new PlayerInfo("other", PlayerType.Human, "client_id2", "other_id"),
|
||||
],
|
||||
);
|
||||
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
player = game.player("player_id");
|
||||
otherPlayer = game.player("other_id");
|
||||
|
||||
|
||||
@@ -17,20 +17,13 @@ describe("PlayerExecution Annexation Bug", () => {
|
||||
beforeEach(async () => {
|
||||
game = await setup(
|
||||
"big_plains",
|
||||
{
|
||||
infiniteGold: true,
|
||||
instantBuild: true,
|
||||
},
|
||||
{ infiniteGold: true, instantBuild: true },
|
||||
[
|
||||
new PlayerInfo("large", PlayerType.Human, "client1", "large_id"),
|
||||
new PlayerInfo("small", PlayerType.Human, "client2", "small_id"),
|
||||
],
|
||||
);
|
||||
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
largePlayer = game.player("large_id");
|
||||
smallPlayer = game.player("small_id");
|
||||
|
||||
|
||||
@@ -18,10 +18,7 @@ describe("NukeExecution", () => {
|
||||
beforeEach(async () => {
|
||||
game = await setup(
|
||||
"big_plains",
|
||||
{
|
||||
infiniteGold: true,
|
||||
instantBuild: true,
|
||||
},
|
||||
{ infiniteGold: true, instantBuild: true },
|
||||
[
|
||||
new PlayerInfo("player", PlayerType.Human, "client_id1", "player_id"),
|
||||
new PlayerInfo("other", PlayerType.Human, "client_id2", "other_id"),
|
||||
@@ -34,10 +31,6 @@ describe("NukeExecution", () => {
|
||||
}));
|
||||
(game.config() as TestConfig).nukeAllianceBreakThreshold = vi.fn(() => 5);
|
||||
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
player = game.player("player_id");
|
||||
otherPlayer = game.player("other_id");
|
||||
|
||||
|
||||
@@ -17,20 +17,13 @@ describe("PlayerExecution", () => {
|
||||
beforeEach(async () => {
|
||||
game = await setup(
|
||||
"big_plains",
|
||||
{
|
||||
infiniteGold: true,
|
||||
instantBuild: true,
|
||||
},
|
||||
{ infiniteGold: true, instantBuild: true },
|
||||
[
|
||||
new PlayerInfo("player", PlayerType.Human, "client_id1", "player_id"),
|
||||
new PlayerInfo("other", PlayerType.Human, "client_id2", "other_id"),
|
||||
],
|
||||
);
|
||||
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
player = game.player("player_id");
|
||||
otherPlayer = game.player("other_id");
|
||||
|
||||
|
||||
@@ -78,10 +78,6 @@ describe("SAM", () => {
|
||||
),
|
||||
);
|
||||
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
attacker = game.player("attacker_id");
|
||||
defender = game.player("defender_id");
|
||||
middle_defender = game.player("middle_defender_id");
|
||||
|
||||
@@ -65,12 +65,8 @@ describe("WinCheckExecution", () => {
|
||||
mg.numLandTiles = vi.fn(() => 100);
|
||||
mg.numTilesWithFallout = vi.fn(() => 0);
|
||||
mg.stats = vi.fn(() => ({ stats: () => ({ mocked: true }) }));
|
||||
// Advance ticks until timeElapsed (in seconds) >= maxTimerValue * 60
|
||||
// timeElapsed = (ticks - numSpawnPhaseTurns) / 10 =>
|
||||
// ticks >= numSpawnPhaseTurns + maxTimerValue * 600
|
||||
const threshold =
|
||||
mg.config().numSpawnPhaseTurns() +
|
||||
(mg.config().gameConfig().maxTimerValue ?? 0) * 600;
|
||||
mg.endSpawnPhase();
|
||||
const threshold = (mg.config().gameConfig().maxTimerValue ?? 0) * 600;
|
||||
while (mg.ticks() < threshold) {
|
||||
mg.executeNextTick();
|
||||
}
|
||||
@@ -109,9 +105,6 @@ describe("WinCheckExecution - Nation Winners", () => {
|
||||
const nation = game.player("nation_id");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Assign 81% of land to Nation
|
||||
const totalLand = game.numLandTiles();
|
||||
@@ -171,10 +164,7 @@ describe("WinCheckExecution - Nation Winners", () => {
|
||||
game.addPlayer(nationInfo);
|
||||
const nation = game.player("nation_id");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
game.endSpawnPhase();
|
||||
|
||||
// Give Nation 60% territory (below 80% threshold)
|
||||
// Give human 30% territory
|
||||
@@ -200,9 +190,7 @@ describe("WinCheckExecution - Nation Winners", () => {
|
||||
expect(nation.numTilesOwned()).toBeGreaterThan(human.numTilesOwned());
|
||||
|
||||
// Fast-forward game ticks past timer expiration
|
||||
const threshold =
|
||||
game.config().numSpawnPhaseTurns() +
|
||||
(game.config().gameConfig().maxTimerValue ?? 0) * 600;
|
||||
const threshold = (game.config().gameConfig().maxTimerValue ?? 0) * 600;
|
||||
while (game.ticks() < threshold) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
@@ -258,9 +246,6 @@ describe("WinCheckExecution - Nation Winners", () => {
|
||||
const nation3 = game.player("nation3_id");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Assign territories: Nation1 (85%), Nation2 (10%), Nation3 (5%)
|
||||
const totalLand = game.numLandTiles();
|
||||
@@ -327,9 +312,6 @@ describe("WinCheckExecution - Nation Winners", () => {
|
||||
expect(bot2.team()).toBe(ColoredTeams.Bot);
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Assign 96% of land to bot team (above 95% Team mode threshold)
|
||||
const totalLand = game.numLandTiles();
|
||||
@@ -392,9 +374,6 @@ describe("WinCheckExecution - 1v1 Ranked Mode", () => {
|
||||
const human2 = game.player("Player2");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Assign some territory to both players
|
||||
let human1Count = 0;
|
||||
@@ -447,9 +426,6 @@ describe("WinCheckExecution - 1v1 Ranked Mode", () => {
|
||||
const human2 = game.player("Player2");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Assign territory to both players
|
||||
let human1Count = 0;
|
||||
@@ -503,9 +479,6 @@ describe("WinCheckExecution - 1v1 Ranked Mode", () => {
|
||||
const human2 = game.player("Player2");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Both players disconnect
|
||||
human1.markDisconnected(true);
|
||||
@@ -547,9 +520,6 @@ describe("WinCheckExecution - 1v1 Ranked Mode", () => {
|
||||
const nation = game.player("NationPlayer");
|
||||
|
||||
// Skip spawn phase
|
||||
while (game.inSpawnPhase()) {
|
||||
game.executeNextTick();
|
||||
}
|
||||
|
||||
// Assign territory to all players
|
||||
let humanCount = 0;
|
||||
|
||||
Reference in New Issue
Block a user