package game import ( "errors" "fmt" "time" ) // Config configures the game subsystem: where the engine loads its dictionaries, // which version new games pin, and the two background knobs — the turn-timeout // sweep cadence and the idle window after which the live-game cache evicts a game // (it is then rebuilt from the journal on next access, so this never affects // correctness). It composes into the backend configuration. type Config struct { // DictDir is the directory holding the committed DAWG files. Sourced from // BACKEND_DICT_DIR; it has no default and must be set. DictDir string // DictVersion labels the dictionary version new games pin. Sourced from // BACKEND_DICT_VERSION. DictVersion string // TimeoutSweepInterval is how often the sweeper scans for overdue turns. // Sourced from BACKEND_GAME_TIMEOUT_SWEEP_INTERVAL. TimeoutSweepInterval time.Duration // CacheTTL is how long an idle game stays resident before eviction. Sourced // from BACKEND_GAME_CACHE_TTL. CacheTTL time.Duration } // DefaultConfig returns the game configuration defaults. DictDir is deliberately // empty: it must be supplied through the environment. func DefaultConfig() Config { return Config{ DictVersion: "v1", TimeoutSweepInterval: time.Minute, CacheTTL: 24 * time.Hour, } } // Validate reports whether the configuration is usable. func (c Config) Validate() error { if c.DictDir == "" { return errors.New("game: BACKEND_DICT_DIR must be set") } if c.DictVersion == "" { return errors.New("game: BACKEND_DICT_VERSION must not be empty") } if c.TimeoutSweepInterval <= 0 { return fmt.Errorf("game: timeout sweep interval must be positive, got %s", c.TimeoutSweepInterval) } if c.CacheTTL <= 0 { return fmt.Errorf("game: cache TTL must be positive, got %s", c.CacheTTL) } return nil }