diff --git a/src/core/game/NationCreation.ts b/src/core/game/NationCreation.ts index 3e4d15807..b2bdc0b70 100644 --- a/src/core/game/NationCreation.ts +++ b/src/core/game/NationCreation.ts @@ -69,9 +69,11 @@ export function createNationsForGame( // If we need more nations than defined in manifest, create additional ones const nations: Nation[] = manifestNations.map(toNation); + const usedNames = new Set(nations.map((n) => n.playerInfo.name)); const additionalCount = targetNationCount - manifestNations.length; for (let i = 0; i < additionalCount; i++) { - const name = generateNationName(random); + const name = generateUniqueNationName(random, usedNames); + usedNames.add(name); nations.push( new Nation( undefined, @@ -97,6 +99,45 @@ export function getCompactMapNationCount( return manifestNationCount; } +function generateUniqueNationName( + random: PseudoRandom, + usedNames: Set, +): string { + for (let attempt = 0; attempt < 1000; attempt++) { + const name = generateNationName(random); + if (!usedNames.has(name)) { + return name; + } + } + // Fallback if we can't generate unique name (extremely unlikely) + // Append a number to ensure uniqueness + let counter = 1; + const baseName = generateNationName(random); + while (usedNames.has(`${baseName} ${counter}`)) { + counter++; + } + return `${baseName} ${counter}`; +} + +function generateNationName(random: PseudoRandom): string { + const template = NAME_TEMPLATES[random.nextInt(0, NAME_TEMPLATES.length)]; + const noun = NOUNS[random.nextInt(0, NOUNS.length)]; + + const result: string[] = []; + + for (const part of template) { + if (part === PLURAL_NOUN) { + result.push(pluralize(noun)); + } else if (part === NOUN) { + result.push(noun); + } else { + result.push(part); + } + } + + return result.join(" "); +} + const PLURAL_NOUN = Symbol("plural!"); const NOUN = Symbol("noun!"); @@ -290,25 +331,6 @@ const NOUNS = [ "Penguin", ]; -function generateNationName(random: PseudoRandom): string { - const template = NAME_TEMPLATES[random.nextInt(0, NAME_TEMPLATES.length)]; - const noun = NOUNS[random.nextInt(0, NOUNS.length)]; - - const result: string[] = []; - - for (const part of template) { - if (part === PLURAL_NOUN) { - result.push(pluralize(noun)); - } else if (part === NOUN) { - result.push(noun); - } else { - result.push(part); - } - } - - return result.join(" "); -} - // Words from NOUNS that need irregular "-oes" plural const O_TO_OES = new Set(["Potato", "Tomato"]); diff --git a/src/server/MapPlaylist.ts b/src/server/MapPlaylist.ts index 7544aa4c8..aaff17264 100644 --- a/src/server/MapPlaylist.ts +++ b/src/server/MapPlaylist.ts @@ -121,7 +121,9 @@ export class MapPlaylist { gameMapSize: isCompact ? GameMapSize.Compact : GameMapSize.Normal, publicGameModifiers: { isCompact, isRandomSpawn }, difficulty: - playerTeams === HumansVsNations ? Difficulty.Hard : Difficulty.Easy, + playerTeams === HumansVsNations + ? Difficulty.Impossible + : Difficulty.Easy, infiniteGold: false, infiniteTroops: false, maxTimerValue: undefined,