Skip to content

GameConfig ​

GameConfig 是引擎运行期配置,在 GameEngine 构造时由 resolveConfig 解析得到,之后只读地驱动引擎的运行参数(动作队列上限、默认方向、随机种子)。

概述 ​

引擎配置由 GameConfigInit 描述,调用方仅提供关心的字段;缺省值由 DEFAULT_GAME_CONFIG 提供。resolveConfig 负责合并两者并产出完整 GameConfig。

seed 字段单独处理:仅在调用方显式传入(包括 0)时才采用,否则保持 undefined,由 GameEngine 自行决定是否自动生成种子。这样可以区分"调用方要求可回放"与"由引擎决定确定性"两种语义。

GameConfig 接口 ​

ts
export interface GameConfig {
  gameId: string
  maxActionsPerTick: number
  defaultDirection: 1 | -1
  seed?: number
}
属性类型说明
gameIdstring当前对局唯一标识,会写入 GameState.gameId,便于日志与回放定位
maxActionsPerTicknumber单次 dispatch tick 内允许处理的最大 Action 数量。超出时抛出 ActionQueueOverflowError
defaultDirection1 | -1默认回合推进方向:1 为正向座位递增,-1 为逆向。仅作为引擎默认值,具体游戏可在运行时通过 GameState.variables 覆写
seed?number引擎 RandomProvider 的种子。若为 undefined,引擎在构造时会生成一个种子并存入 GameState,使对局可被回放

DEFAULT_GAME_CONFIG ​

ts
export const DEFAULT_GAME_CONFIG: GameConfig = {
  gameId: 'game-default',
  maxActionsPerTick: 1000,
  defaultDirection: 1
}

引擎默认配置。当 GameConfigInit 中未提供对应字段时使用。

maxActionsPerTick: 1000 是经验性安全上限,足以容纳常规链式事件,但仍能在失控循环下及时熔断。

GameConfigInit 接口 ​

ts
export interface GameConfigInit {
  gameId?: string
  maxActionsPerTick?: number
  defaultDirection?: 1 | -1
  seed?: number
}

创建引擎时允许传入的可选配置项。所有字段均可省略,缺省值由 DEFAULT_GAME_CONFIG 提供,便于调用方仅覆盖关心的字段。

resolveConfig() ​

ts
export function resolveConfig(init?: GameConfigInit): GameConfig

参数 ​

参数类型必填说明
initGameConfigInit否调用方传入的部分配置

返回值 ​

GameConfig —— 合并后的完整配置。

行为 ​

  • gameId / maxActionsPerTick / defaultDirection 取 init 字段或 DEFAULT_GAME_CONFIG
  • 对 seed 单独处理:仅在调用方显式传入(包括 0)时才采用,否则保持 undefined
ts
function resolveConfig(init?: GameConfigInit): GameConfig {
  const cfg: GameConfig = {
    gameId: init?.gameId ?? DEFAULT_GAME_CONFIG.gameId,
    maxActionsPerTick: init?.maxActionsPerTick ?? DEFAULT_GAME_CONFIG.maxActionsPerTick,
    defaultDirection: init?.defaultDirection ?? DEFAULT_GAME_CONFIG.defaultDirection
  }
  if (init?.seed !== undefined) {
    cfg.seed = init.seed
  }
  return cfg
}

示例 ​

ts
import { resolveConfig, DEFAULT_GAME_CONFIG } from 'decklet'

const cfg1 = resolveConfig()
// { gameId: 'game-default', maxActionsPerTick: 1000, defaultDirection: 1 }

const cfg2 = resolveConfig({ gameId: 'my-game', seed: 123456 })
// { gameId: 'my-game', maxActionsPerTick: 1000, defaultDirection: 1, seed: 123456 }

const cfg3 = resolveConfig({ seed: 0 })
// { gameId: 'game-default', maxActionsPerTick: 1000, defaultDirection: 1, seed: 0 }
// 注意:seed=0 被视为显式传入

与 GameEngine 的协作 ​

GameEngine 构造时通过 resolveConfig 解析配置:

ts
constructor(config?: GameConfigInit & { validation?: ValidationMode }) {
  this.config = resolveConfig(config)
  const seed = this.config.seed ?? generateRandomSeed()
  this.config.seed = seed   // 把实际使用的种子回写到 config
  this.randomProvider =
    this.config.seed !== undefined
      ? new SeededRandomProvider(this.config.seed)
      : new MathRandomProvider()
  // ...
}

调用方可通过 engine.getConfig() 读取最终的配置(包括引擎自动生成的 seed):

ts
const engine = new GameEngine()
const cfg = engine.getConfig()
console.log(cfg.seed)  // 引擎自动生成的种子

示例 ​

ts
import { GameEngine } from 'decklet'

// 完全使用默认配置
const engine1 = new GameEngine()

// 自定义 gameId 与 maxActionsPerTick
const engine2 = new GameEngine({
  gameId: 'room-42',
  maxActionsPerTick: 500
})

// 传入 seed 让对局可回放
const engine3 = new GameEngine({ seed: 123456 })

// 关闭状态校验(生产热路径)
const engine4 = new GameEngine({ validation: 'none' })

注意事项 ​

  • seed = 0 被视为显式传入(init.seed !== undefined 判断)
  • 引擎构造后会把实际使用的种子回写到 config,外部可通过 getConfig() 读取
  • engine.getConfig() 返回的是浅拷贝,外部修改不会影响引擎内部配置