Guide

Game match lobby and pregame systems explained

Harbor Arena shipped ranked 5v5 with a fast queue: match found, three-second countdown, load in. Players loved the speed until telemetry showed 41% of ranked matches ended before round one — not from skill gaps but from queue-abandon, AFK teammates, and parties scrambling to configure kits after spawn. Rematch churn hit 38% because the first minute felt like a coin flip on whether all ten humans were actually present and ready.

A match lobby is the structured pregame phase between “match found” and “round one live.” It coordinates ready checks, team assignment, optional map veto phases, loadout locks, and reconnect grace so competitive integrity starts before the first tick. This guide covers lobby FSM design, party merge rules, timing budgets, integration with match format and economy, the Harbor Arena refactor, a technique decision table, pitfalls, and a production checklist.

What a lobby actually does

Casual games often treat “match found” as the finish line. Competitive titles need a contract phase where every participant confirms intent, sees who they are playing with and against, and finishes setup tasks that would be unfair mid-round. Core responsibilities:

  • Presence verification — distinguish “in queue” from “at keyboard ready to play.”
  • Roster finalization — merge parties into balanced teams without splitting friends unexpectedly.
  • Configuration window — loadouts, agents, skins, and settings that must be locked before server authority begins.
  • Information parity — both teams see the same map, mode, and rules before committing.
  • Graceful failure — replace leavers, requeue fairly, or cancel without MMR punishment when the lobby cannot start.

Skip the lobby and you push all of this into the first 30 seconds of live play — exactly when buy phases and objective setups are most sensitive to missing players.

Lobby finite-state machine

Production lobbies are best modeled as an explicit FSM, not ad-hoc timers. A typical ranked flow:

  1. MATCH_FOUND — notify all matched players; start accept timer (15–30s).
  2. ACCEPT_PENDING — each player accepts or declines; first decline cancels or triggers backfill depending on mode.
  3. ROSTER_LOCK — parties merged; captain tags assigned; smurf-detection flags surfaced to server.
  4. TEAM_ASSIGN — shuffle or skill-balance sides; show team rosters with privacy rules (hide exact MMR if desired).
  5. MAP_VETO (optional) — hand off to pick-ban sub-FSM; timeout defaults to random legal map.
  6. LOADOUT_CONFIG — edit presets until lock; show opponent agent picks if mode is reveal-based.
  7. READY_CHECK — final per-player ready; idle detection kicks AFK accounts.
  8. COUNTDOWN — synchronized 3–5s; no config changes; warm assets.
  9. HANDOFF — transition to match server; spawn players in pre-round freeze.

Each state has entry actions (play sound, disable queue button), exit guards (all accepted? map chosen?), and telemetry events. Logging state transitions makes “why did my match cancel?” support tickets answerable in one query.

Accept phase and queue-abandon prevention

The accept window is your first anti-abandon lever. Design choices:

  • Single decline policy — one “decline” cancels entire lobby and requeues nine others (harsh but simple).
  • Backfill policy — decline opens slot to priority queue waiter; extends accept timer once.
  • Partial accept — require 9/10 accepts to proceed; risky for fairness unless backfill is fast.
  • Penalty escalation — declining or missing accept applies increasing queue cooldown; prevents serial dodgers.

Harbor Arena originally used a 5s accept with no penalty. Dodgers farmed favorable map seeds by declining until lobbies felt random. Moving to 20s accept + 2min escalating cooldown and showing map pool before accept cut unexplained cancels by half. Pair accept UI with audio and OS notifications — mobile clients miss silent popups.

Party merge and team assignment

Parties arrive as graph nodes; the lobby must flatten them into two teams without violating party-size rules (e.g., max 3-stack in ranked). Common patterns:

  • Keep parties intact — never split a party across teams unless flex queue explicitly allows it.
  • Captain relay — party leader accepts for the group; reduces accept spam but hides individual AFK.
  • Role reservation — parties declare roles before merge; matcher pre-validates composition.
  • Side preference — optional “prefer attack/defense” hint consumed during side assignment.

Show merged rosters early. Players who discover a stream sniper or smurf account at spawn will leave anyway — better to offer a limited dodge token during ROSTER_LOCK with tracked limits than to waste a full match server.

Map veto and mode hooks

When ranked uses pick-ban, the lobby FSM delegates to a nested veto machine rather than duplicating timers. Contract between layers:

  • Lobby passes legal map pool + series length (BO1/BO3).
  • Veto sub-FSM returns final map list + starting side if applicable.
  • Lobby resumes at LOADOUT_CONFIG with map-specific preset slots unlocked.
  • Global lobby timeout still applies — veto cannot extend total pregame budget unbounded.

For casual modes, skip veto and show a single random map during ACCEPT so players know what they are joining. Ambush modes need longer loadout phases on large maps; scale LOADOUT_CONFIG duration by map size tier, not a global constant.

Loadout lock timing

