Metadata-Version: 2.4
Name: xverter
Version: 1.0.0
Summary: xVerter: Xbox and Xbox 360 game format converter - GoD, ISO, ZAR, STFS, extracted; any to any, verified at every step
Author: blank-query
License: MIT
Project-URL: Homepage, https://github.com/blank-query/xverter
Project-URL: Releases, https://github.com/blank-query/xverter/releases
Keywords: xbox,xbox360,iso,god,zar,cci,cso,chd,xdvdfs,stfs,converter,emulation,redump
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: System :: Archiving
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: textual>=0.80
Requires-Dist: lz4
Requires-Dist: zstandard; python_version < "3.14"
Requires-Dist: py7zr
Provides-Extra: security
Requires-Dist: defusedxml; extra == "security"
Dynamic: license-file

# xVerter

**xVerter: the Xbox 360 — and original Xbox — game format converter: any format in, any format out, verified at every step.**

GoD containers, XDVDFS ISOs (bare or full redump), ZArchive `.zar`, STFS content packages (XBLA/DLC/TUs), CCI, CSO, CHD, `.zip`/`.7z` archives, extracted game directories — `xverter` reads them all, converts between them, shows live progress at every stage, and refuses to call any output "done" until it has been re-read and checked by its own verification code. Every format is read *and written* by xVerter's own pure-Python code (one exception: CHD delegates to MAME's `chdman`) — there is no toolchain to assemble.

![the xVerter TUI mid-conversion](docs/tui.svg)

## Quick start

**The zero-setup way — one standalone file per platform** (from the release page; Python included, nothing to install):

| Platform | File | Then |
|----------|------|------|
| Windows | `xverter.exe` | double-click it — the program opens |
| Linux x86_64 | `xverter-linux-x86_64` | `chmod +x` it once, run it in any terminal |
| Linux ARM64 (Raspberry Pi etc.) | `xverter-linux-arm64` | same — works headless over SSH, mouse included |
| macOS (Apple Silicon) | `xverter-macos-arm64` | same |

Launching with no arguments opens the TUI on the current folder. Testing status, stated honestly: the Windows and Linux x86_64 binaries are click-tested (real conversions driven through the TUI); the ARM64 binary is tested on a Raspberry Pi 5 (TUI renders, conversions verified); the macOS binary is built by CI from the identical code and recipe but **untested — it *should* work**, and a report either way earns you a place in the changelog. (Linux file managers refuse to run terminal programs by double-click — that's a desktop-environment policy, not an xverter quirk; the TUI's Setup tab can install an app-menu launcher entry if you want one.)

**The pip way**, if you'd rather have it as a command:

```
pip install xverter        # or: pipx install xverter
xverter                    # bare = TUI, or:
xverter convert "Some Game.iso" -o "Some Game.zar"
```

No compilers, no external tools — the converters are pure Python, and the few Python packages they use install automatically. From a clone of this repo, `pip install .` gives you the same command.

```
xverter info    <anything>                 # what is this? (magic bytes, never extensions)
xverter verify  <anything>                 # hash trees, structure, redump authentication
xverter convert <anything> -o out.zar      # or out.iso, out.god, outdir/
```

## The matrix

| from \ to              | dir | `.iso`   | `.zar` | `.god` | `.cci`   | `.cso`   | `.chd`   |
| ---------------------- |:---:|:--------:|:------:|:------:|:--------:|:--------:|:--------:|
| **GoD**                | ✅   | ✅ direct | ✅      | —      | ✅ direct | ✅ direct | ✅ direct |
| **ISO**                | ✅   | —        | ✅      | ✅      | ✅ direct | ✅ direct | ✅ direct |
| **ZAR**                | ✅   | ✅        | —      | ✅      | ✅        | ✅        | ✅        |
| **STFS** (XBLA/DLC/TU) | ✅   | ✅*       | ✅      | ✅*     | ✅*       | ✅*       | ✅*       |
| **CCI**                | ✅   | ✅        | ✅      | ✅      | —        | ✅ direct | ✅ direct |
| **CSO**                | ✅   | ✅        | ✅      | ✅      | ✅ direct | —        | ✅ direct |
| **CHD**                | ✅   | ✅ direct | ✅      | ✅      | ✅        | ✅        | —        |
| **dir**                | —   | ✅        | ✅      | ✅      | ✅        | ✅        | ✅        |

