Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Server Administration Guide

Audience: Server operators, tournament organizers, competitive league administrators, and content creators / casters.

Prerequisites: Familiarity with TOML (for server configuration — if you know INI files, you know TOML), command-line tools, and basic server administration. For design rationale behind the configuration system, see D064 in decisions/09a-foundation.md and D067 for the TOML/YAML format split.

Status: This guide describes the planned configuration system. Iron Curtain is in the design phase — no implementation exists yet. All examples show intended behavior.


Who This Guide Is For

Iron Curtain’s configuration system serves four professional roles. Each role has different needs, and this guide is structured so you can skip to the sections relevant to yours.

RoleTypical TasksKey Sections
Tournament organizerSet up bracket matches, control pauses, configure spectator feeds, disable surrender votesQuick Start, Match Lifecycle, Spectator, Vote Framework, Tournament Operations
Community server adminRun a persistent relay for a clan or region, manage connections, tune anti-cheat, monitor server healthQuick Start, Relay Server, Anti-Cheat, Telemetry & Monitoring, Security Hardening
Competitive league adminConfigure rating parameters, define seasons, tune matchmaking for population sizeRanking & Seasons, Matchmaking, Deployment Profiles
Content creator / casterSet spectator delay, configure VoIP, maximize observer countSpectator, Communication, Training & Practice

Regular players do not need this guide. Player-facing settings (game speed, graphics, audio, keybinds) are configured through the in-game settings menu and settings.toml — see 02-ARCHITECTURE.md for those.


Quick Start

Running a Relay Server with Defaults

Every parameter has a sane default. A bare relay server works without any configuration file:

./ic-server

This starts a relay on the default port with:

  • Up to 1,000 simultaneous connections
  • Up to 100 concurrent games
  • 16 players per game maximum
  • All default match rules, ranking, and anti-cheat settings

Creating Your First Configuration

To customize, create a server_config.toml in the server’s working directory:

# server_config.toml — only override what you need to change
[relay]
max_connections = 200
max_games = 50

Any parameter you omit uses its compiled default. You never need to specify the full schema — only your overrides.

Start the server with a specific config file:

./ic-server --config /path/to/server_config.toml

Validating a Configuration

Before deploying a new config, validate it without starting the server:

ic server validate-config /path/to/server_config.toml

This checks for:

  • TOML syntax errors
  • Unknown keys (with suggestions for typos)
  • Out-of-range values (reports which values will be clamped)
  • Cross-parameter inconsistencies (e.g., matchmaking.initial_range > matchmaking.max_range)

Configuration System

Three-Layer Architecture

Configuration uses three layers with clear precedence:

Priority (highest → lowest):
┌────────────────────────────────────────┐
│ Layer 3: Runtime Cvars                 │  /set relay.tick_deadline_ms 100
│ Live changes via console commands.     │  Persist until restart only.
├────────────────────────────────────────┤
│ Layer 2: Environment Variables         │  IC_RELAY_TICK_DEADLINE_MS=100
│ Override config file per-value.        │  Docker-friendly.
├────────────────────────────────────────┤
│ Layer 1: server_config.toml            │  [relay]
│ Single file, all subsystems.           │  tick_deadline_ms = 100
├────────────────────────────────────────┤
│ Layer 0: Compiled Defaults             │  (built into the binary)
└────────────────────────────────────────┘

Rule: Each layer overrides the one below it. A runtime cvar always wins. An environment variable overrides the TOML file. The TOML file overrides compiled defaults.

Environment Variable Naming

Every cvar maps to an environment variable by:

  1. Uppercasing the cvar name
  2. Replacing dots (.) with underscores (_)
  3. Prefixing with IC_
CvarEnvironment Variable
relay.tick_deadline_msIC_RELAY_TICK_DEADLINE_MS
match.pause.max_per_playerIC_MATCH_PAUSE_MAX_PER_PLAYER
rank.system_tauIC_RANK_SYSTEM_TAU
spectator.delay_ticksIC_SPECTATOR_DELAY_TICKS

Runtime Cvars

