ValveKeyValue 0.40.0.471
See the version list below for details.
dotnet add package ValveKeyValue --version 0.40.0.471
NuGet\Install-Package ValveKeyValue -Version 0.40.0.471
<PackageReference Include="ValveKeyValue" Version="0.40.0.471" />
<PackageVersion Include="ValveKeyValue" Version="0.40.0.471" />
<PackageReference Include="ValveKeyValue" />
paket add ValveKeyValue --version 0.40.0.471
#r "nuget: ValveKeyValue, 0.40.0.471"
#:package ValveKeyValue@0.40.0.471
#addin nuget:?package=ValveKeyValue&version=0.40.0.471
#tool nuget:?package=ValveKeyValue&version=0.40.0.471
<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 Types
The library is built around two types:
KVObject(class) -- a named tree node. Holds aNameand aKVValue. Supports navigation, mutation, and enumeration.KVValue(readonly record struct) -- the data. Stores scalars inline (no boxing), strings, binary blobs, arrays, and collections. Supports implicit/explicit conversions, flags, andwithexpressions.
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 value (typed constructors for common types, no cast needed)
var obj = new KVObject("key", "hello");
var obj = new KVObject("key", 42);
var obj = new KVObject("key", 3.14f);
var obj = new KVObject("key", true);
// Dictionary-backed collection (O(1) lookup, no duplicate keys)
var obj = KVObject.Collection("root"); // empty, can Add children
var obj = KVObject.Collection("root", [ // with children
new KVObject("name", "Dota 2"),
new KVObject("appid", 570),
]);
// List-backed collection (preserves insertion order, allows duplicate keys, for KV1)
var obj = KVObject.ListCollection("root"); // empty
var obj = KVObject.ListCollection("root", [ // with children
new KVObject("key", "first"),
new KVObject("key", "second"), // duplicate keys allowed
]);
// Array from values (implicit conversions from primitives)
var arr = KVObject.Array("items"); // empty, can Add elements
var arr = KVObject.Array("tags", new KVValue[] { "action", "moba" }); // from KVValue[]
// Array from KVObjects (when elements need flags, nested structure, etc.)
var arr = KVObject.Array("data", [
new KVObject(null, (KVValue)"element"),
new KVObject(null, flaggedValue),
]);
// Binary blob
var blob = KVObject.Blob("data", new byte[] { 0x01, 0x02, 0x03 });
new KVObject("name")is equivalent toKVObject.Collection("name")(empty dict-backed collection).
Reading values
KVObject data = kv.Deserialize(stream);
// 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.TryGetChild("optional", out var child)) { ... }
// Null-safe (indexer returns null for missing keys)
KVObject val = data["missing"]; // null
// Access the underlying KVValue directly
KVValueType type = data.ValueType; // forwarded from Value
KVFlag flag = data["texture"].Value.Flag; // flags live on KVValue
ReadOnlySpan<byte> bytes = data["blob"].Value.AsSpan();
Modifying
// Set scalar (implicit conversion)
data["name"] = "new name";
data["count"] = 42;
// Chained writes work (reference semantics)
data["config"]["resolution"] = "1920x1080";
// Add/remove children
data.Add(new KVObject("newprop", 42));
data.Add("shorthand", (KVValue)"value");
data.Remove("deprecated");
// Array mutation
arr.Add((KVValue)"new element");
arr.RemoveAt(2);
// Clear
data.Clear();
// Modify flags via with expression
var child = data.GetChild("texture");
child.Value = child.Value with { Flag = KVFlag.Resource };
Enumerating
// KVObject implements IEnumerable<KVObject>
foreach (var child in data)
{
Console.WriteLine($"{child.Name} = {(string)child}");
}
// LINQ works naturally
var names = data.Children.Select(c => c.Name);
// Scalars yield nothing
foreach (var child in scalarObj) { } // empty
KVValue
A readonly record struct that stores scalar data inline (no boxing):
// Implicit from primitives
KVValue v = "hello";
KVValue v = 42;
KVValue v = 3.14f;
KVValue v = true;
// Explicit to primitives
string s = (string)value;
int n = (int)value;
// Typed accessors
string s = value.AsString();
int n = value.ToInt32(CultureInfo.InvariantCulture);
ReadOnlySpan<byte> data = value.AsSpan();
byte[] blob = value.AsBlob();
// Properties
value.ValueType // KVValueType enum
value.Flag // KVFlag enum
value.IsNull // true if ValueType == Null
// with expressions (readonly record struct)
var flagged = value with { Flag = KVFlag.Resource };
// default is null
default(KVValue).IsNull == true
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);
KVObject 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 anInvalidDataException.FileLoader- Provider for referenced files with#includeor#basedirectives.
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);
KVObject 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 | Versions 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. |
-
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 | 27 | 3/30/2026 |
| 0.40.0.471 | 90 | 3/29/2026 |
| 0.31.0.460 | 231 | 3/27/2026 |
| 0.30.1.456 | 116 | 3/26/2026 |
| 0.20.0.417 | 16,388 | 8/10/2025 |
| 0.13.1.398 | 32,505 | 4/5/2025 |
| 0.12.0.391 | 8,226 | 11/2/2024 |
| 0.11.0.378 | 79,806 | 7/3/2024 |
| 0.10.0.360 | 206,857 | 3/22/2024 |
| 0.9.0.267 | 116,067 | 6/5/2023 |
| 0.8.2.162 | 216,010 | 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,736 | 6/23/2020 |
| 0.3.0.149 | 1,114 | 6/23/2020 |
View release notes at https://github.com/ValveResourceFormat/ValveKeyValue/releases