Special bot names (#2552)

## Description:

Special bot names. If the solution seems convoluted for such an easy
thing, that is because: not all bots find a spawn position, so only
assign a candidate name after finding a spawn. And the first few are
almost always overwritten by Nation spawns so the first 20 just get a
random name. Only then do we assign from the provided lists. For the
random names, some might get the same name but that's not an issue as
no-one will notice and they're off the map quite fast anyway.

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

tryout33
This commit is contained in:
VariableVince
2025-12-04 01:01:05 +01:00
committed by GitHub
parent 4ff2ca3315
commit 8f32746bb2
2 changed files with 229 additions and 7 deletions
+48 -7
View File
@@ -4,11 +4,16 @@ 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";
import {
COMMUNITY_FULL_ELF_NAMES,
COMMUNITY_PREFIXES,
SPECIAL_FULL_ELF_NAMES,
} from "./utils/BotNames";
export class BotSpawner {
private random: PseudoRandom;
private bots: SpawnExecution[] = [];
private nameIndex = 0;
constructor(
private gs: Game,
@@ -24,9 +29,13 @@ export class BotSpawner {
console.log("too many retries while spawning bots, giving up");
return this.bots;
}
const botName = this.randomBotName();
const spawn = this.spawnBot(botName);
const candidate = this.nextCandidateName();
const spawn = this.spawnBot(candidate.name);
if (spawn !== null) {
// Only use candidate name once bot successfully spawned
if (candidate.source === "list") {
this.nameIndex++;
}
this.bots.push(spawn);
} else {
tries++;
@@ -51,10 +60,42 @@ export class BotSpawner {
);
}
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]}`;
private nextCandidateName(): {
name: string;
source: "list" | "random";
} {
if (this.bots.length < 20) {
//first few usually overwritten by Nation spawn
return { name: this.getRandomElf(), source: "random" };
}
if (this.nameIndex < COMMUNITY_FULL_ELF_NAMES.length) {
return {
name: COMMUNITY_FULL_ELF_NAMES[this.nameIndex],
source: "list",
};
}
const specialOffset = COMMUNITY_FULL_ELF_NAMES.length;
if (this.nameIndex < specialOffset + SPECIAL_FULL_ELF_NAMES.length) {
return {
name: SPECIAL_FULL_ELF_NAMES[this.nameIndex - specialOffset],
source: "list",
};
}
const prefixOffset = specialOffset + SPECIAL_FULL_ELF_NAMES.length;
if (this.nameIndex < prefixOffset + COMMUNITY_PREFIXES.length) {
return {
name: `${COMMUNITY_PREFIXES[this.nameIndex - prefixOffset]} the Elf`,
source: "list",
};
}
return { name: this.getRandomElf(), source: "random" };
}
private getRandomElf(): string {
const suffixNumber = this.random.nextInt(1, 10001);
return `Elf ${suffixNumber}`;
}
private randTile(): TileRef {
+181
View File
@@ -253,3 +253,184 @@ export const BOT_NAME_SUFFIXES = [
"Democracy",
"Autocracy",
];
export const COMMUNITY_FULL_ELF_NAMES = [
"evan the Creator Elf",
"iamlewis the Head Elf",
"Restart the Community Elf",
"Mr Box the Dev Elf",
"InGloriousTom the Dev Elf",
"Sheikh the First Elf",
"N0ur the Flag Elf",
"Diessel the UI Elf",
"Nikola123 the Map Elf",
"Aotumuri the Language Elf",
"Pilkey the Admin Elf",
"Mr tryout33s Elf",
"Biffeur the YT Elf",
"Enzo the YT Elf",
"Molky the YT Elf",
"FuzeIII the YT Elf",
"Node the YT Elf",
"Lumiin the YT Elf",
"youngfentanyl OFM Elf",
"Remorse the Wiki Elf",
"Lonely Millenial Twitch Elf",
"Kaizeron OFM Elf",
"Zilka OFM Elf",
"JIZK Caster Elf",
"MiraCZ the FP Elf",
"aPuddle best Elf",
"lucas the sound Elf",
];
export const SPECIAL_FULL_ELF_NAMES = [
"Santa",
"Rudolf the Red-Nosed Reindeer",
"Frosty the Snowman",
"Hermey the Elf",
"Ivan the Elf",
"Elf on the Shelf",
"Buddy the Elf",
"Legolas",
"Elrond",
"Galadriel",
"Celeborn",
"Glorfindel",
];
export const COMMUNITY_PREFIXES = [
"Baguette Bot",
"Kiwi",
"FakeNeo",
"Nash",
"1brucben",
"Toyatak",
"Readix",
"Danny",
"php",
"Redincon",
"Sachx.",
"Fuity Mctooty",
"Vimacs",
"Wraith",
"Phantom",
"Crescent",
"OF Therapist",
"Aviid",
"brunoo",
"Ezaru",
"prices",
"Santos",
"Wonder",
"Vincent",
"Smith M",
"Acer Alex",
"Controller",
"d3n0x",
"devalnor",
"FloPinguin",
"falcon",
"GlacialDrift",
"Jax",
"Killersoren",
"MiniMeTiny",
"Remissile",
"Sorikairo",
"That Otter",
"Arya",
"Nebula",
"takeser",
"Kai IL PAZZO",
"Vanon",
"Foorack",
"Abod",
"aaa4xu",
"Goblinon",
"dx",
"Pod",
"Demonessica",
"Dovg",
"Joel",
"LegitimatelyCool1",
"OxMzimzy",
"RTHOne",
"Egophobic",
"djmrFunnyMan",
"5oliloguy",
"cfsolver",
"nvm",
"Supbro",
"Mischa",
"WALMART NINJA",
"Magico",
"sidious",
"Bruny",
"Goofer",
"Backn",
"EyeSeeEm",
"TrionX",
"Theodora",
"platz1de",
"Maths Empire",
"Moha",
"SyntaxPM",
"theskeleton4393",
"juliosilvaqwerty5",
"NewHappyRabbit",
"Moki",
"Xaelor",
"NiclasWK",
"cldprv",
"r3ms",
"Tanepro193",
"gx21",
"toldinsound",
"jacks0n",
"floriankilian",
"Fibig",
"Texxter",
"pantelispantelidis",
"ap ms",
"frappa10",
"Lollosean",
"daimyo panda2",
"gafunuko",
"Jinyoon",
"Perdiccas",
"zibi",
"RinkyDinky",
"Rulfam",
"Nobody",
"Vekser",
"extraextra",
"MotivatedMonkey",
"6uzm4n",
"theangel2",
"Keevee",
"Makonede",
"grassified",
"Zjefken",
"Summers Nick",
"Marvin",
"EagleEye",
"Shahiid",
"INGSOC",
"SIG",
"Bobo",
"seekerreturns",
"SlyTy",
"Leo 21",
"FX",
"Calrathan",
"AzloD",
"SunnyBoyWTF",
"BeGj",
"tnhnblgl",
"BrunoJurkovic",
"q8gazy",
"Kipstz",
"aqw42",
"TylerHavanan",
"KerodK",
"ghisloufou",
"dxtron",
"Sii",
];