mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 12:32:21 +00:00
cf3e3a7a74
## Description: BotSpawner used the same PRNG seed (simpleHash(gameID)) as createGameRunner, causing bot IDs to collide with nation IDs. When a bot's SpawnExecution found a nation with the same ID via hasPlayer(), it silently reused that nation instead of creating a new player - resulting in far fewer players than configured (e.g. ~670 instead of 800 with 400 bots + 400 nations) with no console warnings. Offsets the BotSpawner seed by +2 to avoid the shared PRNG sequence (matching the +1 pattern already used by Executor). ## 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: FloPinguin
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { Game, PlayerInfo, PlayerType } from "../game/Game";
|
|
import { PseudoRandom } from "../PseudoRandom";
|
|
import { GameID } from "../Schemas";
|
|
import { simpleHash } from "../Util";
|
|
import { SpawnExecution } from "./SpawnExecution";
|
|
import { BOT_NAME_PREFIXES, BOT_NAME_SUFFIXES } from "./utils/BotNames";
|
|
|
|
export class BotSpawner {
|
|
private random: PseudoRandom;
|
|
private bots: SpawnExecution[] = [];
|
|
|
|
constructor(
|
|
private gs: Game,
|
|
private gameID: GameID,
|
|
) {
|
|
// Use a different seed than createGameRunner (which uses simpleHash(gameID))
|
|
// to avoid bot IDs colliding with nation/human IDs from the same PRNG sequence.
|
|
this.random = new PseudoRandom(simpleHash(gameID) + 2);
|
|
}
|
|
|
|
spawnBots(numBots: number): SpawnExecution[] {
|
|
for (let i = 0; i < numBots; i++) {
|
|
const name = this.randomBotName();
|
|
const spawn = this.spawnBot(name);
|
|
this.bots.push(spawn);
|
|
}
|
|
|
|
return this.bots;
|
|
}
|
|
|
|
spawnBot(botName: string): SpawnExecution {
|
|
return new SpawnExecution(
|
|
this.gameID,
|
|
new PlayerInfo(botName, PlayerType.Bot, null, this.random.nextID()),
|
|
);
|
|
}
|
|
|
|
private randomBotName(): string {
|
|
const prefixIndex = this.random.nextInt(0, BOT_NAME_PREFIXES.length);
|
|
const suffixIndex = this.random.nextInt(0, BOT_NAME_SUFFIXES.length);
|
|
return `${BOT_NAME_PREFIXES[prefixIndex]} ${BOT_NAME_SUFFIXES[suffixIndex]}`;
|
|
}
|
|
}
|