Server operators with Host or Admin permission can change parameters live:

/set relay.max_games 50
/get relay.max_games
/list relay.*

Runtime changes persist until the server restarts — they are not written back to the TOML file. This is intentional: runtime adjustments are for in-the-moment tuning, not permanent policy changes.

Hot Reload

Reload server_config.toml without restarting:

  • Unix: Send SIGHUP to the relay process
  • Any platform: Use the /reload_config admin console command

Hot-reloadable parameters (changes take effect for new matches, not in-progress ones):

  • All match lifecycle parameters (match.*)
  • All vote parameters (vote.*)
  • All spectator parameters (spectator.*)
  • All communication parameters (chat.*)
  • Anti-cheat thresholds (anticheat.*)
  • Telemetry settings (telemetry.*)

Restart-required parameters (require stopping and restarting the server):

  • Relay connection limits (relay.max_connections, relay.max_connections_per_ip)
  • Database PRAGMA tuning (db.*)
  • Workshop P2P transport settings (workshop.p2p.*)

Validation Behavior

The configuration system enforces correctness at every layer:

CheckBehaviorExample
Range clampingOut-of-range values are clamped; a warning is loggedrelay.tick_deadline_ms: 10 → clamped to 50, logs WARN
Type safetyWrong types (string where int expected) produce a startup errorrelay.max_games: "fifty" → error, server won’t start
Unknown keysTypos produce a warning with the closest valid key (edit distance)rleay.max_gamesWARN: unknown key 'rleay.max_games', did you mean 'relay.max_games'?
Cross-parameterInconsistent pairs are automatically correctedrank.rd_floor: 400, rank.rd_ceiling: 350 → floor set to 300 (ceiling - 50)

Cross-Parameter Consistency Rules

These relationships are enforced automatically:

  • catchup_sim_budget_pct + catchup_render_budget_pct = 100. If not, render budget adjusts to 100 - sim_budget.
  • rank.rd_floor < rank.rd_ceiling. If violated, floor is set to ceiling - 50.
  • matchmaking.initial_rangematchmaking.max_range. If violated, initial is set to max.
  • match.penalty.abandon_cooldown_1st_secs2nd3rd. If violated, higher tiers are raised to match lower.
  • anticheat.degrade_at_depthanticheat.queue_depth. If violated, degrade is set to queue_depth × 0.8.

Subsystem Reference

Each subsystem section below explains: what the parameters control, when you would change them, and recommended values for common scenarios. For the complete parameter registry with types and ranges, see D064 in decisions/09f-tools.md.

Relay Server (relay.*)

The relay server accepts player connections, orders and forwards game data between players, and enforces protocol-level rules. These parameters control the relay’s resource limits and timing behavior.

Connection Management

ParameterDefaultWhat It Controls
relay.max_connections1000Total simultaneous TCP connections the relay accepts
relay.max_connections_per_ip5Connections from a single IP address
relay.connect_rate_per_sec10New connections accepted per second (rate limit)
relay.idle_timeout_unauth_secs60Seconds before kicking an unauthenticated connection
relay.idle_timeout_auth_secs300Seconds before kicking an idle authenticated player
relay.max_games100Maximum concurrent game sessions

When to change these:

  • LAN tournament: Raise max_connections_per_ip to 10–20 (many players behind one NAT). Lower max_games to match your bracket size.
  • Small community server: Lower max_connections to 200 and max_games to 50 to match your hardware.
  • Large public server: Raise max_connections toward 5000–10000 and max_games toward 1000, but ensure your hardware can sustain it (see Capacity Planning).
  • Under DDoS / connection spam: Lower connect_rate_per_sec to 3–5 and idle_timeout_unauth_secs to 15–30.

Timing & Reconnection

ParameterDefaultWhat It Controls
relay.tick_deadline_ms120Maximum milliseconds the relay waits for a player’s orders before marking them late
relay.reconnect_timeout_secs60Window for a disconnected player to rejoin a game in progress
relay.timing_feedback_interval30Ticks between timing feedback messages sent to clients

