ValveKeyValue 0.50.0.474

dotnet add package ValveKeyValue --version 0.50.0.474
                    
NuGet\Install-Package ValveKeyValue -Version 0.50.0.474
                    
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="ValveKeyValue" Version="0.50.0.474" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ValveKeyValue" Version="0.50.0.474" />
                    
Directory.Packages.props
<PackageReference Include="ValveKeyValue" />
                    
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 ValveKeyValue --version 0.50.0.474
                    
#r "nuget: ValveKeyValue, 0.50.0.474"
                    
#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 ValveKeyValue@0.50.0.474
                    
#: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=ValveKeyValue&version=0.50.0.474
                    
Install as a Cake Addin
#tool nuget:?package=ValveKeyValue&version=0.50.0.474
                    
Install as a Cake Tool

<h1 align="center"><img src="./Misc/logo.png" width="64" height="64" align="center"> Valve Key Value for .NET</h1>

<p align="center"> <a href="https://github.com/ValveResourceFormat/ValveKeyValue/actions" title="Build Status"><img alt="Build Status" src="https://img.shields.io/github/actions/workflow/status/ValveResourceFormat/ValveKeyValue/ci.yml?logo=github&label=Build&logoColor=ffffff&style=for-the-badge&branch=master"></a> <a href="https://www.nuget.org/packages/ValveKeyValue/" title="NuGet"><img alt="NuGet" src="https://img.shields.io/nuget/v/ValveKeyValue.svg?logo=nuget&label=NuGet&logoColor=ffffff&color=004880&style=for-the-badge"></a> <a href="https://app.codecov.io/gh/ValveResourceFormat/ValveKeyValue" title="Code Coverage"><img alt="Code Coverage" src="https://img.shields.io/codecov/c/github/ValveResourceFormat/ValveKeyValue/master?logo=codecov&label=Coverage&logoColor=ffffff&color=F01F7A&style=for-the-badge"></a> </p>

KeyValues is a simple key-value pair format used by Valve in Steam and the Source engine for configuration files, game data, and more (.vdf, .res, .acf, etc.). This library aims to be fully compatible with Valve's various implementations of KeyValues format parsing (believe us, it's not consistent).

Core Type

The library is built around a single type:

  • KVObject (class) -- a value node. Can be a scalar (string, int, float, bool, etc.), a binary blob, an array, or a named collection of children. Keys (names) are stored in the parent container, not on the child -- similar to how JSON works.
  • KVDocument (class, extends KVObject) -- a deserialized document with a root key Name and optional Header.

All types are shared across KV1 and KV3 -- you can deserialize from one format and serialize to another. However, not all value types are supported by all formats:

Feature KV1 Text KV1 Binary KV3 Text
Collections Yes (list-backed, allows duplicate keys) Yes (list-backed) Yes (dict-backed, O(1) lookup)
Arrays Emulated as objects with numeric keys No (throws) Yes (native)
Binary blobs No No (throws) Yes (native)
Scalars Yes Yes Yes
Flags No No Yes

When constructing objects programmatically, use KVObject.Collection() (dict-backed) for general use and KV3 output, or KVObject.ListCollection() (list-backed) when you need duplicate keys or KV1 compatibility. Deserialization picks the appropriate backing store automatically.

KVObject

Constructing

// Scalar values (typed constructors)
var obj = new KVObject("hello");    // string
var obj = new KVObject(42);         // int
var obj = new KVObject(3.14f);      // float
var obj = new KVObject(true);       // bool

// Implicit conversion from primitives
KVObject obj = "hello";
KVObject obj = 42;

// Dictionary-backed collection (O(1) lookup, no duplicate keys)
var obj = KVObject.Collection();                     // empty
var obj = new KVObject();                            // same as above

// List-backed collection (preserves insertion order, allows duplicate keys, for KV1)
var obj = KVObject.ListCollection();                 // empty

// Build up children
var obj = new KVObject();
obj["name"] = "Dota 2";                              // implicit string -> KVObject
obj["appid"] = 570;                                   // implicit int -> KVObject

// Array
var arr = KVObject.Array();                           // empty
var arr = KVObject.Array([ new KVObject("a"), new KVObject("b") ]); // from elements

