package lobby import ( "fmt" "time" ) // Config configures auto-match robot substitution: how long an open game waits for a // human opponent before a robot is substituted, and how often the reaper scans. type Config struct { // RobotWait is the fixed minimum an open auto-match game waits for a human // opponent before it is eligible for robot substitution. Sourced from // BACKEND_LOBBY_ROBOT_WAIT. RobotWait time.Duration // RobotWaitJitter is a random extra wait in [0, RobotWaitJitter) added on top of // RobotWait per game, so the substitution time varies. Sourced from // BACKEND_LOBBY_ROBOT_WAIT_JITTER. RobotWaitJitter time.Duration // ReaperInterval is how often the reaper scans for open games due for a robot. // Sourced from BACKEND_LOBBY_REAPER_INTERVAL. ReaperInterval time.Duration } // DefaultConfig returns the matchmaking defaults: a guaranteed 90-second wait for a // human plus up to 90 random seconds (90–180 s total) before a robot substitutes // (docs/ARCHITECTURE.md §7), scanned every five seconds. func DefaultConfig() Config { return Config{ RobotWait: 90 * time.Second, RobotWaitJitter: 90 * time.Second, ReaperInterval: 5 * time.Second, } } // Validate reports whether the configuration is usable. func (c Config) Validate() error { if c.RobotWait <= 0 { return fmt.Errorf("lobby: robot wait must be positive, got %s", c.RobotWait) } if c.RobotWaitJitter < 0 { return fmt.Errorf("lobby: robot wait jitter must not be negative, got %s", c.RobotWaitJitter) } if c.ReaperInterval <= 0 { return fmt.Errorf("lobby: reaper interval must be positive, got %s", c.ReaperInterval) } return nil }