When to change these:

  • Competitive league (low latency): Keep effective deadline behavior inside 90–140ms envelope (D060). If running a fixed value, start around 110ms.
  • Casual / high-latency regions: Keep effective deadline behavior inside 120–220ms envelope (D060). If running a fixed value, start around 160ms.
  • Training / debugging: Raise tick_deadline_ms to 500 and reconnect_timeout_secs to 300 for generous timeouts.

Recommendation: Leave tick_deadline_ms at 120 unless you have specific latency data for your player base. The adaptive run-ahead system handles most cases automatically.

QoS Envelope Alignment (D060)

The relay’s match QoS auto-profile should stay within these envelopes:

Queue TypeDeadline EnvelopeShared Run-Ahead EnvelopeSuggested Fixed Baseline (if auto-profile unavailable)
Ranked / Competitive90–140 ms3–5 ticks110 ms
Casual / Community120–220 ms4–7 ticks160 ms
Training / Debug200–500 ms6–15 ticks300 ms

If your runtime currently supports only a fixed relay.tick_deadline_ms, choose the baseline above and tune by observed late-order rate. If match auto-profile envelopes are available, prefer those and keep fixed overrides minimal.

Catchup (Reconnection Behavior)

ParameterDefaultWhat It Controls
relay.catchup.sim_budget_pct80% of frame budget for simulation during reconnection catchup
relay.catchup.render_budget_pct20% of frame budget for rendering during reconnection catchup
relay.catchup.max_ticks_per_frame30Maximum sim ticks processed per render frame during catchup

When to change these: These control how aggressively a reconnecting client catches up to the live game state. Higher max_ticks_per_frame means faster catchup but more stutter during reconnection. The defaults work well for most deployments. Only increase max_ticks_per_frame (to 60–120) if you need sub-10-second reconnections and your players have powerful hardware.


Match Lifecycle (match.*)

These parameters control the lifecycle of individual games, from lobby acceptance through post-game.

ParameterDefaultWhat It Controls
match.accept_timeout_secs30Time for players to accept a matchmade game
match.loading_timeout_secs120Maximum map loading time before a player is dropped
match.countdown_secs3Pre-game countdown (after everyone loads)
match.postgame_active_secs30Post-game lobby active period (chat, stats visible)
match.postgame_timeout_secs300Auto-close the post-game lobby after this many seconds
match.grace_period_secs120Grace period — abandoning during this window doesn’t penalize as harshly
match.grace_completion_pct5Maximum game completion % for grace void (abandoned games during grace don’t count)

When to change these:

  • Tournament: Raise countdown_secs to 5–10 for dramatic effect. Lower loading_timeout_secs only if you’ve verified all participants have fast hardware.
  • Casual community: Lower postgame_timeout_secs to 120 — players want to re-queue quickly.
  • Mod development: Raise loading_timeout_secs to 600 for large total conversion mods.

Pause Configuration (match.pause.*)

ParameterDefault (ranked)Default (casual)What It Controls
match.pause.max_per_player2-1 (unlimited)Pauses allowed per player per game (-1 = unlimited)
match.pause.max_duration_secs120300Maximum single pause duration before auto-unpause
match.pause.unpause_grace_secs3030Warning countdown before auto-unpause
match.pause.min_game_time_secs300Minimum game time before pausing is allowed
match.pause.spectator_visibletruetrueWhether spectators see the pause screen

Recommendations per deployment:

Deploymentmax_per_playermax_duration_secsRationale
Tournament LAN5300Admin-mediated; allow equipment issues
Competitive league160Strict; minimize stalling
Casual community-1600Fun-first; let friends pause freely
Training / practice-136001-hour pauses for debugging

Disconnect Penalties (match.penalty.*)

ParameterDefaultWhat It Controls
match.penalty.abandon_cooldown_1st_secs300First abandon: 5-minute queue cooldown
match.penalty.abandon_cooldown_2nd_secs1800Second abandon (within 24 hrs): 30-minute cooldown
match.penalty.abandon_cooldown_3rd_secs7200Third+ abandon: 2-hour cooldown
match.penalty.habitual_abandon_count3Abandons in 7 days to trigger habitual penalty
match.penalty.habitual_cooldown_secs86400Habitual abandon cooldown (24 hours)
match.penalty.decline_cooldown_escalation“60,300,900”Escalating cooldowns for declining match accepts

