Back to NxLabs

NxLabs / Vintage Story

P

Patch Wars: Enhanced JSON Patching

JBy JapanHasRice

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)

<pre>{ <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>
Read the full description on Vintage Story ModDB →

Ratings & reviews

No ratings yet

Sign in to leave a rating or comment.