Skip to main content

What Are NetField Exports?

NetField exports are the fundamental building blocks of Unreal Engine network replication. They represent individual properties and objects that are synchronized across the network during gameplay. In Fortnite replays, these exports contain all the game state data—from player positions to weapon stats to game events.

The INetFieldExportGroup Interface

All NetField exports inherit from INetFieldExportGroup:
public abstract class INetFieldExportGroup
{
    public Actor ChannelActor { get; internal set; }
    public ExternalData ExternalData { get; internal protected set; }

    public virtual bool ManualRead(string property, object value)
    {
        return false;
    }
}

Key Components

  • ChannelActor: The actor associated with this export’s network channel
  • ExternalData: Additional metadata about the export
  • ManualRead: Optional method for custom property deserialization

Export Types

The library processes dozens of export types, each representing different aspects of the game. Here are the major categories:
Path: /Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_CRepresents a player’s pawn (character) in the world. Contains:
[NetFieldExportGroup("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C", ParseType.Full)]
public class PlayerPawnC : INetFieldExportGroup
{
    [NetFieldExport("Location", RepLayoutCmdType.PropertyVector100)]
    public FVector Location { get; set; }
    
    [NetFieldExport("Rotation", RepLayoutCmdType.PropertyRotator)]
    public FRotator Rotation { get; set; }
    
    [NetFieldExport("bIsDBNO", RepLayoutCmdType.PropertyBool)]
    public bool? bIsDBNO { get; set; }
    
    [NetFieldExport("CurrentWeapon", RepLayoutCmdType.Property)]
    public ActorGUID CurrentWeapon { get; set; }
    
    [NetFieldExport("Vehicle", RepLayoutCmdType.Property)]
    public ActorGUID Vehicle { get; set; }
    
    [NetFieldExport("bIsSkydiving", RepLayoutCmdType.PropertyBool)]
    public bool? bIsSkydiving { get; set; }
    
    [NetFieldExport("bIsParachuteOpen", RepLayoutCmdType.PropertyBool)]
    public bool? bIsParachuteOpen { get; set; }
    
    // ... 100+ more properties
}
Use Cases: Player tracking, movement analysis, cosmetic data
Path: /Script/FortniteGame.FortPlayerStateAthenaRepresents persistent player information:
[NetFieldExportGroup("/Script/FortniteGame.FortPlayerStateAthena")]
public class FortPlayerState : INetFieldExportGroup
{
    [NetFieldExport("PlayerNamePrivate", RepLayoutCmdType.PropertyString)]
    public string PlayerNamePrivate { get; set; }
    
    [NetFieldExport("UniqueId", RepLayoutCmdType.PropertyNetId)]
    public string UniqueId { get; set; }
    
    [NetFieldExport("TeamIndex", RepLayoutCmdType.Enum)]
    public int? TeamIndex { get; set; }
    
    [NetFieldExport("Place", RepLayoutCmdType.PropertyInt)]
    public int? Place { get; set; }
    
    [NetFieldExport("KillScore", RepLayoutCmdType.PropertyUInt32)]
    public uint? KillScore { get; set; }
    
    [NetFieldExport("bIsABot", RepLayoutCmdType.PropertyBool)]
    public bool? bIsABot { get; set; }
    
    [NetFieldExport("bDBNO", RepLayoutCmdType.PropertyBool)]
    public bool? bDBNO { get; set; }
    
    [NetFieldExport("DeathCause", RepLayoutCmdType.Enum)]
    public EDeathCause DeathCause { get; set; }
}
Use Cases: Player identification, stats, team info, elimination tracking

Game State Exports

Path: /Game/Athena/Athena_GameState.Athena_GameState_CThe central game state object containing match-wide information:
[NetFieldExportGroup("/Game/Athena/Athena_GameState.Athena_GameState_C")]
public class GameStateC : INetFieldExportGroup
{
    [NetFieldExport("GamePhase", RepLayoutCmdType.Enum)]
    public EAthenaGamePhase GamePhase { get; set; }
    
    [NetFieldExport("PlayersLeft", RepLayoutCmdType.PropertyInt)]
    public int? PlayersLeft { get; set; }
    
    [NetFieldExport("TeamsLeft", RepLayoutCmdType.PropertyInt)]
    public int? TeamsLeft { get; set; }
    
    [NetFieldExport("SafeZonePhase", RepLayoutCmdType.PropertyByte)]
    public byte? SafeZonePhase { get; set; }
    
    [NetFieldExport("AircraftStartTime", RepLayoutCmdType.PropertyFloat)]
    public float? AircraftStartTime { get; set; }
    
    [NetFieldExport("TeamFlightPaths", RepLayoutCmdType.DynamicArray)]
    public GameStateC[] TeamFlightPaths { get; set; }
}
Use Cases: Match progression, storm phases, player counts
GameStateC is always fully parsed regardless of ParseType setting.
Storm circle/safe zone information:
Replay.GameInformation.UpdateSafeZone(safeZoneIndicator);
Use Cases: Storm tracking, zone analysis, positioning strategies

Item & Weapon Exports

Base class for all weapons:
public class BaseWeapon : INetFieldExportGroup
{
    [NetFieldExport("Owner", RepLayoutCmdType.Property)]
    public NetworkGUID Owner { get; set; }
    
    [NetFieldExport("WeaponData", RepLayoutCmdType.Property)]
    public ItemDefinitionGUID WeaponData { get; set; }
    
    [NetFieldExport("AmmoCount", RepLayoutCmdType.PropertyUInt32)]
    public uint? AmmoCount { get; set; }
    
    [NetFieldExport("WeaponLevel", RepLayoutCmdType.PropertyUInt32)]
    public uint? WeaponLevel { get; set; }
    
