
Patch Wars: Enhanced JSON Patching
Library for modders to have greater control over JSON patches
Description
Features
Prepatches
Patches found inside the prepatches folder of a mod's assets will run before any regular patches are processed, guaranteeing the ability to patch standard patches before they have run.
Postpatches
Patches found inside the postpatches folder of a mod's assets will run after all prepatches and patches are processed.
JPath Queries
Adds the ability to use Newtonsoft's JPath queries to define more expressive and dynamic patches. This feature is available for use in patches found in patches, prepatches, and postpatches.
Use
To utilize JPath queries, place your query inside the path field of your patch.
If you expect and want your patch to apply to multiple elements in the target file, be sure to add "patchMultiple": true to your patch.
When performing an add or addeach patch operation using JPath queries, because the element being added does not exist yet and would cause the query to fail, it must be left out of the path definition. Instead, add the new element name (or index) to pathAppend. The string found in pathAppend will be added to the end of the pointers found by your JPath query before patching the target file. pathAppend does not support JPath and must be in vanilla's standard JsonPointer notation.
Examples
You'd like to mod the panning loot table so that temporal gears are far more common from both sand/gravel and bony soil. (Excerpt from pan.json as of Vintage Story v1.18.0)
{ <span class="hljs-attr">"code"</span>: <span class="hljs-string">"pan"</span>, <span class="hljs-attr">"attributes"</span>: { <span class="hljs-attr">"panningDrops"</span>: { <span class="hljs-attr">"@(bonysoil|bonysoil-.)"</span>: [ // ... <span class="hljs-number">17</span> other items not shown { <span class="hljs-attr">"type"</span>: <span class="hljs-string">"item"</span>, <span class="hljs-attr">"code"</span>: <span class="hljs-string">"gear-temporal"</span>, <span class="hljs-attr">"chance"</span>: { <span class="hljs-attr">"avg"</span>: <span class="hljs-number">0.001</span>, <span class="hljs-attr">"var"</span>: <span class="hljs-number">0</span> } }, // ... ], <span class="hljs-attr">"@(sand|gravel)-."</span>: [ // ... <span class="hljs-number">19</span> other items not shown { <span class="hljs-attr">"type"</span>: <span class="hljs-string">"item"</span>, <span class="hljs-attr">"code"</span>: <span class="hljs-string">"gear-temporal"</span>, <span class="hljs-attr">"chance"</span>: { <span class="hljs-attr">"avg"</span>: <span class="hljs-number">0.0005</span>, <span class="hljs-attr">"var"</span>: <span class="hljs-number">0</span> } }, // ... ] } } } </pre> If you were to write a patch file for this in the vanilla patching system (or use modmaker.exe), your patch file would look like this:
<pre>[ { <span class="hljs-attr">"op"</span>: <span class="hljs-string">"replace"</span>, <span class="hljs-attr">"path"</span>: <span class="hljs-string">"/attributes/panningDrops/@(bonysoil|bonysoil-.)/17/chance/avg"</span>, <span class="hljs-attr">"value"</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">"file"</span>: <span class="hljs-string">"game:blocktypes/wood/pan.json"</span>, <span class="hljs-attr">"side"</span>: <span class="hljs-string">"Server"</span> }, { <span class="hljs-attr">"op"</span>: <span class="hljs-string">"replace"</span>, <span class="hljs-attr">"path"</span>: <span class="hljs-string">"/attributes/panningDrops/@(sand|gravel)-./19/chance/avg"</span>, <span class="hljs-attr">"value"</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">"file"</span>: <span class="hljs-string">"game:blocktypes/wood/pan.json"</span>, <span class="hljs-attr">"side"</span>: <span class="hljs-string">"Server"</span> } ] </pre> These patches are brittle to any changes to the drop tables in vanilla as well as from other mods due to the array indexes shifting from additions and deletions. Also, you and anyone reading your patch have no idea which item in the drop table is being changed without referencing pan.json.
Using a JPath query instead, your patch might look like this:
<pre>[ { <span class="hljs-attr">"op"</span>: <span class="hljs-string">"replace"</span>, <span class="hljs-attr">"path"</span>: <span class="hljs-string">"$.attributes.panningDrops.*..[?(@..code == 'gear-temporal')].chance.avg"</span>, <span class="hljs-attr">"value"</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">"patchMultiple"</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">"file"</span>: <span class="hljs-string">"game:blocktypes/wood/pan.json"</span>, <span class="hljs-attr">"side"</span>: <span class="hljs-string">"Server"</span> } ] </pre>Ratings & reviews
Sign in to leave a rating or comment.

