Skip to main content
The GameState class contains information about the match state, timing, team configuration, and session details. It provides context about the game mode, tournament settings, and real-time match progression.

Overview

The GameState is accessible through GameInformation.GameState and contains metadata about the match configuration and current state.
var gameState = gameInfo.GameState;

Console.WriteLine($"Session ID: {gameState.SessionId}");
Console.WriteLine($"Match Time: {gameState.MatchTime}");
Console.WriteLine($"Playlist: {gameState.PlaylistId}");
Console.WriteLine($"Max Players: {gameState.MaxPlayers}");
Console.WriteLine($"Team Size: {gameState.TeamSize}");

Properties

Session & Identity

SessionId
string
required
Unique identifier for this game session.
PlaylistId
string
required
The playlist/game mode identifier (e.g., “Playlist_DefaultSolo”, “Playlist_DefaultDuo”, “Playlist_DefaultSquad”).
MatchTime
DateTime
required
UTC timestamp when the match started.

Timing

GameWorldStartTime
float
required
Game world time in seconds when the match world started (used as baseline for delta calculations).
AirCraftStartTime
float
required
Game time in seconds when the battle bus started its path.
InitialSafeZoneStartTime
float
required
Game time in seconds when the first storm circle begins shrinking.
MatchEndTime
float
required
Game time in seconds when the match ended.
CurrentWorldTime
float
required
Current game world time in seconds (updated during parsing).
DeltaGameTime
float
required
Computed property: CurrentWorldTime - GameWorldStartTime. Represents elapsed match time in seconds.

Teams & Players

MaxPlayers
int
required
Maximum number of players configured for this match.
TotalTeams
int
required
Total number of teams in the match.
TeamSize
int
required
Number of players per team, computed as MaxPlayers / TotalTeams.For older replays where TotalTeams is 0, falls back to OldTeamSize.
TotalBots
int
required
Total number of bots that started in the match.
RemainingPlayers
int
required
Number of players still alive (updated during parsing).
CurrentTeams
int
required
Number of teams still in the match (updated during parsing).
RemainingBots
int
required
Number of bots still alive (updated during parsing).
WinningTeam
uint
required
Team number/index of the winning team.

Game Mode

LargeTeamGame
bool
required
Whether this is a large team game mode (e.g., Team Rumble, 50v50).
EEventTournamentRound
EEventTournamentRound
required
Tournament round information if this is a tournament match.Default value is EEventTournamentRound.EEventTournamentRound_MAX for non-tournament games.
EventTournamentRound
int
required
Integer representation of the tournament round.

Storm & Safe Zones

SafeZonePhase
byte
required
Current storm phase number (0 = no storm, 1 = first circle, etc.).

Battle Bus

BusPaths
List<Aircraft>
required
Collection of battle bus flight paths. Each Aircraft contains:
  • FlightStartLocation: Starting position of the bus
  • FlightRotation: Direction/rotation of the bus path
Most matches have one bus path, but team modes may have multiple.

Additional Info

ReplayRecorder
Player
required
Reference to the Player object who recorded this replay.
PoiManager
FortPoiManager
required
Point of Interest manager containing named locations and their tags.
TotalPlayerStructures
int
required
Total number of player-built structures in the match.
RecorderActor
uint
required
Internal actor ID of the replay recorder.
ElapsedTime
float
required
Elapsed time since last update (internal use).
OldTeamSize
int
required
Team size for older replay formats (fallback when TotalTeams is unavailable).

Examples

Match Overview

void PrintMatchOverview(GameState state)
{
    Console.WriteLine("===== Match Information =====");
    Console.WriteLine($"Session: {state.SessionId}");
    Console.WriteLine($"Match Time: {state.MatchTime:yyyy-MM-dd HH:mm:ss} UTC");
    Console.WriteLine($"Playlist: {state.PlaylistId}");
    Console.WriteLine();
    
    Console.WriteLine("Game Configuration:");
    Console.WriteLine($"  Max Players: {state.MaxPlayers}");
    Console.WriteLine($"  Total Teams: {state.TotalTeams}");
    Console.WriteLine($"  Team Size: {state.TeamSize}");
    Console.WriteLine($"  Total Bots: {state.TotalBots}");
    Console.WriteLine($"  Large Team Game: {state.LargeTeamGame}");
    Console.WriteLine();
    
    if (state.WinningTeam > 0)
    {
        Console.WriteLine($"Winning Team: {state.WinningTeam}");
    }
}

