28
patches.json specification
bicarus edited this page 2026-07-19 23:26:19 -07:00

What is this page?

This page is for people writing / developing patches. If you just want to know how to patch your game, see this page instead.

Format for JSON file

The JSON file is an array of patch objects.

Patch object specification

Property Type Description
name String Name of the patch.
description String Patch description which appears in the tooltip. Required, but can be blank.
caution ** String Warning about the patch which appears in a highlighted tooltip.
gameCode String Gamecode. For instance; ABC in ABC-001-2024042700.
type String See Memory, union, and Signature patch properties.
peIdentifier* String Identifier for main game module. See the PE Identifier section.
preset** Bool Unused. Leave as false or omit.
group String Group ID, if this patch parents up to a group. Optional.

*Optional if the filename is {peIdentifier}.json.

**Optional.

Memory Patch Properties

For "type": "memory", the patch object has an array patches of objects:

Property Type Description
dllName String Name of the module in which the patch is to be applied.
offset Integer Integer representation of the offset at which the patch is to be applied.
dataDisabled String Original data in hex.
dataEnabled String Patch data in hex.

Union Patch Properties

For "type": "union", the patch object has an array patches of objects:

Property Type Description
name String Name of the patch option.
patch Object See below.

patch object properties:

Note

For union type, all patches in the patches array must have the same dllName, offset, and length of data.

Property Type Description
dllName String Name of the module in which the patch is to be applied.
offset Integer Integer representation of the offset at which the patch is to be applied.
data String Patch data in hexadecimal.

Signature Patch Properties

For "type": "signature", the patch object has the following extra properties:

Property Type Description
signature String Signature to match on. String of hex bytes, but with wildcards represented as ?? or XX.
replacement String Replacement bytes. Can also include wildcards as ?? or XX.
dllName String Name of the module in which the patch is to be applied.
offset* Integer Byte offset to start replacing, starting with the beginning of signature match.
usage* Integer Finds the n-th match, 0-based. Omitting this or setting this to 0 means use the first signature match, 1 is second match, and so on.

*Optional.

Number Patch Properties

For "type": "number", the patch object has an object named patch with the following properties:

Property Type Description
dllName String Name of the module in which the patch is to be applied.
offset Integer Integer representation of the offset at which the patch is to be applied.
size Integer Size of patch, in bytes (e.g., 4 for int32). Must be 1, 2, 4, or 8.
min Integer Minimum allowed value for the patch(inclusive)
max Integer Maximum allowed value for the patch(inclusive)

Group Patch Object specification

For "type": "group", these are not actually patches but placeholders for parenting up child patches.

Groups were introduced in this PR, submitted July 2026. Previous versions of spice will see groups as Invalid type and show up as a red row, but can be safely ignored.

Property Type Description
type String Must be "group"
id String Unique group ID.
name String Name of the group.
description String group description which appears in the tooltip. Required, but can be blank.
caution ** String Warning about the group which appears in a highlighted tooltip.
gameCode String Gamecode. For instance; ABC in ABC-001-2024042700.

Header / metadata

Starting with version 24-07-03 -

for the first JSON object in the array, if it does not follow the patch format (i.e., omit the name field), it will be printed in the log. In this object, you can put whatever you want, such as version, time created, date code for the game, etc. See the example JSON file below.

PE Identifier

By default, modules are identified by the following PE headers:

The peIdentifier is then produced by concatinating the 3-character gameCode in uppercase, the TimeDateStamp in lowercase hexadecimal, and the AddressOfEntryPoint in lowercase hexacedimal as follows:

  • {gameCode}-{TimeDateStamp}_{AddressOfEntryPoint}

For instance, if gameCode = LDJ, TimeDateStamp = 0x64EF0FF5, and AddressOfEntryPoint = 0x1037754, then peIdentifier = LDJ-64ef0ff5_1037754.

We use the timestamp and the entry point offset as opposed to a file hash, since files can be pre-patched by other tools, and can have additional sections added (e.g., for translations). We also explicitly do not use the game datecode since that information does not come from the DLL but rather a separate XML file, which is often incorrect on people's setups. The filename of DLLs are not used either to identify contents since there are scenarios where DLLs are renamed (e.g., bm2dx_omni.dll)

Example

URL https://spice2x.github.io/patches/ is available with:

Here is a file with groups:

These patches are shared as a reference for patch developers only. spice2x team will not be maintaining patches.

Troubleshooting issues when developing patches

If patches don't show up, run spice.exe -cfg, open the Patches tab, and check for any error messages in the console.

If patches do show up but with an error, check the rightmost column for error message in the UI.

Getting "config parse error" error code? Check rapidjson error codes here.

Credits

Github user KuuaDev for contributing this documentation.