Archive CLI
Archive commands package gamedata into X-Ray .db or .xdb volumes, inspect their contents, and extract or verify
stored files. Use pack for a full distribution and pack-patch for added or modified files relative to an
installation.
Packing examples run from a project containing target/gamedata. Inspection and unpacking examples use a db directory
in the current working directory. Source paths and output destinations are separate.
Pack an archive
Pack the assembled tree, then verify the written volumes:
xrf-cli archive pack target\gamedata --dest target\db --name gamedata
xrf-cli archive verify --path target\db
Example output excerpt — pack an archive:
Packed 29 file(s) into 1 volume(s) in 23 ms
Phases: 10 ms collecting, 13 ms writing, 0 ms finalizing
Summary: 14 compressed, 15 stored, 0 aliased, 0 skipped
Size: 2.37 MB source, 2.37 MB written
Speed: 103 MB/s
Exit code: 0.
The command compresses file types the engine normally compresses and stores the rest. It writes one volume as
gamedata.db; when the archive needs more than one volume, it writes gamedata.db0, gamedata.db1, and so on.
By default, a volume can be up to 1900 MB and receives a header that mounts its contents at $fs_root$\gamedata\. That
is the usual setting for a gamedata archive. To add or change one entry, name it:
xrf-cli archive pack target\gamedata --dest target\db --name gamedata `
--header 'creator="Modder"' --header 'link="www.moddb.com/mods/my-mod"'
Each --header value is key=value, merged over the default header, so naming creator keeps auto_load and
entry_point. level_name, level_ver, creator, and link are the entries mod templates conventionally carry; they
are yours to set and the engine ignores them.
The engine requires auto_load and entry_point; a volume missing either can stop the game on load. Packing validates
the effective header before writing, including values supplied through a configuration file.
Choose what to pack
Without selection options, the command packs the whole source directory. Use a configuration file when the selection is shared or checked in; use command-line options for a one-off build. They cannot be combined.
An .ltx configuration uses the xrCompress dialect:
[options]
exclude_exts = *.txt,*.json
[include_folders]
configs = true
scripts = true
[include_files]
gamemtl.xr
[header]
auto_load = true
entry_point = $fs_root$\gamedata\
xrf-cli archive pack target\gamedata --dest target\db --name gamedata --config pack.ltx
In [include_folders] and [exclude_folders], true applies to the directory and everything below it; false applies
only to the named directory. Use .\ for the packed root. An .ltx or .json configuration may contain selection
rules and a header only. Source path, destination, volume name, and run options remain on the command line.
A JSON configuration for the same selection looks like this:
{
"excludeExtensions": ["*.txt", "*.json"],
"includeFiles": ["gamemtl.xr"],
"includeDirectories": [
{ "path": "configs", "isRecursive": true },
{ "path": "scripts", "isRecursive": true }
],
"header": [
{ "key": "auto_load", "value": "true" },
{ "key": "entry_point", "value": "$fs_root$\\gamedata\\" }
]
}
xrf-cli archive pack target\gamedata --dest target\db --name gamedata --config pack.json
For a direct selection, repeat the relevant option:
xrf-cli archive pack target\gamedata --dest target\db --name configs `
--include-directory configs --include-directory spawns --include-file gamemtl.xr `
--exclude-extension '*.txt'
--include-directory-shallow includes a directory’s files but not the files in its child directories.
--exclude-directory-shallow excludes the named directory only; its contents can still be packed. All paths are
relative to the source.
Common packing options
- Use
--storeto store every file without compression. - Use
--max-size <MB>to choose a volume cap from 1 through 1900 MB.--oversized-volumespermits a larger cap only for an engine fork that supports it. - Use
--xdbto create.xdbvolumes. - Use
--no-skip-listto retain editor and source leftovers that the normal engine-build skip list excludes. - Use
--verboseto see every selected, skipped, stored, compressed, and deduplicated file while packing.
Performance compared with xrCompress
These are median results from interleaved runs of both tools on the same machine and source tree. xrCompress -fast
uses the compression mode that matches archive pack; the xrCompress default trades time for a smaller archive. Each
time/RAM value is wall-clock seconds and peak resident memory in megabytes.
| Input | archive pack time / peak RAM (s / MB) | xrCompress -fast time / peak RAM (s / MB) |
|---|---|---|
| 1,657 config files, 9.89 MB | 0.22 s / 11 MB | 0.57 s / 99 MB |
| 4,206 Anomaly configs and scripts, 35 MB | 0.86 s / 13 MB | 0.97 s / 101 MB |
| 1,017 mesh files, 275 MB | 0.17 s / 28 MB | 1.07 s / 115 MB |
| Vanilla gamedata, 36,925 files, 4.69 GB | 4.6 s / 180 MB | 16.8 s / 275 MB |
For inputs that contain compressible files, these are the resulting archive sizes:
| Input | archive pack | xrCompress -fast | xrCompress |
|---|---|---|---|
| 1,657 config files, 9.89 MB | 2.00 MB | 2.49 MB | 1.93 MB |
| Anomaly configs and scripts, 35 MB | 8.57 MB | 10.63 MB | 8.26 MB |
In these comparisons, archives packed from the same source by either tool unpacked to byte-identical files.
Replace an existing archive
Packing refuses to overwrite volumes with the same name. Add --force only when replacing that set is intended:
xrf-cli archive pack target\gamedata --dest target\db --name gamedata --force
--force replaces volumes as it writes and cannot restore the previous set after a partial failure. It also does not
prune higher-numbered volumes left by a larger previous build. Prefer a fresh output directory, verify its complete set,
then replace the old distribution. A non-forced failed run removes the volumes it created.
Build a patch
archive pack-patch creates .db volumes containing added and modified files. To package edits from a game’s loose
gamedata\, point at the installation:
xrf-cli archive pack-patch 'C:\Games\Anomaly' --dest target\patch --name mypatch
Without --target, the command compares the installation’s archives with its loose files. Unchanged copies are omitted,
and archived files absent from gamedata\ remain untouched. The installation must contain archives and loose files to
compare.
Write outside the input and target trees; destinations inside either are refused. Copy the resulting volumes to a
directory mounted after the base archives in fsgame.ltx, usually db\patches\.
Loose files in the player’s gamedata\ take priority over patch archives. Distribute loose replacements when those
files need updating.
A patch cannot remove a base file: archive registration can replace an entry but has no deletion marker. Removing content requires replacing or removing it from the installed base distribution.
Deliver a tree of your own
Use --target to deliver files from a separate folder:
xrf-cli archive pack-patch 'C:\Games\Anomaly' --target C:\work\mymod\gamedata `
--dest target\patch --name mypatch
For a loose target, name the gamedata directory itself, with paths such as configs\ and textures\ directly inside
it. Naming its parent adds an unwanted gamedata\ prefix to archive entries.
Preview before writing
Use --dry-run to compare without writing volumes. Add --report to save every changed entry:
xrf-cli archive pack-patch 'C:\Games\Anomaly' --dry-run --report patch-preview.json
The size shown is the total unpacked payload; the final archive size is known only after writing.
--include configslimits both sides to a logical prefix.--ignore configs\debugexcludes a prefix, even when included.--exclude-extension '*.txt'excludes matching file extensions.--verify-payloadreads and compares both payloads when their sizes and checksums match.
The three filter options are repeatable.
Inspect or extract files
For info, list, find, extract, and verify, --path may name one volume or a directory. A volume reads only
that file; a directory reads all .db and .xdb volumes below it as one merged archive set.
# Check the number of volumes, entries, and their sizes.
xrf-cli archive info --path .\db
# List file paths, or search their names without unpacking.
xrf-cli archive list --path .\db --files
xrf-cli archive find --path .\db --query wpn_ak74 --files
# Extract one logical file, or an entire logical directory.
xrf-cli archive extract --path .\db --file textures\wpn\wpn_ak74.dds --dest .\ak74.dds
xrf-cli archive extract --path .\db --directory configs --dest .\extracted-configs
list --verbose and find --verbose show a file’s sizes and source volume. If identical files share one stored
payload, they also name the other paths that read those bytes.
Unpack an archive
Unpack a complete volume set by giving its containing directory:
xrf-cli archive unpack --path .\db --dest .\unpacked
The archive’s mount prefix is retained beneath the destination. An archive packed with the default gamedata header
therefore writes files under unpacked/gamedata, rather than directly under unpacked.
To unpack one volume by itself, pass the volume path instead. --dry opens the archive and prints its summary without
writing files. Use -j to control the worker count, for example -j 8 or -j 50%.
xrf-cli archive unpack --path .\db\configs.db --dest .\unpacked\configs --dry
Use a new or empty destination directory. Existing files can otherwise be replaced while the archive is unpacked.
Unpacking speed and memory
These results use the same measurement method. The default run uses the available worker count; -j 1 is the
single-worker comparison.
| Archive | archive unpack time / peak RAM (s / MB) | -j 1 time / peak RAM (s / MB) |
|---|---|---|
| Vanilla configs, 1,657 files, 2.00 MB | 0.20 s / 12 MB | 0.40 s / 10 MB |
| Vanilla gamedata, 36,925 files, 4.48 GB | 6.1 s / 28 MB | 12.3 s / 21 MB |
Verify an archive
Verify every file after packing or copying an archive:
xrf-cli archive verify --path .\db
Example output — verify an archive:
Verified 29 file(s) in 29 ms
Exit code: 0.
The command reads every payload, checks decompression, and validates its CRC. It reports damaged files as failures; use
--report archive-verify.json to save the findings. Successful archive verification establishes payload integrity; run
gamedata verification to check the files’ formats and references in their installed context.
Command reference
xrf-cli archive extract
Extract one archive file or directory without unpacking the complete set
xrf-cli archive extract [OPTIONS] --path <path> --dest <dest>
| Option | Required | Default | Description |
|---|---|---|---|
-p, --path <path> | yes | Path to an archive volume or a directory containing volumes | |
--file <file> | Exact logical path of one archive file; –dest is the output file | ||
--directory <directory> | Logical directory to extract; –dest receives that directory’s contents | ||
-d, --dest <dest> | yes | Output file for –file, or output directory for –directory | |
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive find
Find archive entries whose logical path contains text
xrf-cli archive find [OPTIONS] --path <path> --query <query>
| Option | Required | Default | Description |
|---|---|---|---|
-p, --path <path> | yes | Path to an archive volume or a directory containing volumes | |
-q, --query <query> | yes | Case-insensitive text to find in an entry’s logical path | |
--files | Search files only, excluding directory records | ||
--directories | Search directory records only, excluding files | ||
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive info
Describe an X-Ray archive volume or volume set
xrf-cli archive info [OPTIONS] --path <path>
| Option | Required | Default | Description |
|---|---|---|---|
-p, --path <path> | yes | Path to an archive volume or a directory containing volumes | |
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive list
List the merged entries in an X-Ray archive volume or volume set
xrf-cli archive list [OPTIONS] --path <path>
| Option | Required | Default | Description |
|---|---|---|---|
-p, --path <path> | yes | Path to an archive volume or a directory containing volumes | |
--files | List files only, excluding directory records | ||
--directories | List directory records only, excluding files | ||
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive pack
Command to pack provided directory into *.db archive volumes
xrf-cli archive pack [OPTIONS] <SOURCE>
| Option | Required | Default | Description |
|---|---|---|---|
<SOURCE> | yes | Directory to pack, normally a gamedata root | |
-d, --dest <dest> | packed | Path to folder for writing the volumes | |
-n, --name <name> | gamedata | Base name of the volumes, written as <name>.db0, <name>.db1 and so on | |
--config <config> | Path to a packing configuration describing what to include, as *.ltx or *.json | ||
--include-file <include-file>... | File to pack, named relative to the source, repeatable | ||
--include-directory <include-directory>... | Directory to pack with everything below it, relative to the source, repeatable | ||
--include-directory-shallow <include-directory-shallow>... | Directory whose own files are packed while its subdirectories only get listed, repeatable | ||
--exclude-directory <exclude-directory>... | Directory to leave out along with everything below it, repeatable | ||
--exclude-directory-shallow <exclude-directory-shallow>... | Directory to leave out while its contents still pack, repeatable | ||
--exclude-extension <exclude-extension>... | Extension pattern that keeps a file out, such as *.txt, repeatable | ||
--header <header>... | Header entry written into the archive as <key>=<value>, repeatable, merged over the default header | ||
--store | Store every file instead of compressing what the engine expects compressed | ||
--max-size <max-size> | Maximum volume size in megabytes, from 1 to 1900 | ||
--oversized-volumes | Let –max-size exceed 1900 MB, which only an engine fork that raised XRP_MAX_SIZE can mount | ||
--xdb | Write volumes with the xdb extension | ||
--no-skip-list | Keep editor and source leftovers the engine build normally drops | ||
-f, --force | Replace volumes of the same set the destination already holds | ||
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive pack-patch
Command to pack what a gamedata tree changes about an installation into overriding *.db archive volumes
xrf-cli archive pack-patch [OPTIONS] <SOURCE>
| Option | Required | Default | Description |
|---|---|---|---|
<SOURCE> | yes | What to patch: an installation, a directory of volumes, or a gamedata tree | |
--target <target> | Tree the patch delivers; omit to use the loose gamedata of the input itself | ||
-d, --dest <dest> | packed | Path to folder for writing the volumes | |
-n, --name <name> | patch | Base name of the volumes, written as <name>.db0, <name>.db1 and so on | |
--dry-run | Report the difference and write no volumes | ||
--config <config> | Path to a patching configuration describing the comparison scope and header, as *.ltx or *.json | ||
--include <include>... | Logical prefix the comparison is restricted to, such as configs, repeatable | ||
--ignore <ignore>... | Logical prefix dropped from the comparison, repeatable | ||
--exclude-extension <exclude-extension>... | Extension pattern that keeps a file out of the comparison, such as *.txt, repeatable | ||
--header <header>... | Header entry written into the archive as <key>=<value>, repeatable, merged over the default header | ||
--verify-payload | Confirm every checksum match by comparing the payloads themselves | ||
--store | Store every file instead of compressing what the engine expects compressed | ||
--max-size <max-size> | Maximum volume size in megabytes, from 1 to 1900 | ||
--oversized-volumes | Let –max-size exceed 1900 MB, which only an engine fork that raised XRP_MAX_SIZE can mount | ||
--xdb | Write volumes with the xdb extension | ||
-f, --force | Replace volumes of the same set the destination already holds | ||
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive unpack
Command to unpack provided *.db into separate files
xrf-cli archive unpack [OPTIONS] --path <path>
| Option | Required | Default | Description |
|---|---|---|---|
-p, --path <path> | yes | Path to *.db file | |
-d, --dest <dest> | unpacked | Path to folder for exporting | |
--dry | Run in dry mode without actually unpacking to disk | ||
-j, --jobs <JOBS> | auto | How much of the machine to use: ‘auto’, a worker count, or a share such as ‘50%’ | |
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |
xrf-cli archive verify
Read every archive payload and verify decompression and CRC checks
xrf-cli archive verify [OPTIONS] --path <path>
| Option | Required | Default | Description |
|---|---|---|---|
-p, --path <path> | yes | Path to an archive volume or a directory containing volumes | |
-s, --silent | Turn off logging | ||
-v, --verbose | Turn on verbose logging | ||
--json | Write the run’s JSON report to stdout, moving human output to stderr | ||
--report <PATH> | Write the run’s JSON report to a file |