**CCI** (Cerbios) and **CSO** (Project Stellar) are the compressed playable formats of the modded original-Xbox hardware scene — block-compressed ISO wrappers, LZ4 throughout. xVerter's writers are **byte-identical to the reference implementations** (Repackinator for CCI, MakeMHz's stellar-cso for CSO), so their output inherits the hardware validation those tools have earned; cross-reads with Repackinator pass in both directions. The wrappers are content-agnostic: yes, you can put an Xbox 360 game inside a CSO that only original-Xbox mod hardware could ever read. Exhibit two in the cursed-but-supported collection. Reading CCI/CSO needs nothing; writing them uses the `lz4` package, which installs with xverter automatically.

**CHD** (MAME's Compressed Hunks of Data) is here as a deliberate bet on the near future. No released Xbox emulator reads it *yet* — xemu had working, community-tested CHD support in review ([PR #2921](https://github.com/xemu-project/xemu/pull/2921), libchdr-based, validated on redump and trimmed images alike) before the author deleted their fork and orphaned the patch. The demand threads go back years. xVerter delegates to `chdman` itself (MAME's reference tool, the same `createdvd` pipeline the PS1/PS2/Dreamcast world runs on), verifies every build by full round-trip against the source, and cross-checks the CHD header's internal SHA-1s — so the day an emulator merges support, your library is already there. Consider this a nudge, xemu.

**Archives are first-class citizens, both directions.** Games travel the internet in `.zip` and `.7z`, so xverter takes them straight: hand any conversion an archive and it extracts it, finds the game inside (announcing what it found), and carries on — `Halo 3.7z → .zar` is one command. As *output*, `.zip`/`.7z` targets wrap your input exactly as it is (no format change smuggled in; convert first if you want the payload converted). ZIP output is canonicalized — sorted entries, fixed timestamps, deterministic — and round-trip verified; 7z is CRC-verified. RAR is deliberately absent: no free native implementation exists anywhere, and xverter doesn't take binary dependencies for it.

Everything routes through a common pivot (the extracted game directory), so every cell is two verified hops at most.

\* Yes, you can turn an XBLA arcade title into a disc image or a Games-on-Demand container. You probably shouldn't. The tool converts; you decide.