When to change these:

  • Tournament: Set abandon_cooldown_1st_secs to 0 — admin handles penalties manually.
  • Casual: Lower all penalties (e.g., 60/300/600) to keep the mood light.
  • Competitive league: Keep defaults or increase for stricter enforcement.

Spectator Configuration (spectator.*)

ParameterDefault (casual)Default (ranked)What It Controls
spectator.allow_livetruetrueWhether live spectating is enabled at all
spectator.delay_ticks60 (3s†)2400 (120s†)Feed delay in ticks (†at Normal ~20 tps). For ranked/tournament, the relay clamps this upward to enforce V59’s wall-time floor (120s/180s) regardless of game speed — see below
spectator.max_per_match5050Maximum spectators per match
spectator.full_visibilitytruefalseWhether spectators see both teams
spectator.allow_player_disabletruefalseWhether players can opt out of being spectated

V59 wall-time floor enforcement: The security floor for ranked (120s) and tournament (180s) is defined in wall-clock seconds, not ticks. The relay computes the minimum tick count at match start: min_delay_ticks = floor_secs × tps_for_speed_preset. If spectator.delay_ticks falls below this computed minimum, the relay clamps it upward. This ensures the floor holds at any game speed (D060). The tick values below assume Normal (~20 tps); at other speeds the relay adjusts automatically.

Ticks (Normal ~20 tps)Real TimeUse Case
0No delayUnranked practice / training (not ranked or tournament — see V59 floors)
603 secondsCasual viewing
24002 minutesRanked minimum (V59 floor — relay enforces 120s at any speed)
36003 minutesTournament minimum (V59 floor — relay enforces 180s at any speed)
90007.5 minCompetitive league (stricter anti-sniping)
1800015 minMaximum supported delay

For casters / content creators:

  • Set full_visibility: true so casters can see entire battlefield
  • Set max_per_match: 200 or higher for large audiences
  • Delay depends on whether stream sniping is a concern in your context

Vote Framework (vote.*)

The vote system allows players to initiate and resolve team votes during matches.

Global Settings

ParameterDefaultWhat It Controls
vote.max_concurrent_per_team1Active votes allowed simultaneously per team

Per-Vote-Type Parameters

Each vote type (surrender, kick, remake, draw) follows the same parameter schema:

Parameter PatternSurrenderKickRemakeDraw
vote.<type>.enabledtruetruetruetrue
vote.<type>.duration_secs30304560
vote.<type>.cooldown_secs1803000300
vote.<type>.min_game_time_secs3001200600
vote.<type>.max_per_player-1212

Kick-specific protections:

ParameterDefaultWhat It Controls
vote.kick.army_value_protection_pct40Can’t kick a player controlling >40% of team’s army value
vote.kick.premade_consolidationtruePremade group members’ kicks count as a single vote
vote.kick.protect_last_playertrueCan’t kick the last remaining teammate

Remake-specific:

ParameterDefaultWhat It Controls
vote.remake.max_game_time_secs300Latest point (5 min) a remake vote can be called

Recommendations:

  • Tournament: Disable surrender and remake entirely (vote.surrender.enabled: false, vote.remake.enabled: false). The tournament admin decides match outcomes.
  • Casual community: Consider disabling kick (vote.kick.enabled: false) in small communities — handle disputes personally.
  • Competitive league: Keep defaults. Consider lowering vote.surrender.min_game_time_secs to 180 for faster concession.

Protocol Limits (protocol.*)

These parameters define hard limits on what players can send through the relay. They are the first line of defense against abuse.

