ValorantReplayParser.Encoding 0.1.0-alpha.2

This is a prerelease version of ValorantReplayParser.Encoding.
dotnet add package ValorantReplayParser.Encoding --version 0.1.0-alpha.2
                    
NuGet\Install-Package ValorantReplayParser.Encoding -Version 0.1.0-alpha.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ValorantReplayParser.Encoding" Version="0.1.0-alpha.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ValorantReplayParser.Encoding" Version="0.1.0-alpha.2" />
                    
Directory.Packages.props
<PackageReference Include="ValorantReplayParser.Encoding" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ValorantReplayParser.Encoding --version 0.1.0-alpha.2
                    
#r "nuget: ValorantReplayParser.Encoding, 0.1.0-alpha.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ValorantReplayParser.Encoding@0.1.0-alpha.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ValorantReplayParser.Encoding&version=0.1.0-alpha.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=ValorantReplayParser.Encoding&version=0.1.0-alpha.2&prerelease
                    
Install as a Cake Tool

ValorantReplayParser

Build Test Quality Gate Status <a href="https://discord.gg/QSRSfcege7"><img src="https://discordapp.com/api/guilds/764106279752826930/widget.png?style=banner2"/></a>

ValorantReplayParser reads VALORANT replay files (.vrf) and emits typed gameplay events and replay metadata. It is a narrow, VALORANT-specific parser, not a general Unreal Engine replay parser.

The NuGet release 0.1.0-alpha.2 is experimental. Replay formats and the public API may change as the reverse-engineered format understanding improves. A replay version passing the compatibility checks does not mean every gameplay feature in that replay is decoded. See the release notes and migration guide before upgrading from 0.1.0-alpha.1.

Requirements and installation

The package targets net10.0; consumers need the .NET 10 runtime. Building this repository requires the .NET 10 SDK. Install the prerelease with:

dotnet add package ValorantReplayParser --version 0.1.0-alpha.2

Read a replay

The default constructor selects the full parse profile and the built-in VALORANT descriptor catalog. Supply an IReplayEventSink to receive events. The sink is called synchronously as events are produced:

using System;
using System.IO;
using Replay.Models.Errors;
using Replay.Models.Events;
using Replay.Valorant;

var reader = new ValorantReplayReader(eventSink: new ConsoleEventSink());

try
{
    // Open a fresh stream at the start of the replay for each read.
    using var stream = File.OpenRead("path/to/replay.vrf");
    ValorantReplayReadResult result = reader.Read(stream);

    Console.WriteLine($"Read status: {result.Status}");
    Console.WriteLine($"Packets: {result.PacketStats.PacketCount}");

    foreach (var diagnostic in result.Diagnostics)
    {
        Console.Error.WriteLine($"{diagnostic.Code}: {diagnostic.Message}");
    }

    if (result.SuppressedDiagnosticCount > 0)
    {
        Console.Error.WriteLine(
            $"{result.SuppressedDiagnosticCount} additional diagnostics were omitted from the retained list.");
    }
}
catch (ReplayParseException exception)
{
    // Includes invalid replay metadata/version and malformed replay data.
    Console.Error.WriteLine($"Replay could not be parsed: {exception.Message}");
}

sealed class ConsoleEventSink : IReplayEventSink
{
    public void Emit(ReplayEvent replayEvent)
    {
        Console.WriteLine(
            $"{replayEvent.GetType().Name} at {replayEvent.TimeSeconds:0.000}s " +
            $"(packet {replayEvent.PacketId})");
    }
}

Read returns a detached ValorantReplayReadResult containing metadata, packet and bunch statistics, diagnostics, and export-group summaries. It does not retain the input archive or stream, so the result remains usable after those inputs are disposed.

Status is Completed when no recoverable warnings were recorded and CompletedWithWarnings when one or more warnings were recorded. Diagnostics retains up to 1,000 structured warnings; TotalDiagnosticCount counts all warnings and SuppressedDiagnosticCount reports warnings beyond that retained limit. Current warnings identify partial-bunch sequence errors, incomplete partial bunches at end of input, and speculative typed-decoder fallbacks to raw payloads.

Malformed replay structure, invalid required reads, unsupported full-parse versions, and resource-limit violations fail with a ReplayParseException subtype. A returned result means the container was traversed under those rules; it does not promise that every known or unknown VALORANT feature was semantically decoded or that the file contains a complete match.

Events are streamed to the sink and are provisional until Read returns successfully. If a later parse error occurs, events already emitted cannot be rolled back. Some semantic enrichers defer events until related replay data is available, so event timestamps are not guaranteed to increase globally in emission order. If the sink throws, parsing stops and the original sink exception is propagated.

