mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-16 06:53:22 +00:00
Added a public game modifier system 😮 For more variety (#2801)
## Description: Added a public game modifier system. It causes that 5% of public games are played on the compact version of the map 10% of public games have "Random Spawn" activated Percentages can easily get changed via `DefaultConfig`. We can also easily add more modifiers. Modifiers can stack, so in rare cases you will play on a compact map with random spawn 😄 More variety! ### "Compact Map" modifier implementation - With the "Compact Map" modifier the lobby max player count gets reduced to 25% and only 25% of the regular bots and only 25% of the regular nations will spawn (because the map has only 25% of its regular size) - In private lobbies and singleplayer the nation reduction happens too (When "Compact Map" is enabled). ### Restrictions - Duos/Trios/Quads team modes do not get Random Spawn (defeats the purpose) - Maps with smallest player count < 50 do not get Compact Map in team games (not enough players after the reduction to 25%). I have calculated all the possible max player counts. ### How it looks like Random Spawn modifier: <img width="528" height="183" alt="Screenshot 2026-01-06 194959" src="https://github.com/user-attachments/assets/2f729da9-80c3-4548-8205-71129da2a76a" /> Very rare case: Two modifiers at the same time and only 10 max players have been chosen from `[GameMapType.FaroeIslands]: [20, 15, 10]`. Because of the 75% reduction in player count only 3 players are allowed (3 is the minimum). I think its funny that you can play a 1v1v1 in rare occasions 😄 <img width="526" height="184" alt="Screenshot 2026-01-06 194938" src="https://github.com/user-attachments/assets/834326eb-df03-41b7-b1db-1efa3f1013b5" /> ### Funny side-effect Team games with random spawn. That will be interesting. No more "Who is better in donating troops to the frontline". Instead you have to heavily coordinate with your teammates. ## 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:
@@ -193,6 +193,11 @@ export enum GameMapSize {
|
||||
Normal = "Normal",
|
||||
}
|
||||
|
||||
export interface PublicGameModifiers {
|
||||
isCompact: boolean;
|
||||
isRandomSpawn: boolean;
|
||||
}
|
||||
|
||||
export interface UnitInfo {
|
||||
cost: (game: Game, player: Player) => Gold;
|
||||
// Determines if its owner changes when its tile is conquered.
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PseudoRandom } from "../PseudoRandom";
|
||||
import { GameStartInfo } from "../Schemas";
|
||||
import {
|
||||
Cell,
|
||||
GameMapSize,
|
||||
GameMode,
|
||||
GameType,
|
||||
HumansVsNations,
|
||||
@@ -14,6 +15,7 @@ import { Nation as ManifestNation } from "./TerrainMapLoader";
|
||||
/**
|
||||
* Creates the nations array for a game, handling HumansVsNations mode specially.
|
||||
* In HumansVsNations mode, the number of nations matches the number of human players to ensure fair gameplay.
|
||||
* For compact maps, only 25% of the nations are used.
|
||||
*/
|
||||
export function createNationsForGame(
|
||||
gameStart: GameStartInfo,
|
||||
@@ -31,13 +33,23 @@ export function createNationsForGame(
|
||||
new PlayerInfo(n.name, PlayerType.Nation, null, random.nextID()),
|
||||
);
|
||||
|
||||
const isCompactMap = gameStart.config.gameMapSize === GameMapSize.Compact;
|
||||
|
||||
const isHumansVsNations =
|
||||
gameStart.config.gameMode === GameMode.Team &&
|
||||
gameStart.config.playerTeams === HumansVsNations;
|
||||
|
||||
// For non-HumansVsNations modes, simply use the manifest nations
|
||||
// For compact maps, use only 25% of nations (minimum 1)
|
||||
let effectiveNations = manifestNations;
|
||||
if (isCompactMap && !isHumansVsNations) {
|
||||
const targetCount = getCompactMapNationCount(manifestNations.length, true);
|
||||
const shuffled = random.shuffleArray(manifestNations);
|
||||
effectiveNations = shuffled.slice(0, targetCount);
|
||||
}
|
||||
|
||||
// For non-HumansVsNations modes, simply use the effective nations
|
||||
if (!isHumansVsNations) {
|
||||
return manifestNations.map(toNation);
|
||||
return effectiveNations.map(toNation);
|
||||
}
|
||||
|
||||
// HumansVsNations mode: balance nation count to match human count
|
||||
@@ -71,6 +83,20 @@ export function createNationsForGame(
|
||||
return nations;
|
||||
}
|
||||
|
||||
// For compact maps, only 25% of nations are used (minimum 1).
|
||||
export function getCompactMapNationCount(
|
||||
manifestNationCount: number,
|
||||
isCompactMap: boolean,
|
||||
): number {
|
||||
if (manifestNationCount === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (isCompactMap) {
|
||||
return Math.max(1, Math.floor(manifestNationCount * 0.25));
|
||||
}
|
||||
return manifestNationCount;
|
||||
}
|
||||
|
||||
const PLURAL_NOUN = Symbol("plural!");
|
||||
const NOUN = Symbol("noun!");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user