    [NetFieldExport("bIsReloadingWeapon", RepLayoutCmdType.PropertyBool)]
    public bool? bIsReloadingWeapon { get; set; }
}
Inherited by: Rifles, Shotguns, SMGs, Snipers, Pistols, Explosives, Throwable, Melee, etc.
Floor loot and dropped items:
case FortPickup fortPickup:
    if (ParseType >= ParseType.Normal)
    {
        if (!_fortniteSettings.IgnoreFloorLoot)
        {
            Replay.GameInformation.UpdateFortPickup(channel, fortPickup);
        }
    }
    break;
Use Cases: Loot tracking, item spawn analysis
Player inventory data:
case FortInventory inventory:
    if (!_fortniteSettings.IgnoreInventory)
    {
        Replay.GameInformation.UpdateFortInventory(channel, inventory);
    }
    break;
Use Cases: Loadout tracking, inventory management analysis

Combat Exports

Damage events (shots, hits):
case BatchedDamage batchedDamage:
    if (!_fortniteSettings.IgnoreShots)
    {
        Replay.GameInformation.UpdateBatchedDamage(channel, batchedDamage);
    }
    break;
Use Cases: Combat analysis, accuracy tracking, damage dealt
Player health and shield values:
[NetFieldExportGroup("/Script/FortniteGame.FortRegenHealthSet", ParseType.Normal)]
public class HealthSet : IHandleNetFieldExportGroup
{
    public float? HealthCurrentValue => HealthFortSet?.CurrentValue;
    public float? HealthMaxValue => HealthFortSet?.Maximum;
    public float? ShieldCurrentValue => ShieldFortSet?.CurrentValue;
    public float? ShieldMaxValue => ShieldFortSet?.Maximum;
    
    public bool HealthChange => HealthFortSet?.CurrentValue != null;
    public bool ShieldChange => ShieldFortSet?.CurrentValue != null;
}
Use Cases: Health tracking, shield monitoring, damage calculations

Building Exports

Player-built structures:
case BaseStructure baseBuild:
    Replay.GameInformation.UpdateBuild(channel, baseBuild);
    break;
Includes: Wood, Stone, Metal classesUse Cases: Build tracking, editing analysis, structure placement
Containers and props:
case BaseProp prop:
    if (!_fortniteSettings.IgnoreContainers)
    {
        Replay.GameInformation.UpdateContainer(channel, prop);
    }
    break;

Vehicle Exports

Base class for all vehicles:
case BaseVehicle vehicle:
    Replay.GameInformation.UpdateVehicle(channel, vehicle);
    break;
Inherited by: BasicCar, BasicTruck, SportsCar, TaxiCab, Boat, LootShark, etc.

Supply & Loot Exports

case SupplyDropLlamaC llama:
    Replay.GameInformation.UpdateLlama(channel, llama);
    break;
    
case SupplyDropC supplyDrop:
    Replay.GameInformation.UpdateSupplyDrop(channel, supplyDrop);
    break;
These are always fully parsed regardless of ParseType setting.
Chests, ammo boxes, etc.:
case SearchableContainer searchableContainer:
    Replay.GameInformation.UpdateSearchableContainer(channel, searchableContainer);
    break;

How Exports Are Processed

The processing flow (FortniteReplayReader.cs:82-198):
protected override void OnExportRead(uint channel, INetFieldExportGroup exportGroup)
{
    ++TotalPropertiesRead;
    
    // Set up context for processing
    Replay.GameInformation.NetGUIDToPathName = GuidCache.NetGuidToPathName;
    Replay.GameInformation.Settings = _fortniteSettings;
    
    // Type-based routing
    switch (exportGroup)
    {
        case PlayerPawnC playerPawn:
            // Only process if ParseType is sufficient
            if (ParseType >= ParseType.Normal)
            {
                Replay.GameInformation.UpdatePlayerPawn(channel, playerPawn);
            }
            break;
            
        case FortPlayerState playerState:
            // Always process player state
            Replay.GameInformation.UpdatePlayerState(
                channel, 
                playerState, 
                GuidCache.NetworkGameplayTagNodeIndex
            );
            break;
            
        // ... more cases
    }
}

Custom Export Handling

To extend the library with custom export processing:
public class CustomReplayReader : ReplayReader
{
    protected override void OnExportRead(uint channel, INetFieldExportGroup exportGroup)
    {
        base.OnExportRead(channel, exportGroup);
        
        // Custom handling for specific export types
        switch (exportGroup)
        {
            case PlayerPawnC pawn when pawn.bIsSkydiving == true:
                LogSkydivingEvent(channel, pawn);
                break;
                
            case GameStateC gameState when gameState.PlayersLeft <= 10:
                LogTopTenSituation(gameState);
                break;
        }
    }
}

Export Attributes

Exports use attributes for metadata:
// Specify the Unreal path and minimum ParseType
[NetFieldExportGroup("/Game/Path/To/Class.Class_C", ParseType.Normal)]
public class MyExport : INetFieldExportGroup
{
    // Map individual properties
    [NetFieldExport("PropertyName", RepLayoutCmdType.PropertyType)]
    public PropertyType PropertyName { get; set; }
}

// Redirect to a different path
[RedirectPath("AlternatePath")]
public class RedirectedExport : INetFieldExportGroup
{
    // ...
}

Performance Considerations

  1. Export Volume: A typical replay processes 10,000-100,000+ exports
  2. Selective Processing: Use ParseType and settings to filter exports
  3. Channel Tracking: Exports are tied to network channels (uint identifiers)
  4. Memory Usage: Full parsing can consume significant memory for long replays
Processing all exports at ParseType.Full can take several seconds for a complete match replay.

Custom Parsing

Learn how to customize parsing behavior

Troubleshooting

Debug export processing issues

Build docs developers (and LLMs) love