Sign in

    moonvalve

    Ordered Valve KeyValues tooling, source editing, streaming and Steam metadata in MoonBit

    valve
    keyvalues
    vdf
    steam
    parser
    Download zip
    Version
    0.8.3
    License
    MIT
    Last updated
    1 hour ago
    Downloads
    78

    No dependencies

    #MoonValve

    MoonBit 原生 Valve 数据工具库:KeyValues、VPK、VMT、本地化、DMX 与编辑器服务。

    MoonValve 让 MoonBit 程序可以读取、查询和写出 Valve 配置与游戏资源,同时保留 KV1 键顺序和重复项、二进制数值位与 DMX 的 UUID 图身份。格式实现和命令行使用同一份 MoonBit 核心;Zstandard 使用 Apache-2.0 的 MoonBit 实现 bikallem/compress(所需源码及归属记录见 internal/vendor),不调用 Python、Valve SDK 或外部解析器。Python/.NET 仅用于独立兼容性测试。

    当前版本为 0.8.3,提供库、命令行、本地可视化工作台和跨平台下载包。从 0.4.0 起已发布到 Mooncakes;安装与独立验证说明版本依赖用法。

    新增查询表达式与快照批量修改、跨对象移动复制、批量编辑优化、文本 KV3、多文件引用重构及标准输入输出 LSP。详见 进阶功能与边界,VS Code 扩展 可通过 VSIX 安装。

    #为什么需要它

    Steam 和 Source 生态使用 KeyValues 保存配置和资源信息。这种格式有嵌套对象,也允许重复键;把它直接转换成普通字典容易丢失信息。MoonValve 使用有序条目数组表示对象,方便游戏工具、资源处理程序和桌面应用复用。

    #已实现

    • 二进制 KV3 0—5 读取、4/5 写出及无压缩/LZ4/Zstandard;精确类型查询编辑与 Source 2 DATA/RERL 检查。
    • VPK v1/v2 索引、按需提取、文件 CRC32 校验、v1 创建及显式目录/VPK 搜索路径挂载。
    • VMT Patch 继承与参数来源、纹理引用;资源正反向依赖、基础游戏来源和目录/ZIP/VPK 闭包导出。
    • Valve 本地化 UTF-8/UTF-16、PO/POT 转换更新、翻译上下文和占位符检查。
    • 独立的 DMX UUID 类型图,支持 KeyValues2、binary 4/5、共享/循环/外部引用及同类型数组。
    • KV1 文本解析:嵌套对象、带引号和不带引号的字符串、空值、空对象、// 注释、Unicode 和 UTF-8 BOM。
    • 有序条目模型,重复键不覆盖;支持首项查询、全部同名项查询和逐层路径查询。
    • 规范化写出与结构往返,提供保留重复键的 JSON 双向转换。
    • 按同名键出现次序定位的插入、替换、删除与重命名,以及保留原文注释和排版的局部编辑。
    • 显式平台条件求值与调用方提供加载回调的 #include/#base 解析,含循环检测和全局资源预算。
    • 保留类型与浮点原始位的标准二进制 KV1 编解码。
    • 可选择的转义模式,以及输入长度、字符串长度、总条目数和嵌套深度限制。
    • 包含错误码、行列号和 Unicode 字符偏移的解析诊断。
    • Steam appmanifest_*.acf 和新旧 libraryfolders.vdf 数据模型。
    • JavaScript 与原生命令行;Steam 清单筛选、排序、精确容量汇总、重复及缺失检查与 CSV 导出。
    • 全重复项路径查询、树遍历、严格类型读取与有序编辑事务。
    • 保留条件、引用与字面路径的源编辑,插入沿用相邻缩进、换行和键的引号方式。
    • shortcuts.vdf 增删改、appinfo/packageinfo 多版本索引、二进制外部字符串表。
    • 增量 UTF-8 解析与事件回调,可跳过对象交付而继续验证语法,附百万条目示例。
    • 命令行编辑预览、带备份的原子保存、受选定目录约束的引用展开和结构化错误。
    • 本机可视化工作台,提供文本/二进制树形浏览、编辑预览、撤销和下载副本。
    • 分块文件命令,支持 JSON Lines 原文事件、原始标量路径查询、CSV 和无条件文本的流式规范化;输出处理慢速接收端的背压。
    • 快捷方式专用表单、批量修改预览;缓存按 ID 搜索、分页和记录按需解码。
    • 多文件工程切换、草稿快照、引用关系及展开字段到原文件行列的来源导航。

    完整格式边界见 兼容性说明,库接口见 API 导览,工具用法见 命令行、本地工作台 和 发行包。

    #环境与获取代码

    • 项目要求 MoonBit 0.10.18 或更高版本(满足验收要求的 ≥0.10.16);已验证工具链:moonc v0.10.18+6c83a7f62,配套 moonbitlang/core 同版本。
    • JavaScript CLI 需要 Node.js 22 或更高版本;原生 CLI 构建需要 C 编译器,运行时无需 Node。

    git clone https://github.com/Charles67676767/MoonValve.git cd MoonValve moon version --all moon update moon check moon test moon run examples/demo moon run examples/advanced

    示例输出以 480: Moon Harbor (Moon Harbor) 开头,随后输出规范化的 KV1。演示中的游戏和路径为合成数据;另有固定上游版本的 Proton 实际配置回归。

    #库用法

    在本仓库中的包配置里导入:

    import {
    "Charles67676767/moonvalve" @valve,
    }

    let doc = @valve.parse("root { tag one tag two name \"Moon Harbor\" }")
    let name = doc.lookup(["root", "name"])
    let normalized = @valve.stringify(doc)
    let same = @valve.parse(normalized) == doc

    parse 和 stringify 会抛出结构化错误,需要由调用方处理。可直接运行的完整错误处理示例在 examples/demo。Mooncakes 发布前,也可通过 独立模块示例 的 moon.work 引入源码依赖。

    对象由 Array[Entry] 表示,Value 为 Text(String) 或 Object(Array[Entry])。查询默认区分大小写,遇到重复键时返回第一项;Document::get_all 返回所有顶层同名项。Steam 数据模型单独采用 ASCII 不区分大小写的字段查询。

    #命令行

    以下命令在仓库根目录执行,默认向标准输出写结果;只有显式 --in-place 才保存到文件并创建备份。

    moon run cmd/main --target js -- help moon run cmd/main --target js -- parse fixtures/duplicates.vdf moon run cmd/main --target js -- from-json data.json moon run cmd/main --target js -- format fixtures/duplicates.vdf moon run cmd/main --target js -- query fixtures/appmanifest_480.acf AppState name moon run cmd/main --target js -- app fixtures/appmanifest_480.acf moon run cmd/main --target js -- libraries fixtures/libraryfolders.vdf

    app 的示例结果:

    {"app_id":"480","name":"Moon Harbor","install_dir":"Moon Harbor","size_on_disk":"1048576","build_id":"20261023"}

    游戏 ID、构建 ID 和输出的字节数使用字符串表示,避免 JSON 消费端的浮点精度问题。

    读取本机实际清单时,将命令中的路径换成自己的 libraryfolders.vdf:

    moon run cmd/main --target js -- inventory "/path/to/Steam/steamapps/libraryfolders.vdf" moon run cmd/main --target js -- inventory "/path/to/libraryfolders.vdf" --filter portal --sort size --csv

    inventory 扫描该文件列出的库中的 steamapps/appmanifest_*.acf,返回 games、errors 和筛选结果的 summary。相对库路径以输入文件的目录为基准。它读取清单记录,不计算实际文件夹大小,也不验证游戏下载是否完整。库路径和清单名可能出现在本机输出中。

    除 inventory、文件引用展开及原地保存外,可以把文件名换成 - 从标准输入读取。文本按 UTF-8 严格解码,普通输入上限 16 MiB,缓存命令上限 512 MiB;流式命令默认 64 MiB,可显式设定预算,见 流式文件处理。退出码为 0(成功)、1(inventory 部分失败)或 2(参数、输入或解析错误)。

    也可以先构建,再直接使用 Node.js:

    moon build --target js --release node _build/js/release/build/cmd/main/main.js help

    原生程序:

    moon build --target native --release moon run cmd/main --target native --release -- help

    可直接分发 _build/native/release/build/cmd/main/ 下生成的 main.exe 或 main,以工具链实际产物为准;.exe 后缀也可能出现在 Linux 产物上。两种 CLI 的命令、输入格式与退出码一致。

    #检查与测试

    moon fmt --check moon check --target js moon test --target all --deny-warn moon build --target js --release node scripts/test-cli.cjs moon build --target native --release node scripts/test-cli.cjs --native python -m pip install vdf==3.4 python scripts/check-reference.py node scripts/benchmark.cjs --native moon info

    核心测试覆盖文本与二进制、编辑事务、格式保留、条件、引用、流解析、Steam 快捷方式、缓存及资源边界。CLI 使用临时目录验收;Python vdf 与 .NET ValveKeyValue 是独立测试参考,不参与产品运行。另有带失败样本缩减的确定性模糊测试。持续集成执行四后端验证、Windows/Linux 命令行、编辑器核心、独立参考和发行包校验。复现细节见 验证说明。

    #目录

    model.mbt 有序数据模型与查询 parser.mbt KV1 文本解析及诊断 writer.mbt 规范化文本写出 steam.mbt Steam 清单模型 inventory.mbt 筛选、排序、统计、检查与 CSV edit.mbt 重复键感知的文档编辑 source_edit.mbt 保留原文的局部编辑 json_codec.mbt 有序 JSON 导入 conditions.mbt 平台条件表达式 resolve.mbt 文件引用解析 project.mbt 引用关系与原文来源 stream_writer.mbt 有界事件写出 binary.mbt 标准二进制 KV1 cmd/main/ JS/C 宿主适配与 MoonBit CLI examples/demo/ 跨后端最小使用示例 examples/advanced/ 编辑、条件、引用与二进制示例 fixtures/ 合成示例与注明来源许可的实际配置 scripts/test-cli.cjs CLI 端到端测试 docs/ 兼容性、设计与路线图

    #后续方向

    0.8.x 保留 0.4—0.7 系列公开签名,遵循兼容约定,并通过接口基线、独立格式参考和注册表消费者验证。DMX 其他二进制版本、VBKV 和未知版本的 Steam 缓存仍需独立扩展。详见路线图。

    #许可证与参考

    采用 MIT 许可证。格式兼容性参考 ValvePython/vdf 和 ValveKeyValue,来源及分发边界见 NOTICE.md。

    MoonValve 是独立项目,与 Valve 或 Steam 没有隶属关系。

    #0.5 新增的工程编辑能力

    • KV3 原文局部编辑:替换值、重命名字段、增删对象字段与数组元素,保留未修改区域的注释、头部、换行和数字写法。
    • 工程字段查询与批量修改:按文件选择,查看全部匹配,统一预览并生成新快照;任一步失败都不返回部分工程。
    • VS Code 文件引用维护:文件及目录重命名更新 #base / #include,跨目录移动重算向外引用;诊断显示文件系统确认的缺失目标及循环引用链。

    可运行示例:moon run examples/advanced --target native。命令行及工作台用法见进阶功能。

    #0.6 工程导出与 KV3 类型工作流

    工作台支持按原目录结构下载工程 ZIP;CLI 可将快照导出到全新目录或 ZIP。KV3 支持类型/标记感知查询、精确整数比较、保留原文的批量编辑、树形字段控件,以及 VS Code 大纲、折叠与类型悬浮。完整命令、库接口和资源限制见工程导出与 KV3 工作流。

    moon run cmd/main --target native -- workspace-export fixtures/workspace-fields.json new-project moon run cmd/main --target native -- workspace-zip fixtures/workspace-fields.json project.zip moon run cmd/main --target native -- kv3-select fixtures/sample.kv3 '/**?type=integer&>9007199254740993'

    #0.7 混合工程与资源维护

    KV1 与文本 KV3 可在同一工程内分别查询、批量修改并导出;新增保留注释、条件、引用与数字写法的格式化。VS Code 可按显式资源目录跳转、检查缺失文件,并在移动资源时更新已载入 KV3 的引用。配置示例和限制见工程与资源工作流。

    #0.8 真实资源工作流

    六类资源能力提供 MoonBit API、JavaScript/原生命令行和本地工作台入口。运行 moon run examples/assets --target js 查看可复现的读取、编辑、依赖闭包与格式转换。格式版本、资源预算、v2 页脚校验边界和完整命令见资源工具使用指南。

    AccessError

    pub suberror AccessError {
    InvalidAccess(Array[Selector], String)
    } derive(
    Debug
    )

    BinaryError

    pub suberror BinaryError {
    InvalidBinary(Int, String)
    } derive(
    Debug
    )

    ConditionError

    pub suberror ConditionError {
    InvalidCondition(String)
    } derive(
    Debug
    )

    EditError

    pub suberror EditError {
    InvalidEdit(String)
    } derive(
    Debug
    )

    JsonImportError

    pub suberror JsonImportError {
    InvalidJsonDocument(String)
    } derive(
    Debug
    )

    ParseError

    pub suberror ParseError {
    ParseError(Diagnostic)
    } derive(
    Debug
    )

    QueryError

    pub suberror QueryError {
    InvalidQuery(String)
    } derive(
    Debug
    )

    ResolveError

    pub suberror ResolveError {
    InvalidReference(String)
    } derive(
    Debug
    )

    SteamError

    pub suberror SteamError {
    InvalidManifest(String)
    } derive(
    Debug
    )

    WriteError

    pub suberror WriteError {
    InvalidDocument(String)
    } derive(
    Debug
    )

    AssetDependency

    pub(all) struct AssetDependency {
    source : String
    reference : String
    target : String?
    kind : String
    property : Array[String]
    status : String
    } derive(Eq,
    Debug
    )

    AssetDependency::equal

    AssetDependency::not_equal

    fn AssetDependency::not_equal(x : AssetDependency, y : AssetDependency) -> Bool

    BinaryEntry

    pub(all) struct BinaryEntry {
    key : String
    value : BinaryValue
    } derive(Eq,
    Debug
    )

    BinaryEntry::equal

    fn BinaryEntry::equal(BinaryEntry, BinaryEntry) -> Bool

    BinaryEntry::not_equal

    fn BinaryEntry::not_equal(x : BinaryEntry, y : BinaryEntry) -> Bool

    BinaryOptions

    pub(all) struct BinaryOptions {
    max_depth : Int
    max_entries : Int
    max_bytes : Int
    max_string_bytes : Int
    } derive(Eq,
    Debug
    )

    BinaryOptions::default

    fn BinaryOptions::default() -> BinaryOptions

    BinaryOptions::equal

    BinaryOptions::not_equal

    fn BinaryOptions::not_equal(x : BinaryOptions, y : BinaryOptions) -> Bool

    BinaryValue

    pub(all) enum BinaryValue {
    ObjectValue(Array[BinaryEntry])
    StringValue(String)
    Int32Value(Int)
    Float32Bits(UInt)
    Pointer32(UInt)
    WideString(String)
    Color32(UInt)
    UInt64Value(UInt64)
    Int64Value(Int64)
    } derive(Eq,
    Debug
    )

    Typed standard binary KV1. Floating-point payloads retain their exact bits, including NaN payloads and negative zero. Pointer values are data, never dereferenced.

    BinaryValue::equal

    fn BinaryValue::equal(BinaryValue, BinaryValue) -> Bool

    BinaryValue::not_equal

    fn BinaryValue::not_equal(x : BinaryValue, y : BinaryValue) -> Bool

    CacheFormat

    pub(all) enum CacheFormat {
    AppInfo
    PackageInfo
    } derive(Eq,
    Debug
    )

    CacheFormat::equal

    fn CacheFormat::equal(CacheFormat, CacheFormat) -> Bool

    CacheFormat::not_equal

    fn CacheFormat::not_equal(x : CacheFormat, y : CacheFormat) -> Bool

    CachePage

    pub(all) struct CachePage {
    records : Array[CacheRecord]
    total : Int
    offset : Int
    }

    CacheRecord

    pub(all) struct CacheRecord {
    id : UInt
    change_number : UInt
    token : UInt64
    sha1 : Bytes
    binary_sha1 : Bytes?
    info_state : UInt?
    last_updated : UInt?
    offset : Int
    length : Int
    } derive(Eq,
    Debug
    )

    CacheRecord::equal

    fn CacheRecord::equal(CacheRecord, CacheRecord) -> Bool

    CacheRecord::not_equal

    fn CacheRecord::not_equal(x : CacheRecord, y : CacheRecord) -> Bool

    Change

    pub(all) struct Change {
    path : Array[Selector]
    operation : Edit
    } derive(
    Debug
    )

    Change::to_repr

    DMXAttribute

    pub(all) struct DMXAttribute {
    name : String
    value : DMXValue
    } derive(Eq,
    Debug
    )

    DMXAttribute::equal

    DMXAttribute::not_equal

    fn DMXAttribute::not_equal(x : DMXAttribute, y : DMXAttribute) -> Bool

    DMXDocument

    pub(all) struct DMXDocument {
    format_name : String
    format_version : Int
    root : String
    elements : Array[DMXElement]
    } derive(Eq,
    Debug
    )

    DMXDocument::element

    fn DMXDocument::element(self : DMXDocument, id : String) -> DMXElement?

    DMXDocument::equal

    fn DMXDocument::equal(DMXDocument, DMXDocument) -> Bool

    DMXDocument::external_references

    fn DMXDocument::external_references(self : DMXDocument) -> Array[String] raise

    DMXDocument::not_equal

    fn DMXDocument::not_equal(x : DMXDocument, y : DMXDocument) -> Bool

    DMXDocument::with_attribute

    fn DMXDocument::with_attribute(self : DMXDocument, id : String, name : String, value : DMXValue) -> DMXDocument raise

    DMXElement

    pub(all) struct DMXElement {
    id : String
    name : String
    kind : String
    attributes : Array[DMXAttribute]
    } derive(Eq,
    Debug
    )

    DMXElement::equal

    fn DMXElement::equal(DMXElement, DMXElement) -> Bool

    DMXElement::not_equal

    fn DMXElement::not_equal(x : DMXElement, y : DMXElement) -> Bool

    DMXValue

    pub(all) enum DMXValue {
    DElement(String?)
    DInt(Int)
    DFloatBits(UInt)
    DBool(Bool)
    DString(String)
    DBinary(Bytes)
    DTime(Int)
    DColor(UInt)
    DVector(Int, Array[UInt])
    DArray(Int, Array[DMXValue])
    } derive(Eq,
    Debug
    )

    DMX is a UUID-addressed graph, independently typed from KV1 and KV3. Time uses 1/10000-second ticks; floating point components retain IEEE bits.

    DMXValue::equal

    fn DMXValue::equal(DMXValue, DMXValue) -> Bool

    DMXValue::not_equal

    fn DMXValue::not_equal(x : DMXValue, y : DMXValue) -> Bool

    DMXValue::to_repr

    DependencyGraph

    type DependencyGraph

    DependencyGraph::dependents

    fn DependencyGraph::dependents(self : DependencyGraph, target : String, transitive? : Bool) -> Array[String]

    DependencyGraph::edges

    DependencyGraph::export_files

    fn DependencyGraph::export_files(self : DependencyGraph, include_base? : Bool, strict? : Bool) -> Map[String, Bytes] raise

    DependencyGraph::export_vpk

    fn DependencyGraph::export_vpk(self : DependencyGraph, include_base? : Bool, strict? : Bool, options? : BinaryOptions) -> Bytes raise

    DependencyGraph::export_zip

    fn DependencyGraph::export_zip(self : DependencyGraph, include_base? : Bool, strict? : Bool) -> Bytes raise

    DependencyGraph::files

    DependencyGraph::to_json

    fn DependencyGraph::to_json(self : DependencyGraph) -> Json

    Diagnostic

    pub(all) struct Diagnostic {
    code : String
    message : String
    offset : Int
    line : Int
    column : Int
    } derive(Eq,
    Debug
    )

    Offset is a zero-based Unicode scalar index; line and column are one-based.

    Diagnostic::equal

    fn Diagnostic::equal(Diagnostic, Diagnostic) -> Bool

    Diagnostic::not_equal

    fn Diagnostic::not_equal(x : Diagnostic, y : Diagnostic) -> Bool

    Document

    pub(all) struct Document {
    entries : Array[Entry]
    } derive(Eq,
    Debug
    )

    A document can contain zero, one, or several top-level entries.

    Document::apply

    fn Document::apply(self : Document, changes : Array[Change], options? : ParseOptions) -> Document raise

    Sequential paths address the result of the preceding change. A failed batch never modifies the original document. Final output must satisfy text limits.

    Document::apply_snapshot

    fn Document::apply_snapshot(self : Document, changes : Array[Change]) -> Document raise

    Document::edit

    fn Document::edit(self : Document, path : Array[Selector], operation : Edit) -> Document raise EditError

    Return a changed document without modifying the input arrays. An empty path selects the root object and supports Insert or Replace(Object(...)).

    Document::equal

    fn Document::equal(Document, Document) -> Bool

    Document::find

    fn Document::find(self : Document, key : String) -> Array[LocatedValue] raise

    Document::get

    fn Document::get(self : Document, key : String) -> Value?

    Look up the first exact, case-sensitive key match.

    Document::get_all

    fn Document::get_all(self : Document, key : String) -> Array[Value]

    Look up every exact key match in source order.

    Document::lookup

    fn Document::lookup(self : Document, path : Array[String]) -> Value?

    Walk object keys. At each level, the first duplicate wins. An empty path addresses the document's top-level object.

    Document::lookup_all

    fn Document::lookup_all(self : Document, path : Array[String]) -> Array[Value] raise AccessError

    Follow every matching duplicate at every level, retaining document order.

    Document::lookup_at

    fn Document::lookup_at(self : Document, path : Array[Selector]) -> Value raise AccessError

    Exact, duplicate-aware lookup. Errors retain the complete requested path.

    Document::not_equal

    fn Document::not_equal(x : Document, y : Document) -> Bool

    Document::query_plan

    fn Document::query_plan(self : Document, expression : String, operation : QueryEdit) -> Array[Change] raise

    Plans address one original snapshot. Use apply_snapshot, not sequential apply.

    Document::read_bool

    fn Document::read_bool(self : Document, path : Array[Selector]) -> Bool raise AccessError

    Document::read_double

    fn Document::read_double(self : Document, path : Array[Selector]) -> Double raise AccessError

    Document::read_int64

    fn Document::read_int64(self : Document, path : Array[Selector]) -> Int64 raise AccessError

    Document::read_text

    fn Document::read_text(self : Document, path : Array[Selector]) -> String raise AccessError

    Document::select

    fn Document::select(self : Document, expression : String) -> Array[LocatedValue] raise

    Document::to_json

    fn Document::to_json(self : Document) -> Json

    Lossless JSON representation: ordered arrays of {key,value} entries. An ordinary JSON object would silently lose duplicate keys.

    Document::to_repr

    Document::transfer

    fn Document::transfer(self : Document, from : Array[Selector], to : Array[Selector], index : Int, copy? : Bool) -> Document raise

    Index is a boundary in the original destination object, before removal. Moving into oneself/descendants is rejected. Copying produces a finite snapshot.

    Document::walk

    fn Document::walk(self : Document, visitor : (Array[Selector], Value) -> Bool raise) -> Unit raise

    Preorder visitor; returning false skips this object's descendants. Paths are independent snapshots. The root itself is not emitted. Exceptions propagate.

    Edit

    pub(all) enum Edit {
    Replace(Value)
    Remove
    Rename(String)
    Insert(Int, Entry)
    } derive(
    Debug
    )

    Edit::to_repr

    Entry

    pub(all) struct Entry {
    key : String
    value : Value
    } derive(Eq,
    Debug
    )

    One key-value pair, in source order.

    Entry::equal

    fn Entry::equal(Entry, Entry) -> Bool

    Entry::not_equal

    fn Entry::not_equal(x : Entry, y : Entry) -> Bool

    Entry::to_repr

    GameFileSystem

    type GameFileSystem

    GameFileSystem::locate

    fn GameFileSystem::locate(self : GameFileSystem, path : String) -> Array[MountCandidate] raise

    GameFileSystem::read

    fn GameFileSystem::read(self : GameFileSystem, path : String) -> MountedFile raise

    GameMount

    pub(all) enum GameMount {
    LooseMount(String, Bool, (String) -> Bool raise, (String) -> Bytes raise)
    VPKMount(String, Bool, VPKArchive, (Int, Int, Int) -> Bytes raise)
    }

    GameSearchPath

    pub(all) struct GameSearchPath {
    ids : Array[String]
    directory : String
    wildcard : Bool
    } derive(Eq,
    Debug
    )

    GameSearchPath::equal

    GameSearchPath::not_equal

    fn GameSearchPath::not_equal(x : GameSearchPath, y : GameSearchPath) -> Bool

    InventoryIssue

    pub(all) struct InventoryIssue {
    code : String
    library : String
    manifest : String?
    message : String
    } derive(Eq,
    Debug
    )

    InventoryIssue::equal

    InventoryIssue::not_equal

    fn InventoryIssue::not_equal(x : InventoryIssue, y : InventoryIssue) -> Bool

    InventoryRecord

    pub(all) struct InventoryRecord {
    library : String
    manifest : String
    app : SteamApp
    } derive(Eq,
    Debug
    )

    InventoryRecord::equal

    InventoryRecord::not_equal

    fn InventoryRecord::not_equal(x : InventoryRecord, y : InventoryRecord) -> Bool

    InventoryTotal

    pub(all) struct InventoryTotal {
    known_size_bytes : Int64
    unknown_size_count : Int
    } derive(Eq,
    Debug
    )

    InventoryTotal::equal

    InventoryTotal::not_equal

    fn InventoryTotal::not_equal(x : InventoryTotal, y : InventoryTotal) -> Bool

    KV3BinaryDocument

    pub(all) struct KV3BinaryDocument {
    version : Int
    compression : Int
    format_id : String
    root : KV3BinaryValue
    } derive(Eq,
    Debug
    )

    KV3BinaryDocument::document

    fn KV3BinaryDocument::document(self : KV3BinaryDocument) -> KV3Document raise

    KV3BinaryDocument::edit_query

    fn KV3BinaryDocument::edit_query(self : KV3BinaryDocument, expression : String, operation : KV3QueryEdit) -> KV3BinaryDocument raise

    Snapshot query edits retain untouched storage widths and exact IEEE bits. Replacements use the ordinary KV3 value model; ambiguous overlaps fail.

    KV3BinaryDocument::equal

    KV3BinaryDocument::not_equal

    fn KV3BinaryDocument::not_equal(x : KV3BinaryDocument, y : KV3BinaryDocument) -> Bool

    KV3BinaryDocument::select

    fn KV3BinaryDocument::select(self : KV3BinaryDocument, expression : String) -> Array[KV3BinaryLocatedValue] raise

    KV3BinaryLocatedValue

    pub(all) struct KV3BinaryLocatedValue {
    path : Array[String]
    value : KV3BinaryValue
    } derive(Eq,
    Debug
    )

    KV3BinaryLocatedValue::equal

    KV3BinaryLocatedValue::not_equal

    KV3BinaryValue

    pub(all) enum KV3BinaryValue {
    BNull
    BBool(Bool)
    BNumber(Int, UInt64)
    BString(String)
    BBlob(Bytes)
    BArray(Array[KV3BinaryValue])
    BObject(Array[(String, KV3BinaryValue)])
    BFlag(String, KV3BinaryValue)
    } derive(Eq,
    Debug
    )

    Binary KV3 numbers retain their storage type and exact integer/IEEE bits. Tag numbers follow Valve KV3: int64=3, uint64=4, double=5, int32=11, uint32=12, float=19, int16=20, uint16=21, int8=22, uint8=23.

    KV3BinaryValue::equal

    KV3BinaryValue::not_equal

    fn KV3BinaryValue::not_equal(x : KV3BinaryValue, y : KV3BinaryValue) -> Bool

    KV3Document

    pub(all) struct KV3Document {
    header : KV3Header?
    root : KV3Value
    } derive(Eq,
    Debug
    )

    KV3Document::equal

    fn KV3Document::equal(KV3Document, KV3Document) -> Bool

    KV3Document::not_equal

    fn KV3Document::not_equal(x : KV3Document, y : KV3Document) -> Bool

    KV3Document::select

    fn KV3Document::select(self : KV3Document, expression : String) -> Array[KV3LocatedValue] raise

    KV3Edit

    pub(all) enum KV3Edit {
    KV3Replace(KV3Value)
    KV3Remove
    KV3Rename(String)
    KV3InsertField(Int, String, KV3Value)
    KV3InsertElement(Int, KV3Value)
    } derive(
    Debug
    )

    KV3Edit::to_repr

    KV3Entry

    pub(all) struct KV3Entry {
    key : String
    value : KV3Value
    } derive(Eq,
    Debug
    )

    KV3Entry::equal

    fn KV3Entry::equal(KV3Entry, KV3Entry) -> Bool

    KV3Entry::not_equal

    fn KV3Entry::not_equal(x : KV3Entry, y : KV3Entry) -> Bool

    KV3Entry::to_repr

    KV3Header

    pub(all) struct KV3Header {
    format_name : String
    format_id : String
    } derive(Eq,
    Debug
    )

    KV3Header::equal

    fn KV3Header::equal(KV3Header, KV3Header) -> Bool

    KV3Header::not_equal

    fn KV3Header::not_equal(x : KV3Header, y : KV3Header) -> Bool

    KV3LocatedValue

    pub(all) struct KV3LocatedValue {
    path : Array[String]
    value : KV3Value
    } derive(Eq,
    Debug
    )

    KV3LocatedValue::equal

    KV3LocatedValue::not_equal

    fn KV3LocatedValue::not_equal(x : KV3LocatedValue, y : KV3LocatedValue) -> Bool

    KV3Query

    type KV3Query

    KV3Query::select

    fn KV3Query::select(self : KV3Query, document : KV3Document) -> Array[KV3LocatedValue] raise

    KV3QueryEdit

    pub(all) enum KV3QueryEdit {
    KV3SetValue(KV3Value)
    KV3ReplacePrefix(String, String)
    KV3RenameMatches(String)
    KV3RemoveMatches
    } derive(
    Debug
    )

    KV3SourceDocument

    type KV3SourceDocument

    KV3SourceDocument::apply_json

    fn KV3SourceDocument::apply_json(self : KV3SourceDocument, plan : Json) -> KV3SourceDocument raise

    A bounded sequential transaction. No result is returned on any invalid step.

    KV3SourceDocument::document

    KV3SourceDocument::edit

    fn KV3SourceDocument::edit(self : KV3SourceDocument, path : Array[String], operation : KV3Edit) -> KV3SourceDocument raise

    Path components are object keys or canonical decimal array indices. Flags are transparent to traversal; replacing a flagged value replaces its flag too.

    KV3SourceDocument::edit_query

    fn KV3SourceDocument::edit_query(self : KV3SourceDocument, expression : String, operation : KV3QueryEdit) -> KV3SourceDocument raise

    All matched paths address the original source. Ancestor overlaps and rename collisions fail the whole edit; unaffected tokens and trivia remain unchanged.

    KV3SourceDocument::format_preserving

    fn KV3SourceDocument::format_preserving(self : KV3SourceDocument) -> KV3SourceDocument raise

    KV3SourceDocument::range

    fn KV3SourceDocument::range(self : KV3SourceDocument, path : Array[String]) -> KV3SourceRange raise

    KV3SourceDocument::resources

    Only resource:"path" is a file reference. resource_name, soundevent and localization/entity names are deliberately not guessed to be filesystem paths.

    KV3SourceDocument::rewrite_resources

    fn KV3SourceDocument::rewrite_resources(self : KV3SourceDocument, roots : Array[ResourceRoot], moves : Map[String, String]) -> KV3SourceDocument raise

    Return a source-preserving reference preview for file or directory moves. This does not move asset bytes. Only original targets are matched, once.

    KV3SourceDocument::text

    fn KV3SourceDocument::text(self : KV3SourceDocument) -> String

    KV3SourceRange

    pub(all) struct KV3SourceRange {
    start : Int
    end : Int
    selection_start : Int
    selection_end : Int
    } derive(Eq,
    Debug
    )

    Zero-based Unicode scalar offsets, suitable for UTF-16 conversion by hosts.

    KV3SourceRange::equal

    KV3SourceRange::not_equal

    fn KV3SourceRange::not_equal(x : KV3SourceRange, y : KV3SourceRange) -> Bool

    KV3Value

    pub(all) enum KV3Value {
    KV3Null
    KV3Bool(Bool)
    KV3Integer(String)
    KV3Float(String)
    KV3String(String)
    KV3Blob(Bytes)
    KV3Array(Array[KV3Value])
    KV3Object(Array[KV3Entry])
    KV3Flag(String, KV3Value)
    } derive(Eq,
    Debug
    )

    KV3Value::equal

    fn KV3Value::equal(KV3Value, KV3Value) -> Bool

    KV3Value::not_equal

    fn KV3Value::not_equal(x : KV3Value, y : KV3Value) -> Bool

    KV3Value::to_repr

    Localization

    pub(all) struct Localization {
    language : String
    tokens : Array[LocalizationToken]
    encoding : String
    } derive(Eq,
    Debug
    )

    Localization::equal

    Localization::import_po

    fn Localization::import_po(self : Localization, catalog : POCatalog, language : String, syntax? : String, allow_fuzzy? : Bool) -> LocalizationImport raise

    Import reviewed translations. Empty, fuzzy, stale, plural or unsafe entries produce issues and retain source text; unknown contexts are also reported.

    Localization::not_equal

    fn Localization::not_equal(x : Localization, y : Localization) -> Bool

    Localization::to_json

    fn Localization::to_json(self : Localization) -> Json raise

    Localization::to_po

    fn Localization::to_po(self : Localization, translated? : Localization) -> POCatalog raise

    Valve token names are PO contexts. Equal source strings remain distinct messages, and translators may reorder entries without changing token identity.

    Localization::validate_translation

    fn Localization::validate_translation(self : Localization, translated : Localization, syntax? : String) -> Array[LocalizationIssue] raise

    Localization::write

    fn Localization::write(self : Localization, encoding? : String) -> Bytes raise

    LocalizationImport

    pub(all) struct LocalizationImport {
    document : Localization
    issues : Array[LocalizationIssue]
    } derive(Eq,
    Debug
    )

    LocalizationImport::equal

    LocalizationImport::not_equal

    LocalizationIssue

    pub(all) struct LocalizationIssue {
    token : String
    code : String
    message : String
    } derive(Eq,
    Debug
    )

    LocalizationIssue::equal

    LocalizationIssue::not_equal

    fn LocalizationIssue::not_equal(x : LocalizationIssue, y : LocalizationIssue) -> Bool

    LocalizationToken

    pub(all) struct LocalizationToken {
    name : String
    text : String
    } derive(Eq,
    Debug
    )

    LocalizationToken::equal

    LocalizationToken::not_equal

    fn LocalizationToken::not_equal(x : LocalizationToken, y : LocalizationToken) -> Bool

    LocatedValue

    pub(all) struct LocatedValue {
    path : Array[Selector]
    value : Value
    } derive(Eq,
    Debug
    )

    LocatedValue::equal

    LocatedValue::not_equal

    fn LocatedValue::not_equal(x : LocatedValue, y : LocatedValue) -> Bool

    LspFramer

    type LspFramer

    LspFramer::feed

    fn LspFramer::feed(self : LspFramer, chunk : Bytes) -> Array[LspPacket] raise

    LspFramer::finish

    fn LspFramer::finish(self : LspFramer) -> Unit raise

    LspPacket

    pub(all) enum LspPacket {
    LspRequest(Json)
    LspInvalidJson
    }

    LspServer

    type LspServer

    Transport-independent LSP 3.17 engine. Files enter only through client messages.

    LspServer::exit_code

    fn LspServer::exit_code(self : LspServer) -> Int

    LspServer::handle

    fn LspServer::handle(self : LspServer, request : Json) -> Array[Json]

    LspServer::should_exit

    fn LspServer::should_exit(self : LspServer) -> Bool

    MountCandidate

    pub(all) struct MountCandidate {
    mount : String
    base_game : Bool
    selected : Bool
    } derive(Eq,
    Debug
    )

    MountCandidate::equal

    MountCandidate::not_equal

    fn MountCandidate::not_equal(x : MountCandidate, y : MountCandidate) -> Bool

    MountedFile

    pub(all) struct MountedFile {
    path : String
    mount : String
    base_game : Bool
    bytes : Bytes
    } derive(Eq,
    Debug
    )

    MountedFile::equal

    fn MountedFile::equal(MountedFile, MountedFile) -> Bool

    MountedFile::not_equal

    fn MountedFile::not_equal(x : MountedFile, y : MountedFile) -> Bool

    POCatalog

    pub(all) struct POCatalog {
    entries : Array[POEntry]
    trailing_comments : Array[String]
    } derive(Eq,
    Debug
    )

    POCatalog::equal

    fn POCatalog::equal(POCatalog, POCatalog) -> Bool

    POCatalog::not_equal

    fn POCatalog::not_equal(x : POCatalog, y : POCatalog) -> Bool

    POCatalog::stringify

    fn POCatalog::stringify(self : POCatalog) -> String raise

    POEntry

    pub(all) struct POEntry {
    context : String?
    id : String
    plural : String?
    translations : Array[String]
    comments : Array[String]
    flags : Array[String]
    obsolete : Bool
    } derive(Eq,
    Debug
    )

    POEntry::equal

    fn POEntry::equal(POEntry, POEntry) -> Bool

    POEntry::not_equal

    fn POEntry::not_equal(x : POEntry, y : POEntry) -> Bool

    POEntry::to_repr

    ParseOptions

    pub(all) struct ParseOptions {
    escape_sequences : Bool
    max_depth : Int
    max_entries : Int
    max_input_chars : Int
    max_token_chars : Int
    conditions : Array[String]?
    } derive(Eq,
    Debug
    )

    Parsing limits apply to the whole document; depth counts nested objects.

    ParseOptions::default

    fn ParseOptions::default() -> ParseOptions

    Escapes are enabled for canonical output and Steam's escaped Windows paths.

    ParseOptions::equal

    ParseOptions::not_equal

    fn ParseOptions::not_equal(x : ParseOptions, y : ParseOptions) -> Bool

    Query

    type Query

    Compiled, duplicate-aware path expression; not a JSONPath implementation.

    Query::select

    fn Query::select(self : Query, document : Document, max_matches? : Int, max_visited? : Int) -> Array[LocatedValue] raise

    QueryEdit

    pub(all) enum QueryEdit {
    SetText(String)
    ReplacePrefix(String, String)
    RenameKey(String)
    RemoveMatches
    } derive(
    Debug
    )

    ReferenceEdge

    pub(all) struct ReferenceEdge {
    source : String
    target : String
    kind : String
    location : SourceLocation
    } derive(Eq,
    Debug
    )

    ReferenceEdge::equal

    ReferenceEdge::not_equal

    fn ReferenceEdge::not_equal(x : ReferenceEdge, y : ReferenceEdge) -> Bool

    ResolvedOrigin

    pub(all) struct ResolvedOrigin {
    path : Array[Selector]
    location : SourceLocation
    } derive(Eq,
    Debug
    )

    ResolvedOrigin::equal

    ResolvedOrigin::not_equal

    fn ResolvedOrigin::not_equal(x : ResolvedOrigin, y : ResolvedOrigin) -> Bool

    ResolvedProject

    pub(all) struct ResolvedProject {
    document : Document
    origins : Array[ResolvedOrigin]
    references : Array[ReferenceEdge]
    } derive(Eq,
    Debug
    )

    ResolvedProject::equal

    ResolvedProject::not_equal

    fn ResolvedProject::not_equal(x : ResolvedProject, y : ResolvedProject) -> Bool

    ResolvedProject::to_json

    fn ResolvedProject::to_json(self : ResolvedProject) -> Json

    ResourceBlock

    pub(all) struct ResourceBlock {
    kind : String
    offset : Int
    bytes : Bytes
    } derive(Eq,
    Debug
    )

    ResourceBlock::equal

    ResourceBlock::not_equal

    fn ResourceBlock::not_equal(x : ResourceBlock, y : ResourceBlock) -> Bool

    ResourceContainer

    pub(all) struct ResourceContainer {
    version : Int
    declared_size : Int
    blocks : Array[ResourceBlock]
    trailing : Bytes
    } derive(Eq,
    Debug
    )

    ResourceContainer::data

    ResourceContainer::equal

    ResourceContainer::external_references

    fn ResourceContainer::external_references(self : ResourceContainer, options? : BinaryOptions) -> Array[ResourceExternalReference] raise

    ResourceContainer::not_equal

    fn ResourceContainer::not_equal(x : ResourceContainer, y : ResourceContainer) -> Bool

    ResourceExternalReference

    pub(all) struct ResourceExternalReference {
    id : UInt64
    name : String
    } derive(Eq,
    Debug
    )

    ResourceExternalReference::equal

    ResourceExternalReference::not_equal

    ResourceReference

    pub(all) struct ResourceReference {
    path : Array[String]
    resource : String
    target : String?
    status : String
    start : Int
    end : Int
    } derive(Eq,
    Debug
    )

    ResourceReference::equal

    ResourceReference::not_equal

    fn ResourceReference::not_equal(x : ResourceReference, y : ResourceReference) -> Bool

    ResourceRoot

    pub(all) struct ResourceRoot {
    prefix : String
    directory : String
    } derive(Eq,
    Debug
    )

    Map a resource path prefix to an explicit directory, never an inferred game root.

    ResourceRoot::equal

    ResourceRoot::not_equal

    fn ResourceRoot::not_equal(x : ResourceRoot, y : ResourceRoot) -> Bool

    Selector

    pub(all) struct Selector {
    key : String
    occurrence : Int
    } derive(Eq,
    Debug
    )

    Select the zero-based occurrence of a key, preserving duplicate siblings.

    Selector::equal

    fn Selector::equal(Selector, Selector) -> Bool

    Selector::not_equal

    fn Selector::not_equal(x : Selector, y : Selector) -> Bool

    Selector::to_repr

    ShortcutFile

    type ShortcutFile

    ShortcutFile::add

    fn ShortcutFile::add(self : ShortcutFile, name : String, exe : String, start_dir? : String, launch_options? : String, tags? : Array[String]) -> ShortcutFile raise SteamError

    ShortcutFile::remove

    fn ShortcutFile::remove(self : ShortcutFile, index : String) -> ShortcutFile raise SteamError

    ShortcutFile::set

    fn ShortcutFile::set(self : ShortcutFile, shortcut : SteamShortcut) -> ShortcutFile raise SteamError

    Replace modeled fields while retaining unknown fields and all other entries. The supplied app_id is kept exactly; callers can deliberately preserve identity.

    ShortcutFile::shortcuts

    fn ShortcutFile::shortcuts(self : ShortcutFile) -> Array[SteamShortcut] raise SteamError

    ShortcutFile::to_binary

    fn ShortcutFile::to_binary(self : ShortcutFile) -> Array[BinaryEntry]

    SourceDocument

    type SourceDocument

    A parsed source with scalar-index spans. Edit returns a new, reparsed source; all characters outside the selected replacement range remain unchanged.

    SourceDocument::apply

    fn SourceDocument::apply(self : SourceDocument, changes : Array[Change]) -> SourceDocument raise

    Apply a batch to independent source snapshots; nothing is published on failure.

    SourceDocument::apply_snapshot

    fn SourceDocument::apply_snapshot(self : SourceDocument, changes : Array[Change]) -> SourceDocument raise

    All targets address the same original source; compile patches then parse once.

    SourceDocument::document

    fn SourceDocument::document(self : SourceDocument) -> Document

    SourceDocument::edit

    fn SourceDocument::edit(self : SourceDocument, path : Array[Selector], operation : Edit) -> SourceDocument raise

    Supports the same occurrence-aware edits as Document::edit. Comments outside replaced values remain intact; removing an entry leaves surrounding comments. Newly inserted or replaced structures use canonical escaped KV1 formatting.

    SourceDocument::edit_query

    fn SourceDocument::edit_query(self : SourceDocument, expression : String, operation : QueryEdit) -> SourceDocument raise

    SourceDocument::evaluate

    fn SourceDocument::evaluate(self : SourceDocument, symbols : Array[String]) -> Document raise ParseError

    Evaluate a source without changing its raw view. Root file directives still require load_resolved with an explicitly supplied loader.

    SourceDocument::format_preserving

    fn SourceDocument::format_preserving(self : SourceDocument) -> SourceDocument raise

    Reflow whitespace only. Keys, values, comments, directives and all conditions retain their exact token text. String contents are never indented or rewritten.

    SourceDocument::locations

    fn SourceDocument::locations(self : SourceDocument, source : String) -> Array[ResolvedOrigin]

    Raw source locations include branches and directives without evaluation.

    SourceDocument::text

    fn SourceDocument::text(self : SourceDocument) -> String

    SourceDocument::transfer

    fn SourceDocument::transfer(self : SourceDocument, from : Array[Selector], to : Array[Selector], index : Int, copy? : Bool) -> SourceDocument raise

    SourceDocument::transfer_json

    fn SourceDocument::transfer_json(self : SourceDocument, json : Json) -> SourceDocument raise

    SourceLocation

    pub(all) struct SourceLocation {
    source : String
    offset : Int
    line : Int
    column : Int
    } derive(Eq,
    Debug
    )

    SourceLocation::equal

    SourceLocation::not_equal

    fn SourceLocation::not_equal(x : SourceLocation, y : SourceLocation) -> Bool

    SteamApp

    pub(all) struct SteamApp {
    app_id : String
    name : String
    install_dir : String
    size_on_disk : Int64?
    build_id : String?
    } derive(Eq,
    Debug
    )

    A validated Steam app manifest. Decimal identifiers stay as strings.

    SteamApp::equal

    fn SteamApp::equal(SteamApp, SteamApp) -> Bool

    SteamApp::not_equal

    fn SteamApp::not_equal(x : SteamApp, y : SteamApp) -> Bool

    SteamApp::to_repr

    SteamCache

    type SteamCache

    An index owns a snapshot of the input. AppInfo payloads are decoded only when requested. PackageInfo has no record sizes, so indexing validates each tree.

    SteamCache::format

    fn SteamCache::format(self : SteamCache) -> CacheFormat

    SteamCache::page

    fn SteamCache::page(self : SteamCache, query? : String, offset? : Int, limit? : Int) -> CachePage raise BinaryError

    Metadata-only pagination never decodes payloads. Query matches decimal IDs.

    SteamCache::read

    fn SteamCache::read(self : SteamCache, id : UInt) -> Array[BinaryEntry]? raise BinaryError

    SteamCache::records

    fn SteamCache::records(self : SteamCache) -> Array[CacheRecord]

    SteamCache::universe

    fn SteamCache::universe(self : SteamCache) -> UInt

    SteamCache::version

    fn SteamCache::version(self : SteamCache) -> Int

    SteamLibrary

    pub(all) struct SteamLibrary {
    index : String
    path : String
    label : String?
    app_ids : Array[String]
    } derive(Eq,
    Debug
    )

    SteamLibrary::equal

    SteamLibrary::not_equal

    fn SteamLibrary::not_equal(x : SteamLibrary, y : SteamLibrary) -> Bool

    SteamShortcut

    pub(all) struct SteamShortcut {
    index : String
    app_id : UInt
    name : String
    exe : String
    start_dir : String
    launch_options : String
    tags : Array[String]
    } derive(Eq,
    Debug
    )

    SteamShortcut::equal

    SteamShortcut::not_equal

    fn SteamShortcut::not_equal(x : SteamShortcut, y : SteamShortcut) -> Bool

    SteamShortcut::url

    fn SteamShortcut::url(self : SteamShortcut) -> String

    StreamEvent

    pub(all) enum StreamEvent {
    Pair(String, String)
    BeginObject(String)
    EndObject
    Condition(String, String)
    } derive(Eq,
    Debug
    )

    Raw SAX-style events. Conditions are validated and retained, never evaluated. Returning false for BeginObject suppresses descendants but still validates them and emits the matching EndObject. All other return values are ignored.

    StreamEvent::equal

    fn StreamEvent::equal(StreamEvent, StreamEvent) -> Bool

    StreamEvent::not_equal

    fn StreamEvent::not_equal(x : StreamEvent, y : StreamEvent) -> Bool

    StreamParser

    type StreamParser

    StreamParser::characters_seen

    fn StreamParser::characters_seen(self : StreamParser) -> Int

    StreamParser::entries_seen

    fn StreamParser::entries_seen(self : StreamParser) -> Int

    StreamParser::feed

    fn StreamParser::feed(self : StreamParser, chunk : String) -> Unit raise

    StreamParser::feed_bytes

    fn StreamParser::feed_bytes(self : StreamParser, chunk : Bytes) -> Unit raise

    Strict incremental UTF-8, retaining at most three incomplete bytes between calls.

    StreamParser::finish

    fn StreamParser::finish(self : StreamParser) -> Unit raise

    StreamWriter

    type StreamWriter

    A bounded event writer. Conditions and root directives require a document resolver and are rejected rather than silently changing their meaning.

    StreamWriter::finish

    fn StreamWriter::finish(self : StreamWriter) -> Unit raise WriteError

    StreamWriter::write

    fn StreamWriter::write(self : StreamWriter, event : StreamEvent) -> Unit raise

    VMTMaterial

    pub(all) struct VMTMaterial {
    shader : String
    parameters : Array[Entry]
    origins : Array[VMTOrigin]
    includes : Array[String]
    } derive(Eq,
    Debug
    )

    VMTMaterial::equal

    fn VMTMaterial::equal(VMTMaterial, VMTMaterial) -> Bool

    VMTMaterial::not_equal

    fn VMTMaterial::not_equal(x : VMTMaterial, y : VMTMaterial) -> Bool

    VMTMaterial::stringify

    fn VMTMaterial::stringify(self : VMTMaterial) -> String raise

    VMTMaterial::textures

    fn VMTMaterial::textures(self : VMTMaterial, extra_parameters? : Array[String]) -> Array[VMTTexture] raise

    VMTMaterial::to_json

    fn VMTMaterial::to_json(self : VMTMaterial) -> Json raise

    VMTMaterial::with_parameter

    fn VMTMaterial::with_parameter(self : VMTMaterial, key : String, value : String) -> VMTMaterial raise

    Return a new material with one top-level parameter. Duplicate matches are rejected so an edit cannot silently target a different effective parameter.

    VMTOrigin

    pub(all) struct VMTOrigin {
    path : Array[Int]
    source : String
    operation : String
    } derive(Eq,
    Debug
    )

    VMTOrigin::equal

    fn VMTOrigin::equal(VMTOrigin, VMTOrigin) -> Bool

    VMTOrigin::not_equal

    fn VMTOrigin::not_equal(x : VMTOrigin, y : VMTOrigin) -> Bool

    VMTTexture

    pub(all) struct VMTTexture {
    path : Array[String]
    parameter : String
    value : String
    target : String?
    status : String
    } derive(Eq,
    Debug
    )

    VMTTexture::equal

    fn VMTTexture::equal(VMTTexture, VMTTexture) -> Bool

    VMTTexture::not_equal

    fn VMTTexture::not_equal(x : VMTTexture, y : VMTTexture) -> Bool

    VPKArchive

    type VPKArchive

    VPKArchive::embedded_size

    fn VPKArchive::embedded_size(self : VPKArchive) -> Int?

    VPKArchive::entries

    fn VPKArchive::entries(self : VPKArchive) -> Array[VPKEntry]

    VPKArchive::find

    fn VPKArchive::find(self : VPKArchive, path : String) -> VPKEntry?

    VPKArchive::read

    fn VPKArchive::read(self : VPKArchive, path : String, loader : (Int, Int, Int) -> Bytes raise, verify_crc? : Bool) -> Bytes raise

    Loader arguments are archive index, absolute byte offset and byte count. Index 0x7fff refers to the directory file. CRC covers preload plus body.

    VPKArchive::to_json

    fn VPKArchive::to_json(self : VPKArchive) -> Json

    VPKArchive::version

    fn VPKArchive::version(self : VPKArchive) -> Int

    VPKEntry

    pub(all) struct VPKEntry {
    path : String
    crc32 : UInt
    preload : Bytes
    archive : Int
    offset : Int
    length : Int
    } derive(Eq,
    Debug
    )

    VPKEntry::equal

    fn VPKEntry::equal(VPKEntry, VPKEntry) -> Bool

    VPKEntry::not_equal

    fn VPKEntry::not_equal(x : VPKEntry, y : VPKEntry) -> Bool

    VPKEntry::to_repr

    Value

    pub(all) enum Value {
    Text(String)
    Object(Array[Entry])
    } derive(Eq,
    Debug
    )

    A KeyValues value. Objects are ordered lists, so duplicate keys are retained.

    Value::as_object

    fn Value::as_object(self : Value) -> Array[Entry]?

    Value::as_text

    fn Value::as_text(self : Value) -> String?

    Value::equal

    fn Value::equal(Value, Value) -> Bool

    Value::not_equal

    fn Value::not_equal(x : Value, y : Value) -> Bool

    Value::to_repr

    Workspace

    type Workspace

    Immutable mixed KV1/text KV3 workspace. Operations return a new snapshot; hosts decide how to present or save it. No multi-file filesystem atomicity is claimed.

    Workspace::add_file

    fn Workspace::add_file(self : Workspace, name : String, text : String) -> Workspace raise

    Workspace::apply

    fn Workspace::apply(self : Workspace, plan : Json) -> Workspace raise

    Workspace::copy_file

    fn Workspace::copy_file(self : Workspace, from : String, to : String) -> Workspace raise

    Workspace::edit_query

    fn Workspace::edit_query(self : Workspace, expression : String, operation : QueryEdit, files? : Array[String]) -> Workspace raise

    Every edit addresses original file contents. Failure returns no new workspace.

    Workspace::edit_query_kv3

    fn Workspace::edit_query_kv3(self : Workspace, expression : String, operation : KV3QueryEdit, files? : Array[String]) -> Workspace raise

    All targets use original file snapshots. Failure returns no partial workspace.

    Workspace::files

    fn Workspace::files(self : Workspace) -> Map[String, String]

    Workspace::remove_file

    fn Workspace::remove_file(self : Workspace, name : String) -> Workspace raise

    Workspace::rename_file

    fn Workspace::rename_file(self : Workspace, from : String, to : String) -> Workspace raise

    Rename incoming references, including inactive branches, and rebase outgoing references when the moved file changes directory.

    Workspace::select

    fn Workspace::select(self : Workspace, expression : String, files? : Array[String]) -> Json raise

    Empty file selection means all files. Results are ordered by file then source.

    Workspace::select_kv3

    fn Workspace::select_kv3(self : Workspace, expression : String, files? : Array[String]) -> Json raise

    Typed queries select KV3 files only. Explicit selections reject KV1 files.

    Workspace::to_json

    fn Workspace::to_json(self : Workspace) -> Json

    binary_from_json

    fn binary_from_json(json : Json, options? : BinaryOptions) -> Array[BinaryEntry] raise BinaryError

    binary_to_json

    fn binary_to_json(entries : Array[BinaryEntry]) -> Json

    Ordered typed JSON; numeric payloads use decimal strings, including raw Float32 bits. No precision or NaN information is routed through JSON numbers.

    build_dependency_graph

    fn build_dependency_graph(roots : Array[String], filesystem : GameFileSystem, max_files? : Int, max_bytes? : Int) -> DependencyGraph raise

    Build a bounded transitive graph from an explicit mounted filesystem. Missing, dynamic and opaque references stay visible; base-game files retain their provenance and can be excluded from export without marking them missing.

    changes_from_json

    fn changes_from_json(json : Json) -> Array[Change] raise

    Portable JSON plan: [{path:[{key,occurrence}],op,value/key/index/entry}]. Values and entries use the same ordered representation as Document::to_json.

    check_inventory

    fn check_inventory(libraries : Array[SteamLibrary], records : Array[InventoryRecord]) -> Array[InventoryIssue]

    Check listed records against declared apps. Paths are compared exactly; filesystem canonicalization and case rules belong to the host adapter.

    compile_kv3_query

    fn compile_kv3_query(expression : String) -> KV3Query raise

    Same path steps and escaping as KV1, with /0 array indices, typed predicates and conjunctions. Numeric comparisons do not coerce integers into doubles.

    compile_query

    fn compile_query(expression : String) -> Query raise QueryError

    create_vpk

    fn create_vpk(files : Map[String, Bytes], preload_bytes? : Int, options? : BinaryOptions) -> Bytes raise

    Deterministic embedded VPK v1. File names are case-insensitive, contents are uncompressed and CRC32 is computed over the complete original byte stream.

    decode_binary

    fn decode_binary(bytes : Bytes, options? : BinaryOptions, string_table? : Array[String]?) -> Array[BinaryEntry] raise BinaryError

    Decode standard KV1 with marker 8. Reject truncated streams, trailing bytes, invalid encodings and unknown types. Appinfo containers and VBKV are separate formats.

    decode_kv3_binary

    fn decode_kv3_binary(bytes : Bytes, options? : BinaryOptions) -> KV3BinaryDocument raise

    Decode lane-encoded KV3 versions 1..5. Legacy VKV3 is dispatched separately.

    dmx_from_json

    fn dmx_from_json(json : Json) -> DMXDocument raise

    dmx_to_json

    fn dmx_to_json(document : DMXDocument) -> Json raise

    document_from_json

    fn document_from_json(value : Json, options? : ParseOptions) -> Document raise JsonImportError

    Decode the ordered [{key,value}] representation emitted by to_json.

    edit_workspace_snapshot

    fn edit_workspace_snapshot(snapshot : Json, plan : Json, options? : ParseOptions) -> Json raise

    encode_binary

    fn encode_binary(entries : Array[BinaryEntry], options? : BinaryOptions, string_table? : Array[String]?) -> Bytes raise BinaryError

    Encode with the same limits as decoding. Order, duplicate keys and numeric types survive a decode/encode round trip without coercion through JSON numbers.

    encode_dmx_binary

    fn encode_dmx_binary(document : DMXDocument, version? : Int, options? : BinaryOptions) -> Bytes raise

    encode_kv3_binary

    fn encode_kv3_binary(document : KV3BinaryDocument, version? : Int, compression? : Int, options? : BinaryOptions) -> Bytes raise

    Write interoperable versions 4 or 5. Numbers preserve original storage width and IEEE bits. Container layout is canonical; compressed bytes need not match.

    encode_kv3_resource

    fn encode_kv3_resource(document : KV3BinaryDocument, resource_version? : Int, version? : Int, compression? : Int, options? : BinaryOptions) -> Bytes raise

    Construct a DATA-only resource. Rebuilding arbitrary compiled resources needs block-specific relocation and is deliberately a separate operation.

    evaluate_condition

    fn evaluate_condition(expression : String, symbols : Array[String]) -> Bool raise ConditionError

    Evaluate $NAME, !, &&, || and parentheses. Symbols are explicit and ASCII case-insensitive; unknown symbols are false. No host platform is inferred.

    export_files_zip

    fn export_files_zip(files : Map[String, Bytes]) -> Bytes raise

    Binary-safe deterministic ZIP32 for explicit virtual files.

    export_project_zip

    fn export_project_zip(snapshot : Json, options? : ParseOptions) -> Bytes raise

    Deterministic ZIP32, stored entries, UTF-8 names, CRC32 and central directory. No compressor, archive reader or filesystem access is required.

    gameinfo_search_paths

    fn gameinfo_search_paths(document : Document, gameinfo_directory : String, engine_directory : String, language? : String) -> Array[GameSearchPath] raise

    Expand known gameinfo tokens using explicit roots. Wildcard paths are plans for the caller to enumerate and mount, not permission to scan the host disk.

    generic_kv3_header

    fn generic_kv3_header() -> KV3Header

    inventory_csv

    fn inventory_csv(records : Array[InventoryRecord]) -> String

    RFC 4180 quoting with CRLF records. All fields are quoted, so commas, quotes and embedded line breaks remain unambiguous.

    inventory_total

    fn inventory_total(records : Array[InventoryRecord]) -> InventoryTotal raise SteamError

    kv3_binary_from_document

    fn kv3_binary_from_document(document : KV3Document) -> KV3BinaryDocument raise

    kv3_binary_from_json

    fn kv3_binary_from_json(json : Json) -> KV3BinaryDocument raise

    kv3_binary_to_json

    fn kv3_binary_to_json(document : KV3BinaryDocument) -> Json raise

    kv3_from_json

    fn kv3_from_json(json : Json) -> KV3Document raise

    kv3_located_values_to_json

    fn kv3_located_values_to_json(values : Array[KV3LocatedValue]) -> Json

    kv3_query_edit_from_json

    fn kv3_query_edit_from_json(json : Json) -> KV3QueryEdit raise

    kv3_to_json

    fn kv3_to_json(document : KV3Document) -> Json raise

    Typed ordered JSON preserves integer precision, float spelling and flags.

    load_project

    fn load_project(source : String, loader : (String) -> String raise, options? : ParseOptions, max_files? : Int) -> ResolvedProject raise

    The resolver and provenance use one merge operation. Locations identify key starts in the original files, before filtering or formatting, in scalar units.

    load_resolved

    fn load_resolved(source : String, loader : (String) -> String raise, options? : ParseOptions, max_files? : Int) -> Document raise

    Load and resolve root-level includes and bases through an explicit loader. Virtual paths use / separators. Budgets count every loaded file, including repeated references, and entries parsed from filtered conditional branches.

    load_vmt

    fn load_vmt(source : String, loader : (String) -> String raise, options? : ParseOptions, max_files? : Int) -> VMTMaterial raise

    Resolve Patch include/insert/replace through an explicit game-relative loader. Origin indices address the expanded parameter tree, including repeated proxies.

    localization_from_json

    fn localization_from_json(json : Json) -> Localization raise

    localization_issues_to_json

    fn localization_issues_to_json(issues : Array[LocalizationIssue]) -> Json

    localization_placeholders

    fn localization_placeholders(text : String, syntax? : String) -> Array[String] raise

    Validate Valve indexed %s1/%d2, printf argument identities, or brace tokens. Sorted identities retain multiplicity, so dropped/repeated parameters differ.

    located_values_to_json

    fn located_values_to_json(values : Array[LocatedValue]) -> Json

    lsp_frame

    fn lsp_frame(message : Json) -> Bytes

    lsp_position

    fn lsp_position(text : String, offset : Int) -> Json

    mount_game_filesystem

    fn mount_game_filesystem(mounts : Array[GameMount], max_bytes? : Int) -> GameFileSystem raise

    Mount order is search order: the first existing file wins. Host callbacks provide explicit filesystem access; no directories are discovered implicitly.

    new_lsp_framer

    fn new_lsp_framer() -> LspFramer

    new_lsp_server

    fn new_lsp_server() -> LspServer

    new_shortcut_file

    fn new_shortcut_file() -> ShortcutFile

    new_stream_parser

    fn new_stream_parser(visitor : (StreamEvent) -> Bool raise, options? : ParseOptions) -> StreamParser raise ParseError

    new_stream_writer

    fn new_stream_writer(sink : (String) -> Unit raise) -> StreamWriter

    new_workspace

    fn new_workspace(files : Map[String, String], options? : ParseOptions) -> Workspace raise

    open_steam_cache

    fn open_steam_cache(input : Bytes, max_bytes? : Int, max_records? : Int) -> SteamCache raise BinaryError

    Supported cache revisions: appinfo 39/40/41, packageinfo 39/40. Record bounds, table offsets, identifiers, sentinels and trailing data are checked strictly.

    parse

    fn parse(input : String, options? : ParseOptions) -> Document raise ParseError

    Parse the documented KV1 text subset; unsupported file-loading directives and platform conditionals are rejected rather than silently misinterpreted.

    parse_json_document

    fn parse_json_document(text : String, options? : ParseOptions) -> Document raise JsonImportError

    parse_kv3

    fn parse_kv3(input : String, options? : ParseOptions, allow_headerless? : Bool) -> KV3Document raise

    Text KV3 only. Limits reuse ParseOptions; KV1 condition/literal modes are invalid.

    parse_kv3_preserving

    fn parse_kv3_preserving(input : String, options? : ParseOptions, allow_headerless? : Bool) -> KV3SourceDocument raise

    parse_po

    fn parse_po(text : String) -> POCatalog raise

    parse_preserving

    fn parse_preserving(input : String, options? : ParseOptions) -> SourceDocument raise

    parse_vmt

    fn parse_vmt(text : String, source? : String, options? : ParseOptions) -> VMTMaterial raise

    project_export_files

    fn project_export_files(snapshot : Json, options? : ParseOptions) -> Map[String, String] raise

    Validate all contents and portable paths before hosts create any output. Only the files explicitly contained in the snapshot are exported.

    query_edit_from_json

    fn query_edit_from_json(json : Json) -> QueryEdit raise

    query_workspace_kv3_snapshot

    fn query_workspace_kv3_snapshot(snapshot : Json, expression : String, files? : Array[String], options? : ParseOptions) -> Json raise

    query_workspace_snapshot

    fn query_workspace_snapshot(snapshot : Json, expression : String, files? : Array[String], options? : ParseOptions) -> Json raise

    read_app_manifest

    fn read_app_manifest(document : Document) -> SteamApp raise SteamError

    Interpret an AppState object without touching the filesystem.

    read_dmx

    fn read_dmx(bytes : Bytes, options? : BinaryOptions) -> DMXDocument raise

    read_library_folders

    fn read_library_folders(document : Document) -> Array[SteamLibrary] raise SteamError

    Read current object-style and legacy string-style libraryfolders entries.

    read_localization

    fn read_localization(bytes : Bytes) -> Localization raise

    BOM determines UTF-16 endianness. UTF-8 without a BOM remains valid; malformed Unicode is rejected, never replaced with lossy text.

    read_resource_container

    fn read_resource_container(bytes : Bytes, options? : BinaryOptions) -> ResourceContainer raise

    Source 2 resource header version 12; block offsets address their own offset fields. Payloads remain bounded slices; unknown blocks are exposed unchanged.

    read_shortcut_file

    fn read_shortcut_file(entries : Array[BinaryEntry]) -> ShortcutFile raise SteamError

    read_vpk

    fn read_vpk(bytes : Bytes, options? : BinaryOptions) -> VPKArchive raise

    Only directory metadata is required. Embedded bytes can be supplied later by the range loader; numbered archives are never eagerly read by this API.

    resource_references_to_json

    fn resource_references_to_json(references : Array[ResourceReference]) -> Json

    resource_roots_from_json

    fn resource_roots_from_json(json : Json) -> Array[ResourceRoot] raise

    select_inventory

    fn select_inventory(records : Array[InventoryRecord], filter? : String, sort? : String) -> Array[InventoryRecord] raise SteamError

    Filter by Unicode lowercase name or identifier; sort by name, id or descending size. Missing sizes sort last. Identifiers are compared as decimal integers.

    shortcut_app_id

    fn shortcut_app_id(name : String, exe : String) -> UInt

    Stable Steam shortcut identifier: CRC-32/ISO-HDLC(exe + name), high bit set.

    stringify

    fn stringify(document : Document) -> String raise WriteError

    Canonical escaped KV1 text. All keys and strings are quoted; order and duplicates are retained. Comments and original whitespace are not retained.

    stringify_dmx

    fn stringify_dmx(document : DMXDocument, options? : BinaryOptions) -> String raise

    Flat KeyValues2 retains UUID graph identity, cycles and shared references. IEEE NaN payloads belong to binary serialization; text normalizes them.

    stringify_kv3

    fn stringify_kv3(document : KV3Document) -> String raise

    update_po

    fn update_po(template : POCatalog, previous : POCatalog) -> POCatalog raise

    Update a PO/POT from a new source catalog. Changed text keeps the old translation marked fuzzy; removed messages become obsolete.

    version

    fn version() -> String

    Development version; distribution scripts verify it against moon.mod.

    workspace_from_json

    fn workspace_from_json(json : Json, options? : ParseOptions) -> Workspace raise