Remove modifiers from normal FFA/Team games (And increase chance of gold multiplier for special games, decrease random spawn) 🎲 (#3471)

## Description:

Normal (FFA and Team) public games no longer roll random modifiers.
Special games remain fully unaffected and continue to use random
modifiers as before.

I also increased the gold multiplier ticket count in the special
modifier pool from 1 to 4 because of player feedback.

Edit: And because I saw complaints of too much random spawn I decreased
the chance of it.

## 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
This commit is contained in:
FloPinguin
2026-03-19 14:50:07 -07:00
committed by evanpelle
parent c5dad1f850
commit 1220a331ba
+16 -74
View File
@@ -110,13 +110,13 @@ type ModifierKey =
// Each entry represents one "ticket" in the pool. More tickets = higher chance of selection. // Each entry represents one "ticket" in the pool. More tickets = higher chance of selection.
const SPECIAL_MODIFIER_POOL: ModifierKey[] = [ const SPECIAL_MODIFIER_POOL: ModifierKey[] = [
...Array<ModifierKey>(4).fill("isRandomSpawn"), ...Array<ModifierKey>(2).fill("isRandomSpawn"),
...Array<ModifierKey>(8).fill("isCompact"), ...Array<ModifierKey>(8).fill("isCompact"),
...Array<ModifierKey>(1).fill("isCrowded"), ...Array<ModifierKey>(1).fill("isCrowded"),
...Array<ModifierKey>(1).fill("isHardNations"), ...Array<ModifierKey>(1).fill("isHardNations"),
...Array<ModifierKey>(8).fill("startingGold"), ...Array<ModifierKey>(8).fill("startingGold"),
...Array<ModifierKey>(1).fill("startingGoldHigh"), ...Array<ModifierKey>(1).fill("startingGoldHigh"),
...Array<ModifierKey>(1).fill("goldMultiplier"), ...Array<ModifierKey>(4).fill("goldMultiplier"),
...Array<ModifierKey>(1).fill("isAlliancesDisabled"), ...Array<ModifierKey>(1).fill("isAlliancesDisabled"),
]; ];
@@ -144,84 +144,35 @@ export class MapPlaylist {
const playerTeams = const playerTeams =
mode === GameMode.Team ? this.getTeamCount(map) : undefined; mode === GameMode.Team ? this.getTeamCount(map) : undefined;
const modifiers = this.getRandomPublicGameModifiers(playerTeams);
const { startingGold } = modifiers;
let { isCompact, isRandomSpawn, isCrowded, isHardNations } = modifiers;
// Duos, Trios, and Quads should not get random spawn (as it defeats the purpose)
if (
playerTeams === Duos ||
playerTeams === Trios ||
playerTeams === Quads
) {
isRandomSpawn = false;
}
// Hard nations modifier only applies when nations are present (not HvN, which is always hard)
if (mode === GameMode.Team) {
isHardNations = false;
}
// Check if compact map would leave every team with at least 2 players
if (
isCompact &&
mode === GameMode.Team &&
!(await this.supportsCompactMapForTeams(map, playerTeams!))
) {
isCompact = false;
}
// Crowded modifier: if the map's biggest player count (first number of calculateMapPlayerCounts) is 60 or lower (small maps),
// set player count to MAX_PLAYER_COUNT (or 60 if compact map is also enabled)
let crowdedMaxPlayers: number | undefined;
if (isCrowded) {
crowdedMaxPlayers = await this.getCrowdedMaxPlayers(map, isCompact);
if (crowdedMaxPlayers === undefined) {
isCrowded = false;
} else {
crowdedMaxPlayers = this.adjustForTeams(crowdedMaxPlayers, playerTeams);
}
}
// Create the default public game config (from your GameManager)
return { return {
donateGold: mode === GameMode.Team, donateGold: mode === GameMode.Team,
donateTroops: mode === GameMode.Team, donateTroops: mode === GameMode.Team,
gameMap: map, gameMap: map,
maxPlayers: maxPlayers: await this.lobbyMaxPlayers(map, mode, playerTeams, false),
crowdedMaxPlayers ??
(await this.lobbyMaxPlayers(map, mode, playerTeams, isCompact)),
gameType: GameType.Public, gameType: GameType.Public,
gameMapSize: isCompact ? GameMapSize.Compact : GameMapSize.Normal, gameMapSize: GameMapSize.Normal,
publicGameModifiers: { publicGameModifiers: {
isCompact, isCompact: false,
isRandomSpawn, isRandomSpawn: false,
isCrowded, isCrowded: false,
isHardNations, isHardNations: false,
startingGold,
isAlliancesDisabled: false, isAlliancesDisabled: false,
}, },
startingGold,
difficulty: difficulty:
isHardNations || playerTeams === HumansVsNations playerTeams === HumansVsNations ? Difficulty.Hard : Difficulty.Medium,
? Difficulty.Hard
: Difficulty.Medium,
infiniteGold: false, infiniteGold: false,
infiniteTroops: false, infiniteTroops: false,
maxTimerValue: undefined, maxTimerValue: undefined,
instantBuild: false, instantBuild: false,
randomSpawn: isRandomSpawn, randomSpawn: false,
nations: nations:
mode === GameMode.Team && playerTeams !== HumansVsNations mode === GameMode.Team && playerTeams !== HumansVsNations
? "disabled" ? "disabled"
: "default", : "default",
gameMode: mode, gameMode: mode,
playerTeams, playerTeams,
bots: isCompact ? 100 : 400, bots: 400,
spawnImmunityDuration: this.getSpawnImmunityDuration( spawnImmunityDuration: this.getSpawnImmunityDuration(playerTeams),
playerTeams,
startingGold,
),
disabledUnits: [], disabledUnits: [],
} satisfies GameConfig; } satisfies GameConfig;
} }
@@ -234,6 +185,7 @@ export class MapPlaylist {
const excludedModifiers: ModifierKey[] = []; const excludedModifiers: ModifierKey[] = [];
// Check if compact map would leave every team with at least 2 players
const supportsCompact = const supportsCompact =
mode !== GameMode.Team || mode !== GameMode.Team ||
(await this.supportsCompactMapForTeams(map, playerTeams!)); (await this.supportsCompactMapForTeams(map, playerTeams!));
@@ -241,6 +193,7 @@ export class MapPlaylist {
excludedModifiers.push("isCompact"); excludedModifiers.push("isCompact");
} }
// Duos, Trios, and Quads should not get random spawn (as it defeats the purpose)
if ( if (
playerTeams === Duos || playerTeams === Duos ||
playerTeams === Trios || playerTeams === Trios ||
@@ -268,6 +221,8 @@ export class MapPlaylist {
isHardNations, isHardNations,
} = poolResult; } = poolResult;
// Crowded modifier: if the map's biggest player count (first number of calculateMapPlayerCounts) is 60 or lower (small maps),
// set player count to MAX_PLAYER_COUNT (or 60 if compact map is also enabled)
let crowdedMaxPlayers: number | undefined; let crowdedMaxPlayers: number | undefined;
if (isCrowded) { if (isCrowded) {
crowdedMaxPlayers = await this.getCrowdedMaxPlayers(map, isCompact); crowdedMaxPlayers = await this.getCrowdedMaxPlayers(map, isCompact);
@@ -484,19 +439,6 @@ export class MapPlaylist {
return TEAM_WEIGHTS[0].config; return TEAM_WEIGHTS[0].config;
} }
private getRandomPublicGameModifiers(
playerTeams?: TeamCountConfig,
): PublicGameModifiers {
return {
isRandomSpawn: Math.random() < 0.05, // 5% chance
isCompact: Math.random() < 0.05, // 5% chance
isCrowded: Math.random() < 0.05, // 5% chance
startingGold: Math.random() < 0.05 ? 5_000_000 : undefined, // 5% chance
isHardNations: Math.random() < 0.025, // 2.5% chance
isAlliancesDisabled: false,
};
}
private getRandomSpecialGameModifiers( private getRandomSpecialGameModifiers(
excludedModifiers: ModifierKey[] = [], excludedModifiers: ModifierKey[] = [],
count?: number, count?: number,