Files
OpenFrontIO/tests/util/TestServerConfig.ts
FloPinguin 417fa0fe09 For v30: Add new modifiers (Hard nations and 25M Starting Gold) 🙂 (#3316)
## Description:

Adds two new public game modifiers for variety and improves compact map
eligibility for team games.

### New Modifiers

**Hard Nations (`isHardNations`)**
- We need this modifier for HvN, because medium nations are easier now
(will result in a much higher human winrate)
- In a discord discussion we concluded that HvN should generally be
easier (higher winrate than 50%, so players are less frustated)
- Thats why only 20% of HvN games have the hard nations modifier (for
now)
- For PvPvE enjoyers, the modifier is also active in FFA games => (Only
2.5% chance, and 1 ticket in `SPECIAL_MODIFIER_POOL`)

**25M Starting Gold (`startingGoldHigh`)**
- Some people in the main discord wanted this modifier, and it will
result in crazy games
- Rare special-only modifier (1 ticket in pool); mutually exclusive with
5M starting gold via `MUTUALLY_EXCLUSIVE_MODIFIERS`
- Disables nations (they lack PVP immunity, so 25M gold doesn't work
well with them)
- Excluded from HumansVsNations games (since it disables nations)
- Spawn immunity set to **2 minutes 30 seconds** (vs 30s for 5M gold),
so people can spend the gold and prepare

### Other Changes

- **Improved `supportsCompactMapForTeams`**: Replaced the hard `smallest
>= 50` land-tile cutoff with a per-team-config calculation that
simulates worst-case compact player count and checks every team gets at
least 2 players.
- **HvN spawn immunity**: Always 5 seconds in both regular and special
lobbies (to get rid of a confusing PVP immunity HeadsUpMessage in 5M
starting gold games)
- **Regular public lobby random spawn modifier probabilty**: Reduced
from 10% to 5% (Because of the new modifier, so there aren't too many
modifiers in non-special-lobbies, should only occur sometimes there)
- Rebalanced `SPECIAL_MODIFIER_POOL` a bit

## 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
2026-03-01 20:12:38 -08:00

94 lines
2.6 KiB
TypeScript

import { JWK } from "jose";
import { GameEnv, ServerConfig } from "../../src/core/configuration/Config";
import { PublicGameModifiers } from "../../src/core/game/Game";
import { GameID } from "../../src/core/Schemas";
export class TestServerConfig implements ServerConfig {
turnstileSiteKey(): string {
throw new Error("Method not implemented.");
}
turnstileSecretKey(): string {
throw new Error("Method not implemented.");
}
apiKey(): string {
throw new Error("Method not implemented.");
}
allowedFlares(): string[] | undefined {
throw new Error("Method not implemented.");
}
stripePublishableKey(): string {
throw new Error("Method not implemented.");
}
domain(): string {
throw new Error("Method not implemented.");
}
subdomain(): string {
throw new Error("Method not implemented.");
}
jwtAudience(): string {
throw new Error("Method not implemented.");
}
jwtIssuer(): string {
throw new Error("Method not implemented.");
}
jwkPublicKey(): Promise<JWK> {
throw new Error("Method not implemented.");
}
otelEnabled(): boolean {
throw new Error("Method not implemented.");
}
otelEndpoint(): string {
throw new Error("Method not implemented.");
}
otelAuthHeader(): string {
throw new Error("Method not implemented.");
}
turnIntervalMs(): number {
throw new Error("Method not implemented.");
}
gameCreationRate(): number {
throw new Error("Method not implemented.");
}
async lobbyMaxPlayers(): Promise<number> {
throw new Error("Method not implemented.");
}
numWorkers(): number {
throw new Error("Method not implemented.");
}
workerIndex(gameID: GameID): number {
throw new Error("Method not implemented.");
}
workerPath(gameID: GameID): string {
throw new Error("Method not implemented.");
}
workerPort(gameID: GameID): number {
throw new Error("Method not implemented.");
}
workerPortByIndex(workerID: number): number {
throw new Error("Method not implemented.");
}
env(): GameEnv {
throw new Error("Method not implemented.");
}
adminToken(): string {
throw new Error("Method not implemented.");
}
adminHeader(): string {
throw new Error("Method not implemented.");
}
gitCommit(): string {
throw new Error("Method not implemented.");
}
getRandomPublicGameModifiers(): PublicGameModifiers {
return {
isCompact: false,
isRandomSpawn: false,
isCrowded: false,
isHardNations: false,
};
}
async supportsCompactMapForTeams(): Promise<boolean> {
throw new Error("Method not implemented.");
}
}