UE4SS Lua mod for Jujutsu Kaisen: Cursed Clash that merges JSON patches into live UDataTable assets at runtime (and reapplies them periodically so rows stay updated after the game loads tables).
- UE4SS installed for the game.
- This folder as a mod:
ue4ss/Mods/DataTablePatcher/with scripts underScripts/.
- Ensure
_enabled.txtexists in the mod folder (UE4SS uses it to enable mods). - Launch the game once with UE4SS; check the UE4SS console/log for lines prefixed with
[BetterGameplay]to confirm the mod ran.
The mod reads config.json in the mod root (next to Scripts/). If it is missing, the mod creates it with defaults.
| Key | Description |
|---|---|
hotreload |
If true, watches patch JSON files and reapplies when their size or modification time changes (in addition to the periodic scan). |
debug |
If true, prints [BetterGameplay] diagnostics to the UE4SS console/log. |
dataTablesRelativePath |
Path from the mod root to the folder that contains your patch subfolders. Default: ../../../../../Content/DataTables (game Content/DataTables). |
You can start from config.json.example: copy it to config.json and adjust values.
Example:
{
"hotreload": true,
"debug": false,
"dataTablesRelativePath": "../../../../../Content/DataTables"
}Patches are only picked up from one level of subfolders under the data root:
- Valid:
Content/DataTables/MyMod/AttackDataTable1.json - Invalid:
Content/DataTables/AttackDataTable1.json(no subfolder) - Invalid: nested deeper than one subfolder
Use any subfolder name you like (MyMod, Balance, etc.). All *.json files in those subfolders are discovered; multiple files that share the same filename are applied in alphabetical order by full relative path.
The mod will try to create the data root directory if it does not exist (Windows).
The file name (without .json) must match this pattern:
{TableName}DataTable or {TableName}DataTable{Index}
Examples:
| File | Table asset |
|---|---|
AttackDataTable1.json |
/Game/DataTables/AttackDataTable1.AttackDataTable1 |
CharacterDataTable.json |
/Game/DataTables/CharacterDataTable.CharacterDataTable |
ChatTextDataTable_En.json |
/Game/DataTables/ChatTextDataTable_En.ChatTextDataTable_En |
If the name does not contain DataTable in the expected place, the file is skipped with a warning.
The file is a single JSON object. Each key is a row name in the target DataTable. Each value is an object of fields to merge into that row (same shape as the row struct in the engine).
- Existing rows: values are merged into the live row.
- New rows: only for table types configured with
AddRows = trueinScripts/fields.lua(e.g. manyAttack,Character,Itemtables). Otherwise unknown row keys are ignored.
String values are normally written as Lua/native types as appropriate. For Unreal FName columns, the mod uses rules from Scripts/fields.lua and these automatic rules:
- Keys named
ID, starting withId_, or ending withFileNameare treated asFNamewhen they are strings. - Tables listed in
fields.luacan list extra columns or use"*"for “all string leaves at this level” (seeAction).
If a patch fails for one row, errors are printed to the console and counts appear in the apply summary.
After each file apply you should see a line like:
[BetterGameplay] Applied MyMod/AttackDataTable1.json | rows_in_file=N edited=A added=B errors=E
If a table is not loaded yet, you may see table not loaded yet and allOk stays false until a later scan succeeds.
Supported assets and options (AddRows, which fields are FName) are defined in Scripts/fields.lua (TableInjectionConfig). Edit that file if you need another *DataTable* name or different FName handling.
The same script also adjusts animation / time dilation for certain actor name patterns (CP_ / CN_) and LevelSequence play rate. Tune the constants at the top of Scripts/main.lua if you use that behavior; it is unrelated to JSON patching.
Scripts/main.lua— entry point, hooks, patch loop.Scripts/config.lua— loadsconfig.json.Scripts/utils.lua— discovery, merge, apply, optionalPrintDataTableRowshelper.Scripts/fields.lua— per-table patch options.