Match Timing

void PrintMatchTiming(GameState state)
{
    var busStart = TimeSpan.FromSeconds(state.AirCraftStartTime - state.GameWorldStartTime);
    var zoneStart = TimeSpan.FromSeconds(state.InitialSafeZoneStartTime - state.GameWorldStartTime);
    var matchEnd = TimeSpan.FromSeconds(state.MatchEndTime - state.GameWorldStartTime);
    
    Console.WriteLine("Match Timeline:");
    Console.WriteLine($"  Battle Bus Launch: {busStart:mm\\:ss}");
    Console.WriteLine($"  First Zone Shrink: {zoneStart:mm\\:ss}");
    Console.WriteLine($"  Match End: {matchEnd:mm\\:ss}");
    Console.WriteLine($"  Total Duration: {matchEnd:mm\\:ss}");
}

Battle Bus Path

void PrintBusPath(GameState state)
{
    Console.WriteLine($"Battle Bus Paths: {state.BusPaths.Count}");
    
    for (int i = 0; i < state.BusPaths.Count; i++)
    {
        var bus = state.BusPaths[i];
        Console.WriteLine($"\nBus {i + 1}:");
        Console.WriteLine($"  Start: ({bus.FlightStartLocation.X:F0}, {bus.FlightStartLocation.Y:F0}, {bus.FlightStartLocation.Z:F0})");
        Console.WriteLine($"  Rotation: {bus.FlightRotation}");
    }
}

Determine Game Mode

string GetGameMode(GameState state)
{
    // Check playlist ID
    if (state.PlaylistId != null)
    {
        if (state.PlaylistId.Contains("Solo")) return "Solo";
        if (state.PlaylistId.Contains("Duo")) return "Duos";
        if (state.PlaylistId.Contains("Squad")) return "Squads";
        if (state.PlaylistId.Contains("Trio")) return "Trios";
    }
    
    // Fall back to team size
    return state.TeamSize switch
    {
        1 => "Solo",
        2 => "Duos",
        3 => "Trios",
        4 => "Squads",
        _ => "Unknown"
    };
}

var mode = GetGameMode(gameState);
Console.WriteLine($"Game Mode: {mode}");

Tournament Detection

bool IsTournamentMatch(GameState state)
{
    return state.EEventTournamentRound != EEventTournamentRound.EEventTournamentRound_MAX;
}

if (IsTournamentMatch(gameState))
{
    Console.WriteLine($"Tournament Match - Round: {gameState.EventTournamentRound}");
}
else
{
    Console.WriteLine("Public Match");
}

Player Count Over Time

// Track remaining players as you parse
void MonitorPlayerCount(GameState state)
{
    Console.WriteLine($"Players Remaining: {state.RemainingPlayers}");
    Console.WriteLine($"Teams Remaining: {state.CurrentTeams}");
    Console.WriteLine($"Bots Remaining: {state.RemainingBots}");
    Console.WriteLine($"Current Phase: {state.SafeZonePhase}");
    
    var elapsedTime = TimeSpan.FromSeconds(state.DeltaGameTime);
    Console.WriteLine($"Elapsed Time: {elapsedTime:mm\\:ss}");
}

Replay Recorder Info

if (gameState.ReplayRecorder != null)
{
    Console.WriteLine($"Replay recorded by: {gameState.ReplayRecorder.DisplayName}");
    Console.WriteLine($"  Epic ID: {gameState.ReplayRecorder.EpicId}");
    Console.WriteLine($"  Platform: {gameState.ReplayRecorder.Platform}");
    Console.WriteLine($"  Placement: #{gameState.ReplayRecorder.Placement}");
}

Build docs developers (and LLMs) love