Loadout editing belongs in lobby, not buy phase — unless your design intentionally sells mid-round swaps. Lock rules:

  • Soft lock at READY_CHECK — edits allowed until individual ready; prevents last-second peer pressure changes.
  • Hard lock at COUNTDOWN — server rejects preset diffs; client UI disables slots.
  • Reveal timing — show enemy loadouts at COUNTDOWN start for counter-pick modes; hide until round one for blind modes.
  • Validation pass — reject illegal attachments before HANDOFF so buy phase does not refund impossible kits.

Harbor moved kit validation from spawn to LOADOUT_CONFIG, eliminating 54% → 16% wrong-kit deaths in the first engagement (the same metric tracked in the loadout guide, now gated earlier).

AFK detection and reconnect grace

Accepting is not readiness. Monitor input heartbeat, menu focus, and voice channel join during READY_CHECK:

  • Idle threshold — no input for 45s in lobby flags AFK; auto-unready or replace from backfill pool.
  • Reconnect token — disconnect during COUNTDOWN reserves slot for 60s; bot placeholder stands in pre-round freeze.
  • Reconnect during live — separate from lobby policy; lobby only guarantees roster snapshot at HANDOFF.
  • Forgive first offense — ranked first AFK warning without ban; repeat within 24h triggers timeout.

Distinguish client crash from intentional leave via session resume tokens. Players who crash during COUNTDOWN should rejoin the same lobby instance, not a new queue.

Countdown, handoff and pre-round freeze

COUNTDOWN synchronizes all clients to match server tick zero. Best practices:

  • Run countdown on match server authority, not client-only timers.
  • Warm level streaming and shader caches during COUNTDOWN, not during first combat frame.
  • Pre-round freeze after spawn lets players orient without damage; duration should match mode (longer for tactical, shorter for TDM).
  • Handoff payload includes roster IDs, map seed, veto history, and locked loadouts for anti-cheat replay.

If HANDOFF fails for one client, hold COUNTDOWN and retry once before canceling — premature cancel punishes nine connected players for one slow disk.

Harbor Arena refactor walkthrough

Harbor replaced instant-start with a LobbyOrchestrator service:

  1. AcceptGate — 20s window, map pool preview, decline cooldown curve.
  2. PartyMerge — keep 3-stacks intact; expose roster MMR band to players.
  3. VetoBridge — BO1 ranked uses 2-ban/1-pick; 90s cap then random fallback.
  4. LoadoutLock — 45s config phase with server-side validation and share-code import.
  5. ReadyPulse — input heartbeat; AFK replace from backfill before COUNTDOWN.
  6. SyncCountdown — 5s server-authoritative; asset warm parallelized.

Four weeks post-ship on ranked: queue-abandon before round one 41% → 9%, rematch churn 38% → 21%, average pregame length rose from 8s to 94s but match completion rose 26%. Players accepted the trade when loading screens showed useful config UI instead of black voids.

Technique decision table

ScenarioPreferAvoid
Ranked 5v5 with map poolAccept + veto + loadout lock FSMInstant spawn with post-hoc dodge
Casual TDMShort accept only; random map90s pick-ban phase
Party-heavy audienceCaptain accept + keep stacks intactSplitting duos across teams silently
High kit complexityLong LOADOUT_CONFIG with validationEditing during buy phase round one
Esports BO3Nested veto per map + series stateRe-rolling entire lobby between maps
Mobile clientsPush notifications + 25s accept5s silent popup accept

Common pitfalls

  • Infinite veto — captains stall; enforce global lobby timeout and auto-random.
  • Hidden roster until spawn — players leave at first frame; show teams during ROSTER_LOCK.
  • Client-only countdown — desync causes early shots; server must own tick zero.
  • No decline penalty — queue becomes a reroll slot machine for map dodgers.
  • Loadout edits after lock — desync between clients and server authority; hard reject diffs.
  • Ignoring backfill latency — 30s backfill in a 60s lobby guarantees cancel; size phases accordingly.
  • Same UX for casual and ranked — casual players bounce off esports-length lobbies.

Production checklist

  • Explicit lobby FSM with logged state transitions.
  • Accept window with notifications and decline cooldown curve.
  • Party merge rules that never silently split groups.
  • Nested map veto with global timeout and random fallback.
  • Loadout config phase with server validation before HANDOFF.
  • Ready check with input heartbeat and AFK backfill.
  • Server-authoritative countdown and reconnect token.
  • Handoff payload for roster, map, and locked kits.
  • Telemetry: abandon rate by state, time-in-state histograms.
  • Separate casual vs ranked pregame duration budgets.
  • Support tools to replay lobby timeline for dispute tickets.

Key takeaways

  • Lobbies are a contract phase — they verify presence, finalize rosters, and lock config before authority starts.
  • FSM design beats scattered timers — every state needs entry actions, guards, and telemetry.
  • Accept and ready are different gates — punishing dodgers and detecting AFK require both.
  • Integrate veto and loadout as nested phases — with bounded total pregame budget.
  • Harbor Arena cut pre-round abandons from 41% to 9% by replacing instant start with a structured LobbyOrchestrator flow.

Related reading