manifest
zpack manifest <archive.zpak>Writes the index as ZON to stdout - everything the archive describes, without any of its contents:
$ zpack manifest game.zpak > manifest.zon.{ .format_version = 1, .archive_bytes = 12828, .entry_count = 5, .total_bytes = 13309, .stored_bytes = 12565, .entries = .{ .{ .path = "audio/blip.wav", .id = 0x40a8e93753577eb5, .size = 2444, .stored_size = 2370, .method = .deflate, .hash = 0xfe514dafacec030e, }, .{ .path = "data/noise.bin", .id = 0xbc5d025c01217e9b, .size = 4096, .stored_size = 4096, .method = .store, .hash = 0x8ca43708f0ada27c, }, },}Fields
Section titled “Fields”| Field | Is |
|---|---|
format_version |
The archive format version. 1 today |
archive_bytes |
Size of the .zpak file itself, index included |
entry_count |
Number of entries |
total_bytes |
Sum of every entry’s original size |
stored_bytes |
Sum of every entry’s stored size |
entries[].path |
Relative, /-separated |
entries[].id |
The asset handle for that path |
entries[].size |
Original file size |
entries[].stored_size |
Bytes occupied in the archive |
entries[].method |
.store or .deflate |
entries[].hash |
XxHash64 of the original bytes |
Sizes are exact byte counts, not the rounded units list prints.
Entries appear in sorted path order, so two manifests of the same tree diff
cleanly.
Reading it back
Section titled “Reading it back”ZON is Zig’s own literal syntax, so the standard library parses it with no dependency and no hand-written parser:
const Manifest = struct { format_version: u32, archive_bytes: u64, entry_count: u32, total_bytes: u64, stored_bytes: u64, entries: []const struct { path: []const u8, id: u64, size: u64, stored_size: u64, method: enum { store, deflate }, hash: u64, },};
const manifest = try std.zon.parse.fromSliceAlloc(Manifest, gpa, source, null, .{});That makes CI assertions cheap: fail a build when an archive crosses a size budget, when an expected asset disappears, or when a texture’s hash changes unexpectedly. See manifests for worked examples.
It cannot go stale
Section titled “It cannot go stale”The manifest is derived from the archive when the command runs, not written alongside it at pack time. There is no second file to forget to regenerate, and no way for the two to disagree.
Only the index is read, so manifest is as cheap as list.
Without the CLI
Section titled “Without the CLI”Archive.writeManifest takes any std.Io.Writer, so a build.zig step can
produce a manifest without invoking the binary:
var archive = try zpack.Archive.open(gpa, io, .cwd(), "game.zpak");defer archive.deinit();try archive.writeManifest(&writer.interface);