Commit Graph
5 Commits
Author SHA1 Message Date
fabd1bd2d1 fix(core): reject spawn intents after the spawn phase (anti-teleport) (#4657)
## Problem
Patches sending the `spawn` intent over the game WebSocket while a match
is underway:

```js
ws.send(JSON.stringify({ type: "intent", intent: { type: "spawn", tile: tileRef } }));
```

The server relays it like any intent, and `SpawnExecution.tick()` then
**relinquishes the player's entire territory and re-conquers it at the
target tile** — instant teleport anywhere on the map.

The root cause is that `SpawnExecution.tick()` had no spawn-phase gate
(only a random-spawn re-roll guard), and the engine ticks the execution
**both during and after** the spawn phase (`activeDuringSpawnPhase()` is
`true`, and after the phase `!inSpawnPhase()` is also `true`).

## Fix

Ignore a spawn intent when the game is no longer in the spawn phase
**and** the player has already spawned:

```js
if (!this.mg.inSpawnPhase() && player.hasSpawned()) {
  return;
}
```

Because `inSpawnPhase()` / `hasSpawned()` are deterministic game state,
the intent becomes a no-op identically on every client — no desync.

Unaffected:
- First-time spawns (`hasSpawned()` is false)
- In-phase spawn picks and re-picks (`inSpawnPhase()` is true)
- Existing random-spawn re-roll protection (kept as-is)

## Tests

- Added `Spawn intent after the spawn phase cannot relocate territory
(anti-teleport)` — establishes a player, then asserts a later `spawn`
intent leaves `spawnTile()` and `numTilesOwned()` unchanged.
- Simplified `Spawn on specific tile` to a single first spawn (the
previous version relied on an out-of-phase re-pick, which this fix now
correctly forbids).
- Full `tests/core` suite green (259 tests).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:22:41 -07:00
FloPinguinandGitHub 71d70dfb0e fix: prevent client from bypassing random spawn selection 🛡️ (#4428)
## Description:

When random spawn mode is active, players are supposed to receive
randomly chosen spawns rather than choosing their own. However,
`SpawnExecution.getSpawn()` checks `center !== undefined` first, which
means if a player manually injects coordinates into the spawn intent
(bypassing the client-side UI guard), the random selection logic is
completely bypassed and the player gets their chosen coordinates.

This was fully exploitable in singleplayer (where no pre-created
`SpawnExecution` objects exist) and was a defense-in-depth gap in
multiplayer (relying on execution order of pre-created spawns to block
it via the `hasSpawned()` guard).

The fix forces `center` to `undefined` in `getSpawn()` when random
spawns are enabled, ensuring the random selection code path is always
taken regardless of what the client sends.

## Changes:
- `src/core/execution/SpawnExecution.ts`: Pass `undefined` to
`getSpawn()` when `isRandomSpawn()` is true, ignoring any
client-specified tile
- `tests/core/execution/SpawnExecution.test.ts`: Added test verifying
that a client-specified tile is ignored when random spawn is enabled

## 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

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

FloPinguin
2026-06-27 11:10:24 -07:00
AotumuriandGitHub f1d162825e 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
2026-05-11 12:44:44 -07:00
097c42740c Random spawn. Avoid spawning near water. (#3009)
## Description:

Fixing
https://discord.com/channels/1359946986937258015/1360078040222142564/1463898386854973642

Now, if not all tiles on the spawn circle can be owned, the algorithm
tries to select another random spawn tile.

## 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:

nikolaj_mykola

---------

Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
2026-02-22 15:51:05 +00:00
6112547273 Improve random spawn (#2503)
## Description:

This is a previously approved PR with an additional commit that fixes
case when nations change spawn & jump around, their previous territory
wasn't getting deleted.

## 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:

nikolaj_mykola

---------

Co-authored-by: Evan <evanpelle@gmail.com>
2025-12-20 13:35:30 -08:00