Refactor: Split config into Config and ServerConfig

This commit is contained in:
evanpelle
2024-12-25 14:04:19 -08:00
parent 111775a3f4
commit 57cbf5c55e
16 changed files with 101 additions and 79 deletions
+26 -12
View File
@@ -1,21 +1,35 @@
import { Difficulty, GameType, Gold, Player, PlayerID, PlayerInfo, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game";
import { Colord, colord } from "colord";
import { devConfig } from "./DevConfig";
import { GameID } from "../Schemas";
import { preprodConfig } from "./PreprodConfig";
import { prodConfig } from "./ProdConfig";
import { consolex } from "../Consolex";
import { GameConfig } from "../Schemas";
import { DefaultConfig } from "./DefaultConfig";
import { DevConfig, DevServerConfig } from "./DevConfig";
export enum GameEnv {
Dev,
Prod
}
export function getConfig(gameConfig: GameConfig): Config {
const sc = getServerConfig()
switch (process.env.GAME_ENV) {
case 'dev':
return new DevConfig(sc, gameConfig)
case 'preprod':
case 'prod':
consolex.log('using prod config')
return new DefaultConfig(sc, gameConfig)
default:
throw Error(`unsupported server configuration: ${process.env.GAME_ENV}`)
}
}
export function getConfig(): Config {
export function getServerConfig(): ServerConfig {
switch (process.env.GAME_ENV) {
case 'dev':
consolex.log('using dev config')
return devConfig
return new DevServerConfig()
case 'preprod':
consolex.log('using preprod config')
return preprodConfig
@@ -27,17 +41,17 @@ export function getConfig(): Config {
}
}
export function getGameEnv(): GameEnv {
return GameEnv.Prod
}
export interface Config {
discordBotSecret(): string
theme(): Theme;
percentageTilesOwnedToWin(): number
export interface ServerConfig {
turnIntervalMs(): number
gameCreationRate(): number
lobbyLifetime(): number
}
export interface Config {
serverConfig(): ServerConfig
gameConfig(): GameConfig
theme(): Theme;
percentageTilesOwnedToWin(): number
numBots(): number
spawnNPCs(): boolean
numSpawnPhaseTurns(gameType: GameType): number
+26 -13
View File
@@ -1,13 +1,35 @@
import { Difficulty, GameType, Gold, Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game";
import { GameID } from "../Schemas";
import { GameConfig } from "../Schemas";
import { assertNever, distSort, manhattanDist, simpleHash, within } from "../Util";
import { Config, Theme } from "./Config";
import { Config, ServerConfig, Theme } from "./Config";
import { pastelTheme } from "./PastelTheme";
export abstract class DefaultServerConfig implements ServerConfig {
turnIntervalMs(): number {
return 100
}
gameCreationRate(): number {
return 10 * 60 * 1000
}
lobbyLifetime(): number {
return 10 * 120 * 1000
}
}
export abstract class DefaultConfig implements Config {
abstract discordBotSecret(): string
export class DefaultConfig implements Config {
constructor(private _serverConfig: ServerConfig, private _gameConfig: GameConfig) {
}
gameConfig(): GameConfig {
return this._gameConfig
}
serverConfig(): ServerConfig {
return this._serverConfig
}
difficultyModifier(difficulty: Difficulty): number {
switch (difficulty) {
@@ -162,15 +184,6 @@ export abstract class DefaultConfig implements Config {
numBots(): number {
return 400
}
turnIntervalMs(): number {
return 100
}
gameCreationRate(): number {
return 10 * 60 * 1000
}
lobbyLifetime(): number {
return 10 * 120 * 1000
}
theme(): Theme { return pastelTheme; }
attackLogic(attackTroops: number, attacker: Player, defender: Player | TerraNullius, tileToConquer: Tile): { attackerTroopLoss: number; defenderTroopLoss: number; tilesPerTickUsed: number } {
+23 -16
View File
@@ -1,20 +1,9 @@
import { GameType, Player, PlayerInfo, UnitInfo, UnitType } from "../game/Game";
import { DefaultConfig } from "./DefaultConfig";
import { GameConfig } from "../Schemas";
import { ServerConfig } from "./Config";
import { DefaultConfig, DefaultServerConfig } from "./DefaultConfig";
export const devConfig = new class extends DefaultConfig {
discordBotSecret(): string {
throw new Error("Method not implemented.");
}
unitInfo(type: UnitType): UnitInfo {
const info = super.unitInfo(type)
const oldCost = info.cost
info.cost = (p: Player) => oldCost(p) / 10000
return info
}
percentageTilesOwnedToWin(): number {
return 95
}
export class DevServerConfig extends DefaultServerConfig {
numSpawnPhaseTurns(gameType: GameType): number {
return gameType == GameType.Singleplayer ? 40 : 200
// return 100
@@ -25,6 +14,24 @@ export const devConfig = new class extends DefaultConfig {
lobbyLifetime(): number {
return 10 * 1000
}
}
export class DevConfig extends DefaultConfig {
constructor(sc: ServerConfig, gc: GameConfig) {
super(sc, gc);
}
unitInfo(type: UnitType): UnitInfo {
const info = super.unitInfo(type)
const oldCost = info.cost
info.cost = (p: Player) => oldCost(p) / 10000
return info
}
percentageTilesOwnedToWin(): number {
return 95
}
// tradeShipSpawnRate(): number {
// return 10
// }
@@ -39,4 +46,4 @@ export const devConfig = new class extends DefaultConfig {
// return false
// }
}
}
+2 -5
View File
@@ -1,8 +1,5 @@
import { DefaultConfig } from "./DefaultConfig";
import { DefaultConfig, DefaultServerConfig } from "./DefaultConfig";
export const preprodConfig = new class extends DefaultConfig {
discordBotSecret(): string {
throw new Error("Method not implemented.");
}
export const preprodConfig = new class extends DefaultServerConfig {
}
+2 -5
View File
@@ -1,8 +1,5 @@
import { DefaultConfig } from "./DefaultConfig";
import { DefaultConfig, DefaultServerConfig } from "./DefaultConfig";
export const prodConfig = new class extends DefaultConfig {
discordBotSecret(): string {
throw new Error("Method not implemented.");
}
export const prodConfig = new class extends DefaultServerConfig {
}
+1 -1
View File
@@ -126,7 +126,7 @@ export class Executor {
this.random.nextID()
),
nation.cell,
nation.strength * this.gs.config().difficultyModifier(this.gs.gameConfig().difficulty)
nation.strength * this.gs.config().difficultyModifier(this.gs.config().gameConfig().difficulty)
))
}
return execs
-1
View File
@@ -314,7 +314,6 @@ export interface Game {
addExecution(...exec: Execution[]): void
nations(): Nation[]
config(): Config
gameConfig(): GameConfig
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void
units(...types: UnitType[]): Unit[]
unitInfo(type: UnitType): UnitInfo
+3 -8
View File
@@ -13,8 +13,8 @@ import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/E
import { UnitImpl } from "./UnitImpl";
import { consolex } from "../Consolex";
export function createGame(terrainMap: TerrainMapImpl, miniMap: TerrainMap, eventBus: EventBus, config: Config, gameConfig: GameConfig): Game {
return new GameImpl(terrainMap, miniMap, eventBus, config, gameConfig)
export function createGame(terrainMap: TerrainMapImpl, miniMap: TerrainMap, eventBus: EventBus, config: Config): Game {
return new GameImpl(terrainMap, miniMap, eventBus, config)
}
export type CellString = string
@@ -45,7 +45,6 @@ export class GameImpl implements MutableGame {
private _miniMap: TerrainMap,
public eventBus: EventBus,
private _config: Config,
private _gameConfig: GameConfig,
) {
this._terraNullius = new TerraNulliusImpl(this)
this._width = _terrainMap.width();
@@ -67,10 +66,6 @@ export class GameImpl implements MutableGame {
))
}
gameConfig(): GameConfig {
return this._gameConfig
}
addFallout(tile: Tile) {
const ti = tile as TileImpl
if (tile.hasOwner()) {
@@ -149,7 +144,7 @@ export class GameImpl implements MutableGame {
}
inSpawnPhase(): boolean {
return this._ticks <= this.config().numSpawnPhaseTurns(this._gameConfig.gameType)
return this._ticks <= this.config().numSpawnPhaseTurns(this.config().gameConfig().gameType)
}
ticks(): number {