ParameterDefaultWhat It Controls
protocol.max_order_size4096Maximum single order size (bytes)
protocol.max_orders_per_tick256Hard ceiling on orders per tick per player
protocol.max_chat_length512Maximum chat message characters
protocol.max_file_transfer_size65536Maximum file transfer size (bytes)
protocol.max_pending_per_peer262144Maximum buffered data per peer (bytes)
protocol.max_voice_packets_per_second50VoIP packet rate limit
protocol.max_voice_packet_size256VoIP packet size limit (bytes)
protocol.max_pings_per_interval3Contextual pings per 5-second window
protocol.max_minimap_draw_points32Points per minimap drawing
protocol.max_markers_per_player10Tactical markers per player
protocol.max_markers_per_team30Tactical markers per team

Warning: Raising protocol limits above defaults increases the abuse surface. The defaults are tuned for competitive play. Only increase them if you have a specific need and understand the anti-cheat implications.

When to change these:

  • Large team games (8v8): You may want to raise max_markers_per_team to 50–60 for more tactical coordination.
  • VoIP quality: Raising max_voice_packets_per_second beyond 50 is unlikely to improve quality — the Opus codec is efficient. Consider raising chat.voip_bitrate_kbps instead.
  • Mod development: Mods that use very large orders might need max_order_size raised to 8192 or 16384.

Communication (chat.*)

ParameterDefaultWhat It Controls
chat.rate_limit_messages5Messages allowed per rate window
chat.rate_limit_window_secs3Rate limit window duration
chat.voip_bitrate_kbps32Opus VoIP encoding bitrate per player
chat.voip_enabledtrueEnable relay-forwarded VoIP
chat.tactical_poll_expiry_secs15Tactical poll voting window

VoIP bitrate guidance:

BitrateQualityBandwidth per PlayerRecommended For
16 kbpsAcceptable~2 KB/sLow-bandwidth environments
32 kbpsGood (default)~4 KB/sMost deployments
64 kbpsExcellent~8 KB/sTournament casting (clear commentary)
128 kbpsStudio~16 KB/sRarely needed; diminishing returns

When to change these:

  • Tournament with casters: Raise voip_bitrate_kbps to 64 for clearer casting audio.
  • Persistent chat trolling: Lower rate_limit_messages to 3 and raise rate_limit_window_secs to 5.
  • Disable VoIP entirely: Set chat.voip_enabled: false if your community uses a separate voice platform (Discord, TeamSpeak).

Anti-Cheat / Behavioral Analysis (anticheat.*)

These parameters tune the automated anti-cheat system. The system analyzes match outcomes and in-game behavioral patterns to flag suspicious activity for review.

ParameterDefaultWhat It Controls
anticheat.ranked_upset_threshold250Rating difference that triggers automatic review when the lower-rated player wins
anticheat.new_player_max_games40Games below which new-player heuristics apply
anticheat.new_player_win_chance0.75Win probability that triggers review for new accounts
anticheat.rapid_climb_min_gain80Rating gain that triggers rapid-climb review
anticheat.rapid_climb_chance0.90Trigger probability for rapid rating climb
anticheat.behavioral_flag_score0.4Relay behavioral score that triggers review
anticheat.min_duration_secs120Minimum match duration for analysis
anticheat.max_age_months6Oldest match data considered
anticheat.queue_depth1000Maximum analysis queue depth
anticheat.degrade_at_depth800Queue depth at which probabilistic triggers degrade

Tuning philosophy:

  • Lower thresholds = more sensitive = more false positives. Appropriate for high-stakes competitive environments.
  • Higher thresholds = less sensitive = fewer false positives. Appropriate for casual communities where false positives are more disruptive than cheating.

Recommendations:

Deploymentranked_upset_thresholdbehavioral_flag_scoreRationale
Tournament500.3Review every notable upset; strict
Competitive league1500.35Moderately strict
Casual community4000.6Relaxed; trust the community


Sub-Pages

SectionTopicFile
Operations & DeploymentSubsystem reference continued (ranking/Glicko-2, matchmaking, AI, telemetry, DB, Workshop/P2P, compression) + deployment profiles + Docker/Kubernetes + tournament operations + security hardening + capacity planning + troubleshooting + CLI reference + engine constantsoperations.md