// Binary blob
var blob = KVObject.Blob(new byte[] { 0x01, 0x02, 0x03 });

// Null value
var nul = KVObject.Null();

Reading values

KVDocument data = kv.Deserialize(stream);

// Root key name (only on KVDocument)
string rootName = data.Name;

// String indexer returns KVObject (supports chaining)
string name = (string)data["config"]["name"];
int version = (int)data["version"];
float scale = (float)data["scale"];
bool enabled = (bool)data["settings"]["enabled"];

// Array elements by index
float x = (float)data["position"][0];

// Check existence
if (data.ContainsKey("optional")) { ... }
if (data.TryGetValue("optional", out var child)) { ... }

// Null-safe (indexer returns null for missing keys)
KVObject val = data["missing"]; // null

// Direct access to value properties
KVValueType type = data.ValueType;
KVFlag flag = data["texture"].Flag;
ReadOnlySpan<byte> bytes = data["blob"].AsSpan();

Modifying

// Set scalar (implicit conversion)
data["name"] = "new name";
data["count"] = 42;

// Chained writes work (reference semantics)
data["config"]["resolution"] = "1920x1080";

// Add children to collections
data.Add("newprop", 42);           // implicit int -> KVObject
data.Add("text", "value");         // implicit string -> KVObject

// Add elements to arrays
arr.Add(3.14f);                    // implicit float -> KVObject

// Remove
data.Remove("deprecated");
arr.RemoveAt(2);
data.Clear();

// Set flags directly
data["texture"].Flag = KVFlag.Resource;

Enumerating

// KVObject implements IEnumerable<KeyValuePair<string, KVObject>>
// Keys are the child names, values are the child KVObjects
foreach (var (key, child) in data)
{
    Console.WriteLine($"{key} = {(string)child}");
}

// Keys and Values properties
var keys = data.Keys;            // IEnumerable<string>
var values = data.Values;        // IEnumerable<KVObject>

// Array elements have null keys
foreach (var (key, element) in arrayObj)
{
    // key is null for array elements
    Console.WriteLine((string)element);
}

// Values on arrays returns elements directly (no KVP wrapper)
foreach (var element in arrayObj.Values)
{
    Console.WriteLine((string)element);
}

// Scalars yield nothing
foreach (var child in scalarObj) { } // empty

KeyValues1

Used by Steam and the Source engine.

Deserializing text

Basic deserialization

var stream = File.OpenRead("file.vdf"); // or any other Stream

var kv = KVSerializer.Create(KVSerializationFormat.KeyValues1Text);
KVDocument data = kv.Deserialize(stream);

Console.WriteLine(data["some key"]);

Typed deserialization

public class SimpleObject
{
    public string Name { get; set; }
    public string Value { get; set; }
}

var stream = File.OpenRead("file.vdf"); // or any other Stream

var kv = KVSerializer.Create(KVSerializationFormat.KeyValues1Text);
KVObject data = kv.Deserialize<SimpleObject>(stream);

Options

The Deserialize method also accepts a KVSerializerOptions object.

By default, operating system specific conditionals are enabled based on the OS the code is running on (RuntimeInformation).

KVSerializerOptions has the following options:

  • Conditions - List of conditions to use to match conditional values.
  • HasEscapeSequences - Whether the parser should translate escape sequences (e.g. \n, \t).
  • EnableValveNullByteBugBehavior - Whether invalid escape sequences should truncate strings rather than throwing an InvalidDataException.
  • FileLoader - Provider for referenced files with #include or #base directives.
var options = new KVSerializerOptions
{
    HasEscapeSequences = true,
};
options.Conditions.Clear(); // Remove default conditionals set by the library
options.Conditions.Add("X360WIDE");

var stream = File.OpenRead("file.vdf");

var kv = KVSerializer.Create(KVSerializationFormat.KeyValues1Text);
var data = kv.Deserialize(stream, options);

Deserializing binary

Essentially the same as text, just change KeyValues1Text to KeyValues1Binary.

Serializing to text

class DataObject
{
    public string Name { get; set; }

    public string Developer { get; set; }

    [KVProperty("description")]
    public string Summary { get; set; }

    [KVIgnore]
    public string ExtraData { get; set; }
}