Inventory and economy descriptors

Inventory and economy data arrive as typed payloads on ExportGroupReceived and RpcReceived events:

  • AresInventoryDescriptor exposes character and equippable references, active state, correction fields, and 16 named slot references in EAresItemSlot order. GetDecodedItemSlots() enumerates only references observed in this update, including explicit GUID zero clears.
  • ItemSlotDescriptor.Contents exposes a single item reference. MultiItemSlotDescriptor.MultiContents exposes an ItemSlotContentsUpdate containing the declared array Count and sparse indexed Updates. Omitted indices retain prior values; a reduced count truncates the array, and count zero means a known empty array.
  • PurchasedItemComponentDescriptor exposes replicated purchase provenance: purchaseable, purchasing player, session flag, and transaction source.

AresInventoryDescriptor is in Replay.Valorant.GameState; slot and purchase types are in Replay.Valorant.Inventory, and economy descriptors are in Replay.Valorant.Economy. Select ExportCategory.Inventory or ExportCategory.Economy in a parse profile to retain the corresponding identity fields too. Payloads represent individual updates. Use HasDecoded(propertyName) to distinguish observed properties from defaults; nullable slot references are null when absent from that update, and GUID zero explicitly clears a reference. Use ExportGroupReceived.IsDeleted and ActorClosed to track removals in consumer-owned state.

MoneyManagementComponentDescriptor exposes observed credits, OwnerExclusivePlayerInfoDescriptor.RoundInfos exposes sparse round credit/loadout updates, and gun request parameter descriptors expose recorded request fields. Identity joins, merged inventory/economy snapshots, weapon-name resolution, credit deltas, and round buy classification belong to the analyser. The parser retains the wire references and timestamps without inferring when a client finished equipping.

Metadata-only reads and input ownership

Use ReadMetadata to inspect replay metadata without parsing packet payloads. The example reuses the reader from the preceding sample:

using var metadataStream = File.OpenRead("path/to/replay.vrf");
ValorantReplayMetadata metadata = reader.ReadMetadata(metadataStream);

Console.WriteLine(metadata.FullParseSupportStatus);
Console.WriteLine(metadata.FullParseUnsupportedReason);

Metadata parsing can report UnsupportedVersion; a full Read rejects such a replay early. ReadMetadata still throws for malformed metadata. Reopen the file for a later full read: the stream overload reads from its current position, buffers the remaining bytes, and advances the supplied stream to its end. The reader does not dispose the caller's stream. FBinaryArchive(Stream) also buffers the remaining stream contents in memory, so replay size contributes to memory use; the partial-bunch limits do not bound this whole-file buffer.

The same reader instance may be reused for sequential reads, but it does not support concurrent or reentrant reads. With the FBinaryArchive overloads, the archive must be positioned at the start of the replay for each operation. Supply a new archive positioned at the beginning for a metadata read followed by a full read.

Parse profiles and support

The default ParseProfile enables all currently defined categories and selects all built-in descriptors and fields unless additional filters are set. ParseProfile.Minimal sets enabled categories to None, which filters out fields and RPCs assigned gameplay categories. Category-neutral fields can still be decoded. It is useful when replay metadata and packet/bunch traversal are needed without categorized gameplay decoding; it is not a lightweight substitute for full semantic parsing and it does not bypass replay-version validation. Other profiles can select categories, export paths, and fields.

The full reader requires replay version 5.3.2, game network protocol version 0, Unreal version values 522/1009, and a registered payload transform for the replay branch. The transform registry currently contains exactly these branches:

  • ++Ares-Core+release-11.06
  • ++Ares-Core+release-11.07
  • ++Ares-Core+release-11.08
  • ++Ares-Core+release-11.09
  • ++Ares-Core+release-11.10
  • ++Ares-Core+release-11.11
  • ++Ares-Core+release-12.00
  • ++Ares-Core+release-12.01
  • ++Ares-Core+release-12.02
  • ++Ares-Core+release-12.03
  • ++Ares-Core+release-12.04
  • ++Ares-Core+release-12.05
  • ++Ares-Core+release-12.06
  • ++Ares-Core+release-12.07
  • ++Ares-Core+release-12.08
  • ++Ares-Core+release-12.09
  • ++Ares-Core+release-12.10
  • ++Ares-Core+release-12.11
  • ++Ares-Core+release-13.00
  • ++Ares-Core+release-13.01
  • ++Ares-Core+release-13.02
  • ++Ares-Core+release-13.04
  • ++Ares-Core+release-13.05
  • ++Ares-Core+release-china-13.05
  • ++Ares-Core+release-13.06

