CAVS — open-source toolkit for smaller Godot updates, PCK analysis, and runtime content patching

Hi everyone,

I’m working on CAVS, an open-source toolkit for smaller game updates, patch generation, and runtime content delivery.

Repository: GitHub - orelvis15/cavs: Content-addressed delivery for game updates, assets, and engine packs — smaller downloads, persistent cache reuse, and byte-identical reconstruction. · GitHub
Docs / website: CAVS — Content-addressed delivery for game updates

I’m currently focusing mainly on Godot.

The part I’m most interested in testing is dynamic content updates: downloading an updated .pck, verifying it, and mounting it at runtime with ProjectSettings.load_resource_pack().

A minimal Godot-side example would look something like this:

var cavs := CavsClient.new()

await cavs.update_pack({
    "server_url": "http://localhost:8990",
    "asset": "game_content",
    "version": "1.0.1",
    "cache_dir": "user://cavs_cache",
    "output_path": "user://packs/game_content_1.0.1.pck"
})

ProjectSettings.load_resource_pack("user://packs/game_content_1.0.1.pck")

The idea is that the game can request updated content, download only what is needed, reconstruct the updated .pck, verify it, and then mount it as an additional resource pack.

Why this may be useful for Godot developers

Godot projects often ship content through .pck files or additional resource packs. Depending on how the project is exported or packed, a small change can sometimes produce a much larger update than expected.

CAVS tries to help with two related problems:

  1. Runtime content updates
    Useful when the game itself downloads or updates content after launch.

  2. Build/update analysis
    Useful for understanding why a .pck update is large and whether the build layout could be improved.

It can help answer questions like:

  • Why did this small change create a large update?
  • Which part of the .pck changed?
  • Would splitting content into extra resource packs help?
  • How much would players need to download?
  • Can previous installed data be reused instead of downloading everything again?

Minimal CLI flow

The CLI side can be very small for a basic test:

cavs pack game_content_v1.pck --asset game_content --version 1.0.0 -o release_1.0.0.cavs

cavs pack game_content_v2.pck --asset game_content --version 1.0.1 --prev release_1.0.0.cavs -o release_1.0.1.cavs

cavs serve ./releases --port 8990

Then the Godot client can request the new version and mount the reconstructed .pck.

There are more advanced commands for analysis, benchmarking, signatures, SDK integration, and pipeline usage, but I’m trying to keep the first Godot workflow as simple as possible.

Plugin vs platform-level patching

A Godot plugin is not always required.

If a launcher or platform updates the game before it starts, the game itself does not need to understand the patch format.

But if the game should download or update content while running, then a Godot plugin becomes useful. That is the area I’m focusing on: runtime content updates, extra .pck / resource-pack delivery, and workflows where the game can request or mount updated content.

What CAVS currently includes

CAVS currently provides:

  • Godot PCK analysis.
  • Runtime-oriented update flow for additional .pck content.
  • CLI tools for packing, previewing, applying, and verifying updates.
  • Offline .cavsplan update plans.
  • Signature and verification tools.
  • Pack-file analysis for shifted data, scattered changes, compressed blobs, large packs, and TOC/offset issues.
  • Benchmarks against full downloads, butler offline, bsdiff, xdelta3, and fixed-chunk models.
  • SDKs that wrap the Rust core libraries for pipeline integration.
  • A local development server for testing update workflows.

Looking for feedback

CAVS is still a young project, and I know there are many real-world Godot cases I have not tested yet.

I would really appreciate feedback from anyone willing to try it with a small Godot project, a .pck export, or a simple update comparison.

Useful feedback could include:

  • Testing CAVS with real Godot .pck files.
  • Testing runtime content update workflows.
  • Comparing full update size vs CAVS update size.
  • Testing extra resource-pack or DLC-style workflows.
  • Reporting confusing CLI behavior.
  • Reporting missing documentation.
  • Sharing cases where CAVS works well.
  • Sharing cases where it does not work well.

Even small feedback would help a lot at this stage.

Thanks for reading, and I’d be grateful for any thoughts from the Godot community.

1 Like

Why the duplicate post? I open-sourced CAVS: tiny verified updates for Godot PCK games

I appreciate the many examples but I think leading with the Godot sample would be best, this sample shows the part I’d care about most, downloading patches dynamically is the cool feature, server management and CLI tools do not look as fun.

Speaking of CLI the examples are all quite long! Keep in mind this program begs the comparison to platform patching tools like itch.io’s butler which patches with one command, maybe try to reduce the number of commands needed? Or have a “minimal” example. It would also help to remove the bin prefix ./target/release

# butler example
butler push Build/Linux "gertkeno/mygame:linux"

################################################

# CAVS example
# 1. Describe the released version once (compact, ~0.07% of the source)
./target/release/cavs signature export ./Build_v1 --raw -o build_v1.cavssig

# 2. See what the next build changes before publishing anything
./target/release/cavs preview ./Build_v2 --against build_v1.cavssig --changes-only

# 3. Produce a deterministic offline update plan (a portable patch)
./target/release/cavs diff-plan ./Build_v1 ./Build_v2 -o update.cavsplan --report plan.md

# 4. Apply it in place — staged, journaled, verified, mod-friendly
./target/release/cavs apply --old ./InstalledGame --plan update.cavsplan --inplace --verify

# 5. Check any install against a known-good signature (mods tolerated)
./target/release/cavs verify-install ./InstalledGame --signature build_v2.cavssig --allow-extra-files

# Identify/inspect any CAVS file
./target/release/cavs file update.cavsplan
./target/release/cavs ls build_v1.cavssig

Thanks for the feedback, that makes a lot of sense.

You’re right about the duplicate post. I should have kept the Godot-focused announcement in one place instead of splitting it across similar posts.

I also agree that the Godot sample should come first. The dynamic patch/download + mounting flow is probably the most interesting part for Godot users, while the CLI/server/pipeline details are more relevant later for people who want to integrate it deeper.

I’ll update the examples to lead with a minimal Godot workflow and keep the CLI section shorter. Something like:

var cavs := CavsClient.new()

await cavs.update_pack({
    "server_url": "http://localhost:8990",
    "asset": "game_content",
    "version": "1.0.1",
    "cache_dir": "user://cavs_cache",
    "output_path": "user://packs/game_content_1.0.1.pck"
})

ProjectSettings.load_resource_pack("user://packs/game_content_1.0.1.pck")

And for the CLI side, I’ll try to provide a much smaller “minimal path” instead of showing every advanced command. Good point about removing the ./target/release prefix too — the examples should look like installed/user-facing commands.

Thanks again. This is exactly the kind of feedback I was hoping to get from Godot developers.

2 Likes

Thanks again for the feedback. I tried to make testing the Godot flow simpler.

I created CAVS Desktop to make it easier to try the basic workflow without starting from several CLI commands. It is mainly meant to help with testing: select an old .pck and a new .pck, analyze the update, generate the CAVS data, start a local test server, and copy a minimal Godot snippet.

Download: desktop · Releases · orelvis15/cavs · GitHub

If anyone tries it with a small Godot project, I’d really appreciate feedback on whether this makes the flow easier to test.