vpkmerge · project details

CLI · Modding Toolkit

vpkmerge

A Rust toolkit for Valve Pak files and the Source 2 assets inside them. Merge many mods into one archive, split them back out, decode textures and compiled models without touching .NET, and recolor a hero's entire ability VFX with one command.

GitHub release downloads Latest release Build status MIT license
01

Overview

why it exists

Deadlock mounts around a hundred addon VPKs before it silently stops loading them. If you hoard mods - and mod people hoard mods - you hit that wall. Pre-merging several mods into one VPK consolidates them into a single addon slot, so a mod manager can resolve load order and overrides up front instead of dropping a pile of loose VPKs into the game.

That was the original tool: merge, with collision policies (later inputs win by default, --strict to refuse), and split as its inverse. Then it grew a toolkit for the assets inside the archives, because once you can open the box, you want to mess with the contents: decode Source 2 textures to PNG, export compiled models to glTF, read and edit sound events, swap hero voice lines with your own MP3s, and recolor VFX.

It's also the merge engine behind Grimoire - the GUI mod manager bundles the vpkmerge binary and calls it for its merge and workshop features.

02

morphic

pure-Rust Source 2 decoding

The interesting crate is morphic: a from-scratch Source 2 asset decoder and encoder in pure Rust. The usual way to read Valve's compiled formats is ValveResourceFormat, which drags in a .NET runtime. morphic replaces that dependency entirely - no .NET, no C runtime, one static binary.

It decodes and re-encodes .vtex_c textures across the BCn family (BC1–BC7, plus BC6H for HDR), covering about 86% of Deadlock's texture corpus by count. It reads, writes, and byte-faithfully patches binary KeyValues3, which is what makes surgical edits to compiled files safe - untouched bytes stay untouched. And it decodes .vmdl_c models - skeleton, skinned meshes, PBR materials, animation clips - straight to binary glTF.

Correctness is held down by a golden-image test harness: LDR decodes diff against PNG references, HDR against raw .f32 siblings with per-channel tolerance, plus roundtrip tests for KV3 and glTF animation.

03

Features

what's in the toolkit

Merge & split

Combine many VPKs into one with per-path collision policies, or split one back into many from a JSON plan. Plus catalog: a searchable offline index of a Deadlock install's assets - voice lines, hero sounds, textures.

Hero VFX recolor

Recolor a whole hero's ability VFX - particle color params, chromatic textures, and baked mesh vertex colors - to one hue, or a static / animated rainbow (prism). One number lands all three mechanisms, packed into a single drop-in addon VPK. rainbow-scan rates which heroes carry the richest spectrum.

Textures & models

Decode .vtex_c to PNG or recolor it by hue and re-encode in its original BCn format, no material edits needed. Export a hero .vmdl_c to a textured, skinned, animated .glb. Extract hero portrait art straight from the archives.

Sound

Decode binary .vsndevts_c sound events to JSON, edit clip paths, volume, and pitch, and re-emit a file the engine loads. soundswap replaces hero sounds with your own MP3 - trim and normalize happen as raw MPEG-frame edits, no decode step.

04

Stack

what it's built on

A four-crate workspace - core, CLI, morphic, and a Tauri + Vue GUI prototype - at roughly 84k lines of Rust, with clippy pedantic enforced workspace-wide. rayon parallelizes block compression, lz4_flex and ruzstd handle Source 2's compressed buffers, and everything ships as one static binary per platform.

05

Status

shipping

Shipping. Twenty tagged releases and counting, with CI running rustfmt, clippy pedantic (-D warnings), and tests on Linux plus a cross-OS check matrix on Windows and macOS. Tag-triggered releases build CLI binaries for Linux x86_64, macOS aarch64, and Windows x86_64, then push an updated vpkmerge-cli-bin package to the AUR automatically. External contributors have landed merged PRs - always a good sign that a tool crossed from personal script to something people depend on.