An unregistered branch or a mismatch in the replay, protocol, or Unreal versions is unsupported. The reader fails early rather than trying a guessed compatibility path. These version checks establish compatibility with the parser's known container and transform layout, not complete gameplay-semantic coverage. The China 13.05 transform has recovered payload-vector tests; a complete China replay fixture is not included in this repository.

Within those explicitly supported branches, descriptors and custom decoders may register release boundaries. A boundary applies from that VALORANT release forward until another boundary replaces it. This is intended for known semantic changes such as shifted field handles; it does not make an unknown branch or wire format supported.

WasDecoded on emitted export-group and RPC events indicates that the applicable decoder path ran; it is not a completeness guarantee. For decoded descriptor payloads, HasDecoded(propertyName) indicates whether that specific property was decoded and assigned. A RawPayloadFallback diagnostic means an explicitly speculative typed decoder rolled back and preserved the bounded payload as raw data.

Custom descriptor catalogs

The descriptorCatalog constructor argument replaces the built-in descriptor catalog completely. To add custom descriptors while keeping the built-in VALORANT descriptors, begin with ValorantDescriptors.CreateCatalog() and add your descriptors to that catalog before constructing the reader:

using Replay.Valorant;
using Replay.Valorant.Descriptors;
using Replay.Models.Descriptors;
using Replay.Models.Replay;

var catalog = ValorantDescriptors.CreateCatalog();
catalog.Add(new ExportGroupDescriptor("/Game/Custom/Example", ExportCategory.Debug));

var legacy = new ExportGroupDescriptor("/Game/Custom/Versioned", ExportCategory.Debug);
var release1305 = new ExportGroupDescriptor("/Game/Custom/Versioned", ExportCategory.Debug);
catalog.Add(
    new VersionedDefinition<ExportGroupDescriptor>(legacy)
        .From(new ReplayReleaseVersion(13, 5), release1305));

var reader = new ValorantReplayReader(descriptorCatalog: catalog);

Replace the example descriptors with your implementations and field definitions. FieldDescriptorBuilder.Decode and RpcDescriptorBuilder.Decode also accept VersionedDefinition values for layouts where only the decoder changes. Class-net-cache variants use the corresponding DescriptorCatalog.Add overload. Low-level ExportBindingRegistry callers must supply a ReplayReleaseVersion when a selected definition contains release boundaries; ValorantReplayReader derives it from the replay branch automatically.

Starting from CreateCatalog() also preserves VALORANT's stable-subobject class paths and path-alias provider. Passing a new empty DescriptorCatalog intentionally replaces those defaults too.

Progress

Area Status
Player Movement ✔
Agents ✔
Abilities 🚧
Gunplay ✔
Game State ❌
World State ❌
Stable public API ❌

Projects

  • Replay.Models: shared models, parse results, constants, context contracts, and parser errors.
  • Replay.Encoding: byte/bit archives, FBinaryArchive, payload transforms, and Oodle decompression.
  • Replay.Unreal: replay-info, chunk scanning, replay-header parsing, and the replay-container pipeline.
  • Replay.Valorant: VALORANT models, export groups, RPCs, ClassNetCaches, and gameplay interpretation.
  • CliReader: CLI/demo entry point.
  • *.Tests: NUnit test projects.

Build and test

dotnet build "ValorantReplayParser.sln"
dotnet test "ValorantReplayParser.sln"

CLI

Log decoded replay activity and a parse summary:

dotnet run --project "src\CliReader\CliReader.csproj" -- log "C:\path\to\replay.vrf"

Export replay events and movement as JSON:

dotnet run --project "src\CliReader\CliReader.csproj" -- export "C:\path\to\replay.vrf" --output "C:\path\to\export"

Show the full command or subcommand help:

dotnet run --project "src\CliReader\CliReader.csproj" -- --help
dotnet run --project "src\CliReader\CliReader.csproj" -- export --help

Useful libraries

  • VRFKit — Rust library for parsing .vrf files.

Special thanks

  • To the folks from FortniteReplayDecompressor for their work and documentation of the replay system.
  • GPT 5.5 for reverse engineering VALORANT payload transformation and movement encoding.

License and disclaimer

This project is distributed under the MIT License; see LICENSE.

This project is an independent, community-developed tool and is not affiliated with, endorsed by, sponsored by, or approved by Riot Games. VALORANT, Riot Games, and all related trademarks are the property of Riot Games, Inc.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ValorantReplayParser.Encoding:

Package Downloads
ValorantReplayParser.Unreal

VALORANT replay container, header, chunk, and network parsing.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0-alpha.2 44 10/8/2026
0.1.0-alpha.1 70 9/30/2026