var data = new DataObject
{
    Developer = "Valve Software",
    Name = "Dota 2",
    Summary = "Dota 2 is a complex game.",
    ExtraData = "This will not be serialized."
};

using var stream = File.OpenWrite("file.vdf");

var kv = KVSerializer.Create(KVSerializationFormat.KeyValues1Text);
kv.Serialize(stream, data, "root object name");

Serializing to binary

Essentially the same as text, just change KeyValues1Text to KeyValues1Binary.

KeyValues2 (Datamodel)

This library does not currently support KeyValues2 (Datamodel). If you need KV2/Datamodel support, use our fork of Datamodel.NET instead.

KeyValues3

Used by the Source 2 engine.

Deserializing text

var stream = File.OpenRead("file.kv3"); // or any other Stream

var kv = KVSerializer.Create(KVSerializationFormat.KeyValues3Text);
KVDocument data = kv.Deserialize(stream);

Console.WriteLine(data["some key"]);

Serializing to text

using var stream = File.OpenWrite("file.kv3");

var kv = KVSerializer.Create(KVSerializationFormat.KeyValues3Text);
kv.Serialize(stream, data);
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.
  • net10.0

    • No dependencies.

NuGet packages (11)

Showing the top 5 NuGet packages that depend on ValveKeyValue:

Package Downloads
GameFinder.StoreHandlers.Steam

Library for finding games installed with Steam.

HGV.Basilius

Clients for download hero, ability, and items from daily cache provided by DotaBuff

ValveResourceFormat

Parser, decompiler, and exporter for Valve's Source 2 resource file formats. Supports models, textures, materials, maps, particles, and more.

GameLib.NET

GameLib.NET is a library to give .NET developers easy access to the users installed game launchers and installed games.

BD.SteamClient

次元超越 SteamClient 库

GitHub repositories (14)

Showing the top 14 popular GitHub repositories that depend on ValveKeyValue:

Repository Stars
beeradmoore/dlss-swapper
SteamAutoCracks/Steam-auto-crack
Steam Game Automatic Cracker
KSP-CKAN/CKAN
The Comprehensive Kerbal Archive Network
ValveResourceFormat/ValveResourceFormat
Source 2 Viewer is an all-in-one tool to browse VPK archives, view, extract, and decompile Source 2 assets, including maps, models, materials, textures, sounds, and more.
GoldenPotato137/PotatoVN
一款Visual Novel管理软件
terrymacdonald/DisplayMagician
DisplayMagician is an open source tool for automatically configuring your displays and sound for a game or application from a single Windows Shortcut.
overtools/OWLib
DataTool is a program that lets you extract models, maps, and files from Overwatch.
EllyVR/VRCVideoCacher
ruarai/CompilePal
A tool to assist in the compiling of source engine maps
saul/demofile-net
Blazing fast cross-platform demo parser library for Counter-Strike 2 and Valve's Deadlock, written in C#.
hedge-dev/HedgeModManager
Multiplatform rewrite of Hedge Mod Manager
Euterpe-org/Euterpe
Muse Dash Mod Manager
ktxiaok/FireAxe
A Left 4 Dead 2 addon manager that supports hierarchical organization, workshop items and collections download, addon enablement management, etc.
SteamDatabase/SteamAppInfo
Parser for appinfo.vdf and packageinfo.vdf files used by the Steam client
Version Downloads Last Updated
0.50.0.474 0 3/30/2026
0.40.0.471 74 3/29/2026
0.31.0.460 227 3/27/2026
0.30.1.456 113 3/26/2026
0.20.0.417 16,364 8/10/2025
0.13.1.398 32,481 4/5/2025
0.12.0.391 8,226 11/2/2024
0.11.0.378 79,805 7/3/2024
0.10.0.360 206,787 3/22/2024
0.9.0.267 116,047 6/5/2023
0.8.2.162 215,989 8/26/2022
0.8.0.139 4,226 2/9/2022
0.8.0.133 1,261 2/4/2022
0.7.1 1,225 1/13/2022
0.6.0.5 1,551 9/8/2021
0.5.0.4 3,559 9/17/2020
0.4.2 1,870 7/30/2020
0.4.1 1,160 7/29/2020
0.3.1.152 17,700 6/23/2020
0.3.0.149 1,114 6/23/2020
Loading failed