**Original Xbox works too, at the same standard.** XDVDFS is the same filesystem on both consoles, so OG Xbox games flow through every edge of the matrix — including GoD output, which correctly produces Xbox Originals containers (content type `0x5000`, the 360's backward-compat install format). The full matrix has been validated on a real XGD1 redump (Halo: Combat Evolved) alongside the 360 runs. One expectation to set straight: **repacking an OG game as GoD/zar does not make it playable on a 360 emulator.** Real 360s play OG games through Microsoft's own built-in emulator (which supported only ~460 titles); Xenia/XenDroid don't implement that layer. GoD `0x5000` output is for real modded 360 hardware — for OG emulation, use xemu with plain xiso ISOs, which this tool happily produces.

**Two deliberate exclusions, stated rather than hidden:** **FATX** (the filesystem inside console hard drives and Xemu's qcow2 HDD images — a storage medium, not a distribution format) and **STFS as *output*.** Rebuilt LIVE packages only matter to modded consoles filling a `Content` folder — emulators are happier with every other format here — and a writer held to this project's verification standard (hash-chain-validated structure, round-trip content equality, a real consumer booting the result) isn't built yet. Shipping it half-checked would be the one thing this tool never does. Note the signature honesty applies across the board: LIVE/PIRS signatures are Microsoft-private-key RSA, so *every* tool that writes these container families — including iso2god, whose GoD output the whole scene runs on — ships junk signature bytes that modded consoles and emulators simply don't check.

## The validation record — three generations of Halo, one hash each

The release gate is a real-media test roster spanning every disc structure Microsoft pressed, all one franchise: full 48-edge matrices, every edge content-verified, on genuine Redump-authenticated dumps. Three numbers per game tell the whole story:

- **Source SHA-1** — the whole input file; matches Redump's canonical dump.
- **Content digest** — a canonical SHA-1 over every file's path + hash inside the game. This is the *format-invariant* fingerprint: identical across all seven formats, immune to compressor versions and container layout. It even survived xVerter's own writers being replaced wholesale — the digest below for Anniversary is byte-for-byte the one measured back when output ran through delegated third-party tools.
- **Decoded-stream SHA-1** — the raw ISO byte stream, identical across `iso`, `cci`, `cso`, `chd`, and GoD for the same build (zar and dir are file-trees, covered by the digest).

| Title                 | Structure          | Source SHA-1                               | Content digest                                         | Stream SHA-1 (iso = cci = cso = chd = god) |
| --------------------- | ------------------ | ------------------------------------------ | ------------------------------------------------------ | ------------------------------------------ |
| Halo: Combat Evolved  | XGD1 (full redump) | `07326d842e324b35cbd53d4e279aa36199d736a3` | `d16b49c60fb920ea9fed4a0fcec6df74be693c12` (50 files)  | `88fce0f215b7b03e58445defa93a5da4f9b0e742` |
| Halo 3                | XGD2 (full redump) | `09b5e4354e62b9547a7776cb1be42010fb7b5208` | `bbbf380233b15fcb2ae8b5a70d8b88f01b735d0a` (167 files) | `c1343f6915e8d7e06bbd989169a08b7cf56fc54a` |
| Halo: CE Anniversary  | XGD3 (full redump) | `2994534528e086c574e2223f2bc5c175075b9c89` | `bd84d86bfa51c755629fd99864ef46ec47533ede` (448 files) | `99e3c0e330e6ebd05f78ace21a69ec42f37093b0` |
| Halo: Spartan Assault | XBLA (LIVE/STFS)   | `159ec0269bb3a6f10ba3a6d819e554b341ff0163` | `653f5d1ccd8e7c14a8c02ffcda59197f259c4680` (906 files) | `97869f3322450a7235328ab213a30b0591809482` |

One franchise, every disc structure Microsoft ever pressed, plus the download-era container — 48/48 edges each. Every number above is reproducible on your own copy with `xverter test` — the run report each release publishes is generated by exactly that command.

## Benchmarks

Test machine: AMD Ryzen 9 7900X (12c/24t), 64GB DDR5, Samsung 990 PRO NVMe, CachyOS Linux, Python 3.14. **Every conversion time includes full verification** (round-trip hash checks are not optional in these numbers). Seconds:

| Conversion              | Spartan Assault (2.3GB) | Halo CE (7.3GB) | Halo 3 (7.8GB) | Anniversary (8.7GB) |
| ----------------------- | -----------------------:| ---------------:| --------------:| -------------------:|
| dir → iso               | 3.1                     | 4.5             | 7.7            | 10.3                |
| dir → zar               | 17.2                    | 10.5            | 25.2           | 34.1                |
| iso → god               | 3.3                     | 5.1             | 8.4            | 10.9                |
| iso → cci               | 11.0                    | 15.1            | 26.5           | 34.5                |
| iso → cso               | 11.4                    | 14.8            | 26.4           | 34.2                |
| iso → chd               | 56.1                    | 48.0            | 84.0           | 123.9               |
| **full 48-edge matrix** | **5m49s**               | **5m55s**       | **10m47s**     | **14m48s**          |

Compression, as a fraction of the raw ISO (content-dependent — Anniversary's assets are already compressed, Spartan's aren't): CHD 60–90%, ZAR 60–93%, CCI/CSO 70–96%, GoD ~100.5% (its SHA-1 hash tree costs half a percent).

## Attribution — the shoulders this stands on

Every line of code in xverter is original, but none of it would exist without the Xbox preservation community. Two contributions ship inside or alongside the tool and deserve headline billing:

- **[Redump](http://redump.org)** — the disc preservation database, bundled **with [explicit permission](http://forum.redump.org/topic/18562/redistributing-dat-files/)** and refreshed weekly from their official export. Every `verify` verdict rests on their twenty-plus years of volunteer dump verification. (database © its contributors)
- **[MAME / chdman](https://github.com/mamedev/mame)** (BSD-3) — the CHD format and its reference tool, the one external binary xverter invokes (optionally, never bundled).

The rest of the community's work served as **format references and differential-validation counterparts** — the sources xverter learned each format from, and in most cases the established implementations its native writers had to match byte-for-byte before earning the right to replace them: [iso2god-rs](https://github.com/iliazeus/iso2god-rs) (Ilia Pozdnyakov, MIT — GoD; byte-identical), [xdvdfs](https://github.com/antangelo/xdvdfs) (antangelo, MIT — XDVDFS; cross-validated), [ZArchive](https://github.com/Exzap/ZArchive) (Exzap, MIT-0 — the `.zar` format itself; byte-identical), [stellar-cso](https://github.com/MakeMHz/stellar-cso) (MakeMHz, BSD-3 — CSO; byte-identical), [Repackinator](https://github.com/Team-Resurgent/Repackinator) (Team Resurgent, GPL-3 — CCI; byte-identical, format facts only), [XBLA-Extract](https://github.com/ryzendew/XBLA-Extract)/extract360.py/wxPirs (Corey Clark, Rene Ladan, gael360 — STFS reader heritage before the from-scratch rewrite), [god2iso](https://github.com/raburton/god2iso) (raburton), [extract-xiso](https://github.com/XboxDev/extract-xiso) (XboxDev), [maxcso](https://github.com/unknownbrackets/maxcso) (Unknown W. Brackets), and [free60](https://free60.org)'s documentation.

### Bundled libraries

The standalone binaries (and pip installs) redistribute the Python packages xverter runs on, unmodified, straight from PyPI: [Textual](https://github.com/Textualize/textual) (MIT — the TUI framework), [python-lz4](https://github.com/python-lz4/python-lz4) (BSD-3 — CCI/CSO compression), [py7zr](https://github.com/miurahr/py7zr) and its codec companions pyppmd/pybcj/inflate64/multivolumefile (LGPL-2.1 — 7z support; used unmodified and replaceable by installing xverter from pip, per the license's intent) with pyzstd/brotli/pycryptodomex (BSD/MIT), and [zstandard](https://github.com/indygreg/python-zstandard) (BSD-3 — zar on Python < 3.14). ZIP support is the Python standard library. The binaries themselves are assembled with [PyInstaller](https://pyinstaller.org) (GPL with runtime exception — the exception exists precisely so bundled applications stay under their own license).

### A particular thank-you to the Redump community

Redump is not a download — it is twenty-plus years of volunteers buying region variants of discs nobody else cared about, dumping them on carefully characterized drives, and refusing to mark anything verified until independent dumps agreed. Every time `xverter verify` says "this is the canonical dump," that certainty was manufactured by those people, disc by disc, for free, forever. If xverter is useful to you, [their forum](https://forum.redump.info) is where thanks (and undumped discs) belong.

If you build on xverter, please carry these credits forward — most of this knowledge was won by hobbyists two decades ago and survives only because people keep attributing it.

## What "verified" means

- **GoD reading** walks the container's complete SHA-1 hash tree — header self-hash, the header-sealed master table, the backwards master-table chain across part files, every sub-table, every 4 KB data block. A typical game is ~900,000 verified blocks. No other GoD tool checks any of this (we audited them). It caught a silently truncated container in the wild that booted fine and would have crashed mid-game.
- **ISO reading** resolves every file extent against the actual image and fails naming the exact file and missing byte count on truncation.
- **Every built output is re-read by the corresponding reader** before success — as cheaply as each format allows: built GoD containers get the full hash-tree walk (single pass; the format carries its own hashes), built ISOs are stream-hashed in place against a source manifest (nothing written, nothing re-extracted), and packed zars are stream-hashed in place by the native reader against the source manifest (the archive's embedded SHA-256 is checked by `verify`). Input verification costs nothing extra: it happens inline during reading.
- **`--no-verify` exists for when you've earned it**: once the tool has a track record on your library, skipping output verification roughly halves conversion I/O. The default stays paranoid, because that's the point.
- **`verify` authenticates ISOs against redump — fully offline out of the box**: the tool ships with redump's Xbox **and** Xbox 360 DATs bundled (refreshed weekly by CI from redump's official database export — bundling is [explicitly permitted by redump's admin](http://forum.redump.org/topic/18562/redistributing-dat-files/)); `verify` matches computed CRC-32/SHA-1 against it locally. `xverter dat update` fetches a fresher copy to your cache; `--dat <file>` uses your own; `--no-lookup` skips authentication. Resolution order: `--dat` → user cache → bundled → single online lookup.

## CLI reference

```
xverter                                    # no arguments: open the TUI here
xverter tui [DIR]                          # TUI on a specific library folder
xverter info    <input>                    # identify anything: magic bytes, never extensions
xverter verify  <input>                    # integrity + redump authentication
xverter convert <input> -o <output>        # any format in, any format out
xverter test    <game>                     # full conversion-matrix self-test + HTML report
xverter dat     update|status              # manage the bundled/cached redump database
```

`convert` options:

| Flag | Effect |
|------|--------|
| `-o PATH` | output — extension picks the format: `.iso` `.zar` `.god` `.cci` `.cso` `.chd` `.zip` `.7z`, or a trailing `/` for an extracted folder |
| `--no-verify` | skip output round-trip verification (halves I/O once the tool has earned your trust) |
| `--split` | split `.cci`/`.cso` at 4GiB for console FATX storage (default: one file) |
| `--scratch ram` | keep pivot files in a tmpfs — Linux, needs ~2.2× game size *available* |
| `--workdir DIR` | put pivot files somewhere specific (overrides `--scratch`) |
| `--progress` | machine-readable `PROGRESS` lines on stderr (a tty gets human percentages automatically) |

`verify` options: `--deep` (read every byte, not just structure), `--dat FILE` (your own Logiqx DAT), `--no-lookup` (skip redump authentication), `--progress`. `test` takes `--workdir DIR` for its scratch (default: temp dir next to the game, cleaned up after). `dat update` refreshes the cached redump database (`--system xbox360|xbox`); `dat status` shows what's bundled and cached.

## Progress you can actually see

Nothing in xverter runs silently. Every stage of every operation reports live progress — extraction, ISO/GoD/zar building, CCI/CSO compression, CHD both directions, archive packing and unpacking, and (the part most tools skip) every *verification* pass, because a two-minute silent hash check looks exactly like a hang:

- **In a terminal**: an automatic in-place percent readout per stage, no flags needed.
- **In the TUI**: a stage-labeled progress bar on the Convert tab; the Test tab shows two — matrix edges completed plus a live bar for whatever the current edge is doing inside.
- **For scripts**: `--progress` on `convert`/`verify` emits machine-readable `PROGRESS <stage> <done> <total>` lines on stderr.

## The suite, or the parts

`xverter` is one integrated tool, but every format implementation stands alone — installable entry points with no knowledge of each other, for scripts that only need one job done:

| Tool           | Does                                                                                                                                                                                    | Example                                    |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| `god2iso`      | GoD container → ISO with full hash-tree verification; `--verify-only` = integrity check                                                                                                 | `god2iso <header-file> game.iso`           |
| `xiso-extract` | XDVDFS image → files (bare partitions and full XGD1/2/3 images, both consoles)                                                                                                          | `xiso-extract game.iso outdir/`            |
| `zar-read`     | Pure-Python ZArchive tool: list / extract / hash / verify / **pack** — no reference binary, any Python ≥ 3.9 (stdlib zstd on 3.14+, the `zstandard` package otherwise) | `zar-read pack game.zar gamedir/`          |
| `stfs-extract` | LIVE/CON/PIRS content packages: list / extract / title                                                                                                                                  | `stfs-extract extract package.bin outdir/` |
| `cci-convert`  | Cerbios CCI: info / unpack / pack (byte-identical to Repackinator output)                                                                                                               | `cci-convert pack game.iso game.cci`       |
| `cso-convert`  | Stellar CSO: info / unpack / pack (byte-identical to stellar-cso output)                                                                                                                | `cso-convert unpack game.1.cso game.iso`   |

Each is also importable (`from xverter.formats import god, xdvdfs, zar_native, stfs`) with a library API — the CLI entry points are thin wrappers over the same functions the suite uses.

## Validate this tool yourself

Don't take the README's word for any of it — the validation harness ships *inside* the program. `xverter test` runs one game of yours through **every edge of the conversion matrix**, checking two things at every hop: the pipeline's own built-in verification, and byte-level content equality against a baseline manifest of the original. Any format in:

```
xverter test "Some Game.zar"
```

(Or select a game in the TUI, open the Test tab, and click "Run full matrix test" to watch the edges stream by.) Every container round-trips through extraction with hashes diffed against the baseline, every artifact kind gets a `verify` pass, and the run ends by writing a single self-contained `<game>_matrix_report.html` next to your game: verdict, per-edge timings, artifact sizes and compression ratios, decoded-stream SHA-1s, tool versions — with the complete machine-readable JSON embedded inside the page. Expected final lines:

```
48 edges, 0 failed
MATRIX: ALL PASS
```

Anything less is a bug: file an issue with the report attached. This is the exact harness used for the release validation runs on real XGD1, XGD2, and XGD3 redumps — and it narrates itself: per-edge results stream live with within-edge progress (`chdman` is the one optional binary, needed only for the CHD edges, which are skipped cleanly without it). Budget scratch space of ~4–5× the game's size (`--workdir` relocates it).

## TUI

```
xverter tui /path/to/library    # or just `xverter` for the current folder
```

A terminal UI over the same verified machinery, fully mouse-driven — no hotkeys to memorize, identical on Linux, Windows, and macOS terminals, and fully usable over SSH (your terminal forwards mouse clicks, so it drives fine on a headless server or a Pi). Three tabs:

- **Convert** — browse the library like a file manager: single click selects (details appear, magic-detected), double click enters a folder, the `..` row goes back up. Click the button for the output you want (ISO, ZAR, GoD, CCI, CSO, CHD, 7z, ZIP, or extracted folder), flip the RAM-scratch / 4GiB-split switches as needed, and watch the stage-labeled progress bar and log. **Batch mode**: press spacebar to mark any number of games (a ● appears), then click one format button — they process alphabetically under two bars, overall batch progress plus the current game's stage, with per-game results in the log. Mixed input formats in one batch are fine (each member is detected independently); members that aren't recognizable games, are already in the target format, or already have their output are *skipped*, never failed, and the final summary counts OK / skipped / failed honestly. The header shows the running version, the log's first line stamps it plus (for standalone binaries) the build date, and on launch xverter quietly checks GitHub for a newer release — if one exists you get one log line with the link, and nothing ever nags beyond that.
- **Setup** — checks the one optional binary (`chdman`) with an install hint, and on Linux offers one-click **Install**/**Remove** of an app-menu launcher entry.
- **Test** — runs the full validation matrix against the selected game, edges streaming live under two progress bars, report saved next to the game.

Everything runs as background workers invoking the exact CLI code paths, so the TUI carries the same verification guarantees as the command line. Launching `xverter` with no arguments opens the TUI on the current directory.

## Install

Three ways, pick one:

1. **Standalone binary** (see Quick start): one file, Python inside, every release builds them for Windows, Linux x86_64/ARM64, and macOS on real hardware via CI.
2. **`pip install xverter`** / `pipx install xverter` — the `xverter` command plus the standalone tools (`god2iso`, `zar-read`, ...).
3. **From a clone**: `pip install .`

**xVerter has no required external tools.** Every reader and every writer is its own code — ISO, GoD, ZAR, CCI, CSO, STFS, ZIP: native, pure Python, nothing to hunt down. `pip install` brings the four Python packages it runs on (`textual` for the TUI, `lz4` for CCI/CSO compression, `py7zr` for 7z, and `zstandard` only on Python < 3.14, where zstd isn't in the stdlib yet — the marker handles it, you don't). One binary exists in the picture at all, and it's opt-in: install it only if you want CHD.

| Binary   | Needed for    | Source                                                                                                      |
| -------- | ------------- | ----------------------------------------------------------------------------------------------------------- |
| `chdman` | `.chd` in/out | ships with MAME (Arch/Debian: `mame-tools`; macOS: `brew install rom-tools`; Windows: in the MAME download) |

CHD is MAME's format and `chdman` is its living definition — delegating there is a feature. Everywhere else, "no dependencies" was earned the hard way: each native writer was validated against the established implementation before replacing it. The GoD writer's output is **byte-identical to iso2god's** (every data part and the header, zero mask, at equivalent settings). The ZAR writer reproduced a reference-tool archive **byte-for-byte**. The CSO writer is **byte-identical to stellar-cso's**. The ISO writer is cross-read by the incumbent `xdvdfs` tool and accepted by independent consumers — and adds something no other XDVDFS packer offers: **deterministic, reproducible output**. Same input tree, same bytes, every time, on every machine (the layout contract is documented in the module and versioned).

The scene has seen what happens when a project rewrites a writer casually — XGDTool's ZAR output accumulated corruption reports ([#1](https://github.com/wiredopposite/XGDTool/issues/1), [#2](https://github.com/wiredopposite/XGDTool/issues/2)). That's why every xVerter writer ships only after differential validation against the tool it replaces, and why every output is still re-read and verified by xVerter's own readers before success is reported — ours included. Never trust a writer. Especially your own.

### Scratch space (and doing it all in RAM)

Conversions that pivot through an intermediate (e.g. `zar → god`) write temporary files to the system temp dir. Disk scratch is the default and the right choice for most machines. If you have the memory, `--scratch ram` keeps every intermediate byte off your SSD:

```
xverter convert game.zar -o game.god --scratch ram
```

(The TUI has the same toggle as a switch in its options panel.) Read the fine print before flipping it:

- You need roughly **2.2× the game's size in *available* RAM** — available as in what `free` reports, not what's installed. A dual-layer 360 game pivots through ~17GB of scratch, so treat **32GB+ total RAM** as the practical floor for full-size discs; with less, expect "no space left on device" failures that plain disk scratch would not have had. xverter preflights this and warns, but the warning can't know what you'll launch next.
- **Linux only.** `--scratch ram` uses the tmpfs every Linux system already has (`/dev/shm`). Windows and macOS don't ship a RAM-backed filesystem; there, create a RAM drive with a third-party tool (e.g. ImDisk) and point `--workdir` at it — `--workdir DIR` (or `TMPDIR`) always wins over `--scratch`.
- The speed win is smaller than you'd hope: the OS page cache already serves hot rereads of disk scratch from memory. RAM scratch is mostly about SSD write wear (a big conversion churns tens of ephemeral gigabytes), not throughput.

### 4GiB splitting

`.cci`/`.cso` outputs are written as one file regardless of size — if you want a single 7GB CSO for your PC emulator, that's exactly what you get. If the destination is a *console's* storage, pass `--split` (a switch in the TUI): FATX caps files at 4GiB, so console-side loaders expect big images as `Name.1.cci` + `Name.2.cci` slices, and that's the convention `--split` produces (byte-identical to Repackinator's). Every reader in xverter accepts both shapes and resolves `Game.cci` to its slice set automatically.

GoD needs no such setting — the format is natively multi-part (its `Data####` chunks are ~170MB each). ZArchive has no split convention at all: no emulator reads a multi-part `.zar`, so xverter won't invent one. If you need to move a >4GiB zar across a FAT32 stick, `split -b 4G` / `cat` (or any archiver's volume feature) is the honest tool for that job.

## Format notes (hard-won, documented so you don't have to)

- **GoD layout**: 4 KB blocks; each `DataNNNN` part = `[master hash table]` + up to 203 × `[sub-table][≤204 data blocks]`; the master-table chain runs *backwards* (part N carries the hash of part N+1's table) and the CON/LIVE header seals part 0's table at `0x37D`. Part count at `0x3A0` is the format's one little-endian field (iso2god-rs marks it `// sic!`).
- **The GoD trim quirk**: `iso2god --trim` shrinks the part *count* while parts fill to capacity, so `blocks_allocated` in the header routinely undercounts the blocks present. The surplus tail is benign, hash-covered padding — warned about, not failed.
- **The embedded GoD stream is a bare game partition** (`MICROSOFT*XBOX*MEDIA` at `0x10000`), which is also what `xdvdfs pack` builds — XGD2 and XGD3 games both reduce to it.
- **Full redump images** carry the game partition at an offset: XGD1 `0x18300000`, XGD2 `0xFD90000`, XGD3 `0x2080000` (constants cross-confirmed in iso2god-rs, extract-xiso, and abgx360). Detection probes all of them. Validation status: **every disc generation verified against real, DAT-authenticated media with the native writers** — see the validation record above.
- **ZArchive is a footer format** — the magic `16 9F 52 D6` lives in the file's final bytes; the file *starts* with zstd frames. Extension-based "detection" would be guessing; footer probing isn't.
- **STFS entries** live in a 64-byte-record file table; SHA-1 hash tables interleave with the data blocks (one per 170, higher levels above), and the volume descriptor seals the chain's root — which is why xverter can verify every allocated block against the package's own math. XBLA titles are `000D0000` content, DLC `00000002`, title updates `000B0000` — all the same container.
- **iso2god's trim bug (through v1.8.1)**: its trim bound is the last *file* extent only — an image whose root directory table sits past its last file gets silently truncated into an unreadable container, exit code 0. Found by this project's matrix; xverter's native GoD writer trims to the true allocation extent (descriptor + every table + every file) by construction.
- **The XDVDFS tree comparator is ASCII-*uppercase* fold** — real Microsoft-mastered images contain adjacent name pairs that only sort correctly under uppercase folding (`_` between the cases). Lowercase folding, the obvious guess, misorders three pairs across four reference images.
- **XDVDFS cannot hold a >4GiB file** (dirent sizes are u32) — which is why CCI/CSO splitting exists for consoles and why no real game ships one (Halo 3's largest file is a 542MB map).
- **Case-insensitivity is load-bearing**: real discs ship `default.xex`, `DEFAULT.XEX`, and `Default.xex`. Anything matching case-sensitively will eventually lie to you.

## License

MIT — see [LICENSE](LICENSE). Every line of code in this repository is original xVerter work (the projects it learned from are credited in the Attribution section); the bundled Redump DAT remains the Redump community's work.
