BPS vs IPS, UPS, xdelta and PPF: ROM patch formats compared
ROM patch formats differ in checksums, size limits, and compatible patchers. BPS is a strong cartridge default; IPS, UPS, xdelta, and PPF serve different release needs.
Applying a patch? Use the format you received
An existing patch's format is already chosen, though Create can convert it when you have the clean ROM. The format table lists what rom-weaver can apply and create.
Converting a patch does not fix a source checksum mismatch. The mismatch concerns the starting bytes, not the patch format. Fix a checksum error gives the procedure.
This guide is for people publishing a patch.
What separates patch formats?
Every format on this page records the same thing: which bytes changed. What separates them is how much they know about the file you are supposed to start from.
Some store a checksum of the original inside the patch. When a user feeds in the wrong file, the patcher stops and says so. Others have no source checks, so the patcher can apply changes to the wrong ROM without detecting the mistake.
That difference decides most of your choice. For cartridge releases, built-in validation helps users detect a wrong starting file. Disc-sized files make patch size and tool support more important.
| Format | Built-in validation | Size and layout limits | Compatibility and common use |
|---|---|---|---|
| BPS | CRC32 for source, output, and patch | Variable-length sizes and offsets; creator memory limits still apply | Cartridge releases with a BPS-compatible patcher |
| IPS / IPS32 | No source, output, or patch checksum | IPS record starts use 24-bit offsets, below 16 MiB; IPS32 uses 32-bit offsets | IPS for older patchers; IPS32 requires explicit tool support |
| UPS | CRC32 for source, output, and patch | Variable-length sizes and offsets, without IPS's 24-bit boundary | Releases whose community tools expect UPS |
| xdelta / VCDIFF | Checks vary by encoder and options; output-window checks are not a whole-source checksum | Windowed encoding supports large files; decoder limits and extensions vary | Large binaries and disc images with compatible VCDIFF tools |
| PPF | PPF1 has no source check; PPF2 checks size and a sample block; PPF3 can check a sample block | PPF1/2 use 32-bit offsets; PPF3 uses 64-bit offsets; exact disc layout matters | Disc releases using PPF-compatible tools |
These are format differences, not promises about every patcher's limits or validation settings. A sample block cannot prove that the whole source file matches. The implementation references document the parsers and external format sources.
No format records every human requirement. Region, revision, header state, patch order, and expected checksums still need clear release notes.
BPS
BPS stores a checksum of the original, of the finished file, and of the patch itself. A patcher can therefore reject the wrong starting file, and confirm the result came out right.
That makes it a strong default for cartridge games when your audience has a BPS-compatible patcher. rom-weaver applies and creates BPS; to publish one, see the browser or CLI create guide.
IPS and IPS32
IPS is widely supported by older patchers. Its records write bytes at fixed offsets, and it can also specify a final file size. It stores no checksum of the original, so an IPS patcher cannot confirm it was handed the right starting file. rom-weaver reads the record layout for hints (see How rom-weaver picks a patch's bytes), but hints are not proof.
IPS favors compatibility with old tools over built-in error detection. Published source checksums can fill that information gap.
IPS also has a hard limit built into its 24-bit offsets: it cannot encode a change that starts at or beyond 16 MiB. Create stops offering IPS when either input reaches that boundary. IPS32 widens the offsets so larger files work. rom-weaver applies and creates both.
UPS
UPS stores CRC32 checksums of the input, output, and patch itself. Like BPS, it can detect a wrong starting file and a damaged patch.
UPS remains useful in communities whose tools expect it. rom-weaver applies and creates it.
xdelta and VCDIFF
VCDIFF is a general-purpose format for describing the difference between any two files. xdelta is the widely used tool built around it, and its name is what most people say.
It handles large binaries and disc images well, which is why disc projects reach for it. Patches turn up as .xdelta, .delta, .dat, and .vcdiff.
An xdelta patch's checks depend on its encoder and options. Optional output-window checks do not identify the entire original file. Separate published source and output checksums remove that uncertainty. rom-weaver applies and creates xdelta and VCDIFF.
PPF
PPF was designed for disc patching and remains in use. PPF1 lacks source validation; PPF2 checks source size and a sample block. PPF3 supports optional block checking, 64-bit offsets, and undo data. These block checks are not whole-file checksums.
Disc layouts add another source of mismatch. A .bin or .iso extension does not identify the track layout, image format, or dump. Those differences change the bytes a patch expects.
rom-weaver applies and creates PPF.
Other supported formats
Less common formats often reflect one platform's tools or a specialized workflow, such as Dreamcast DCP. Apply support and creation support can differ.
The full format table is the authoritative list of names, extensions, and what rom-weaver can currently apply and create. The browser Apply guide covers the byte-level formats and single-file HDiffPatch requirements. Dreamcast DCP needs the CLI disc-sheet workflow.
How rom-weaver picks a patch's bytes
Some dumps contain a copier header before the ROM data. Others, especially Nintendo 64 dumps, store the same data in different byte orders. A patch needs the form its author used.
rom-weaver first compares the available expected checksums against supported variants. Explicit checks and a weave's input checks for its first patch take precedence over a patch's own source checks. A weave's expected-ROM checks describe the file as supplied, so rom-weaver compares them with that file unchanged, and a match on the file as supplied does not choose a layout. A weave can be recorded from another dump of the same game, so the CLI also accepts a match on the file's header-stripped form or another N64 byte order. When only such a form matches, that form chooses the layout only if the patch gives no clue of its own: no checksum or declared-check evidence, and no decisive structural evidence such as record geometry, the ROM-header tiebreak, or the N64 boot-checksum tiebreak. It takes the place of keeping the file unchanged. weave create does not apply patches, but on the ROM the weave was recorded from, the patch can only meet headerless bytes or that byte order, which makes that form the better guess when nothing else decides. File size alone can distinguish two candidate layouts, but cannot identify a ROM.
For the first patch, missing checksum evidence can trigger inference from patch records, validation failures, and the resulting platform header. N64 inference can also use a rewritten boot checksum. These are fallbacks, not checksum proof. Later chain steps use checksum evidence rather than repeating first-patch inference.
When the evidence cannot distinguish candidates, rom-weaver keeps the existing form. A reported inference still needs checking against the author's expected result. Publishing source and output checksums removes that uncertainty.
The architecture guide records the decision rules and implementation paths. Fix a checksum error covers what to check in the browser.
Interleaved Genesis dumps are not a header question
A Genesis .smd dump also opens with 512 bytes, and it is tempting to treat those as one more removable header. They are not. Behind them the ROM is stored in 16 KiB blocks with each block's odd bytes written first and its even bytes second, so removing the 512 bytes leaves interleaved data rather than a shorter ROM. There is no offset a patch could be shifted by to fit it.
rom-weaver therefore does not offer a headerless form behind an .smd header. It recognises the dump for what it is and leaves it alone, which also stops a misnamed .smd from being read as a copier-headered SNES ROM - every .smd file happens to have exactly the size a copier-headered dump has.
Which format should I choose?
- Applying somebody's patch: the format they gave you, with the exact file they documented.
- Publishing for a cartridge game: BPS, for the checksums it carries.
- Publishing where old patchers must work: IPS, with checksums in your release notes.
- Publishing for a disc or a very large file: xdelta/VCDIFF or PPF, or whatever that platform's community already uses.
- Publishing several patches at once: any of the above, plus a rom-weaver weave to record the order, the optional pieces, and the checksums.
Create a patch covers creation and reconstruction checks.