I open-sourced CAVS: tiny verified updates for Godot PCK games

Hi Godot community,

I recently open-sourced a project I have been working on called CAVS:

CAVS is a content-addressable update/delivery system for game assets. The first practical target is Godot PCK-based games.

The basic idea is simple:

Instead of making players download a full new .pck every time, CAVS splits the exported pack into verified chunks, stores them by hash, and later downloads only the chunks that are missing on the client. The client reconstructs the final PCK locally, verifies it, and then mounts it at runtime.

I tested it with real open-source Godot projects from GitHub using two refs from each repo history. The results were encouraging:

  • Marble: update went from 6.55 MiB compressed PCK to 0.19 MiB with CAVS

  • GDQuest third-person controller demo: 27.61 MiB to 13.27 MiB

  • Godot TPS demo: 247.60 MiB to 4.97 MiB, later improved to 1.64 MiB with 64 KiB chunks

The client now reconstructs files in a streaming way, writing to .part, verifying SHA-256, and doing an atomic rename only after the file is valid. On the 569 MiB TPS demo PCK, peak client RAM dropped from about 1.1 GiB to around 7 MiB in release mode.

What CAVS is:

  • open-source

  • written in Rust

  • content-addressable

  • designed for verified game updates

  • useful for PCKs, game assets, launchers, and possibly other asset delivery systems

What CAVS is not:

  • not a replacement for Godot export

  • not a replacement for SteamPipe or platform patching

  • not trying to be a new compression codec

  • not always smaller than xdelta/bsdiff for a single exact v1->v2 patch

The main advantage is operational: one chunk store can serve multiple versions, interrupted downloads can resume safely, the client does not need to keep the entire old PCK in memory, and the reconstructed pack is verified before being exposed.

I would love feedback from Godot developers, especially around:

  • PCK runtime mounting

  • plugin structure

  • update UX

  • security/signing

  • whether this could be useful for indie games with frequent updates

  • what the Godot integration should look like next

Repo:

2 Likes

Yeah, sure.

Why Rust?

Good question. Mostly because the core is very file/IO-heavy: chunking large binary files, hashing, streaming reconstruction, verification, and safe writes to disk. Rust gives good performance and low memory usage while reducing memory-safety issues compared to C/C++.

It also lets the core stay engine-agnostic. Godot can use it through a plugin/CLI/GDExtension, but the same core could later be reused for Unity, Unreal, launchers, or other asset delivery tools. So Rust is not required for the concept, but it felt like a good fit for the low-level update system.

2 Likes

This is neat, but what’s the use case for this?

Both itch.io and Steam - the most common distribution platforms for Godot games - already handle this for developers, creating diffs and patching versions using those diffs.

1 Like

That’s true, and I don’t see CAVS as a replacement for Steam or itch patching.

There are two use cases I’m looking at:

  1. CAVS delivery for custom launchers, self-hosted updates, runtime PCK downloads, mods, DLC/content packs, private builds, etc.

  2. CAVS SteamPipe Analyzer, which would not replace SteamPipe but help developers prepare better builds for it. SteamPipe already patches versions, but large pack files can still cause oversized updates if assets are reordered, offsets change, timestamps/build metadata change, or a small change rewrites a big binary container.

So for Steam, the goal would be to analyze builds before upload and show which files are likely to make the update bigger, then recommend better packing/layout. It improves the workflow around SteamPipe, not the Steam protocol itself.

2 Likes

Just to give an idea of the impact from the early tests:

With real Godot PCKs, CAVS reduced update payloads from full compressed PCK downloads by around 52% to 98%.

Examples:

  • Marble: 6.55 MiB → 0.19 MiB

  • GDQuest demo: 27.61 MiB → 13.27 MiB

  • Godot TPS demo: 247.60 MiB → 1.64 MiB after switching to smaller chunks

The way it works is that the PCK is split into verified content-addressed chunks. When a new version is released, the client only downloads chunks it does not already have, reconstructs the final PCK locally, verifies it with SHA-256, and then exposes/mounts it.

After changing the client to stream reconstruction directly to disk, the TPS demo update used around 7 MiB peak RAM instead of loading the whole 569 MiB PCK in memory.

So the main value is not replacing Steam/itch, but showing that for custom delivery, runtime PCKs, external content packs, or build analysis, this approach can make updates much smaller and safer.

2 Likes

There are concerns about both platforms. Sometimes very serious ones. This could be very useful for those who want to distribute games independently of these platforms. So there is a niche. It’s hard to say how big it is until we see some practical results.

3 Likes

That makes sense. I see it the same way: probably not something every Godot game needs, but potentially useful for independent distribution, custom launchers, private builds, runtime PCK downloads, mods, or games with frequent content updates.

My next goal is to make it easier to test. I already submitted a Godot plugin with the compiled binaries included, so I’m currently waiting for approval on the Godot Asset Library. Once it’s available there, developers should be able to try CAVS without setting up the Rust tooling manually.

After that, I’d like to collect practical results from real projects and see where it actually fits.

2 Likes