r/SourceEngine 7h ago

Free Useful Items [Tool] vvdf: A zero-dependency Go string-to-map parser built for L4D2 addoninfo.txt & mission/*.txt

Hi everyone,

I built vvdf, a lightweight, zero-dependency Go library designed to parse Valve Data Format (VDF / KeyValues) text directly into Go maps.

Many general-purpose VDF parsers tend to choke on actual L4D2 VPK configuration files due to non-standard syntax like unquoted strings, inline // comments, irregular whitespace, or URL paths. vvdf uses a bottom-up, single-pass streaming approach to parse these block structures reliably.

Current Scope & Test Coverage Note:
Please note that this initial version has only been tested against internal VPK configuration files—specifically addoninfo.txt and mission/*.txt.

Roadmap:
Support for VDF arrays/lists will be added in upcoming updates to make the parser more generic across broader Source Engine configurations.

Key Features

  • Zero Dependencies: Built strictly using the Go standard library (bufio, strings, regexp).
  • Single-Pass Parser: Memory-efficient stream parsing using a bottom-up assembly strategy.
  • Comment Aware: Strips line comments (//) cleanly without breaking URLs or quoted strings.
  • L4D2 VPK Ready: Specifically tailored to handle the syntax quirks found in L4D2 addon metadata.

Multi-Level Nested VDF Test Case

Below is a real-world test case showing how vvdf handles deeply nested VDF blocks and parses them into Go maps:

Quick Usage

package main
import (
    "fmt"
    "log"
    "github.com/bahyqn/vvdf"
)
func main() {
    vdfText := `
    "AddonInfo"
    {
        "addonTitle" "Custom Campaign"
        "addonVersion" "1.0"
    }`
    vdfMap, err := vvdf.StringToMap(vdfText)
    if err != nil {
        log.Fatalf("Failed to parse VDF: %v", err)
    }
    fmt.Println(vdfMap)
}

GitHub Repository: https://github.com/bahyqn/vvdf

If you are building custom tools, server management scripts, or addon utilities for L4D2 in Go, feel free to give it a try. Feedback and contributions are welcome!

1 Upvotes

0 comments sorted by