Patch File Unification
.uasset
using .toml
or .toml.all
The .toml
command merges all patch files in the patches
directory⠀and creates a “unified” TOML patch files.
The unification creates a single patch file for all the merged patch files for each .uasset
, with all data table regular expression and patchlets applied, producing plain TOML patches.
Non-data table .@:
patches are copied as they are, but with their load order embedded in between .@:
and /
or $
to preserve their original sequence of applications.
For example, for the following patches
structure:
where:
-
patches\beta-burst-recovery-scan\EffectTable.toml
:# based on https://www.nexusmods.com/stellarblade/mods/802 [N_Drone_Scan] LifeTime = 30.0 # based on https://www.nexusmods.com/stellarblade/mods/897 ['.*: ^P_Eve_SkillTree_Just(.*BetaGauge|.*BurstGauge).*$'] CalculationMultipleValue = '''=> v.objName match { case "P_Eve_SkillTree_JustParry_BetaGauge1" => 8 case "P_Eve_SkillTree_JustParry_BetaGauge2" => 6 case "P_Eve_SkillTree_JustEvade_BurstGauge1" => 4 case "P_Eve_SkillTree_JustEvade_BurstGauge2" => 3 }''' OverlapCount = 1 LifeTime = 11 StartDelayTime = 1 LoopIntervalTime = 1 ActiveTargetFilterAlias = 'Self' LoopTargetFilterAlias = 'Self'
-
patches\EffectTable.toml
:['.*: ^Gear_BetaCrystalAdditiveRate_.*$'] StatType = "ActorStatType_DrainHpByAttackPowerRate" StatCalculationType = "EffectCalculationType_Static" CalculationValue = '''=> { val prefix = "Gear_BetaCrystalAdditiveRate_" var n = 0.003 * v.objName(prefix.length).toDouble if (v.objName.contains("MK2")) n = n * 2 n }''' LifeType = "EffectLifeType_Infinite" LifeTime = 0
-
patches\RecoveryCacheZone.toml
:['.@: $..[?(@.Name == "ZoneBoundPadOverrides" && @.StructType == "Vector")]'] ZoneBoundPadOverrides = '''=> { val orig = v.orig[Map[String, Any]] orig + ("Z" -> -1999d) }'''
-
patches\TargetFilterTable.toml
:['.@: $..[?(@.Name =~ /N_Drone_Normal_Scan1_1_Target.*/)]'] FarDistance = 30000 TargetCheckValue1 = 3000
.toml
produces 3 patch files:
-
EffectTable.toml
:# ... # Game Original Value [Gear_BetaCrystalAdditiveRate_1] CalculationValue = 0.147 # 0.4000000059604645 LifeTime = 0 # "+0" LifeType = "EffectLifeType_Infinite" # "EffectLifeType_Infinite" StatCalculationType = "EffectCalculationType_Static" # "EffectCalculationType_Static" StatType = "ActorStatType_DrainHpByAttackPowerRate" # "ActorStatType_BetaCrystalAdditiveRate" [Gear_BetaCrystalAdditiveRate_1_MK2] CalculationValue = 0.294 # 0.6000000238418579 LifeTime = 0 # "+0" LifeType = "EffectLifeType_Infinite" # "EffectLifeType_Infinite" StatCalculationType = "EffectCalculationType_Static" # "EffectCalculationType_Static" StatType = "ActorStatType_DrainHpByAttackPowerRate" # "ActorStatType_BetaCrystalAdditiveRate" [Gear_BetaCrystalAdditiveRate_2] CalculationValue = 0.15 # 0.699999988079071 LifeTime = 0 # "+0" LifeType = "EffectLifeType_Infinite" # "EffectLifeType_Infinite" StatCalculationType = "EffectCalculationType_Static" # "EffectCalculationType_Static" StatType = "ActorStatType_DrainHpByAttackPowerRate" # "ActorStatType_BetaCrystalAdditiveRate" [Gear_BetaCrystalAdditiveRate_2_MK2] CalculationValue = 0.3 # 1.0499999523162842 LifeTime = 0 # "+0" LifeType = "EffectLifeType_Infinite" # "EffectLifeType_Infinite" StatCalculationType = "EffectCalculationType_Static" # "EffectCalculationType_Static" StatType = "ActorStatType_DrainHpByAttackPowerRate" # "ActorStatType_BetaCrystalAdditiveRate" [Gear_BetaCrystalAdditiveRate_3] CalculationValue = 0.153 # 1.0 LifeTime = 0 # "+0" LifeType = "EffectLifeType_Infinite" # "EffectLifeType_Infinite" StatCalculationType = "EffectCalculationType_Static" # "EffectCalculationType_Static" StatType = "ActorStatType_DrainHpByAttackPowerRate" # "ActorStatType_BetaCrystalAdditiveRate" [Gear_BetaCrystalAdditiveRate_3_MK2] CalculationValue = 0.306 # 1.5 LifeTime = 0 # "+0" LifeType = "EffectLifeType_Infinite" # "EffectLifeType_Infinite" StatCalculationType = "EffectCalculationType_Static" # "EffectCalculationType_Static" StatType = "ActorStatType_DrainHpByAttackPowerRate" # "ActorStatType_BetaCrystalAdditiveRate" [N_Drone_Scan] LifeTime = 30.0 # 3.5 [P_Eve_SkillTree_JustEvade_BurstGauge1] ActiveTargetFilterAlias = "Self" # "Self" CalculationMultipleValue = 4 # 1.0 LifeTime = 11 # 1.0 LoopIntervalTime = 1 # "+0" LoopTargetFilterAlias = "Self" # 'null' OverlapCount = 1 # 0 StartDelayTime = 1 # "+0" [P_Eve_SkillTree_JustEvade_BurstGauge2] ActiveTargetFilterAlias = "Self" # "Self" CalculationMultipleValue = 3 # 1.0 LifeTime = 11 # 1.0 LoopIntervalTime = 1 # "+0" LoopTargetFilterAlias = "Self" # 'null' OverlapCount = 1 # 0 StartDelayTime = 1 # "+0" [P_Eve_SkillTree_JustParry_BetaGauge1] ActiveTargetFilterAlias = "Self" # "Self" CalculationMultipleValue = 8 # 1.0 LifeTime = 11 # 1.0 LoopIntervalTime = 1 # "+0" LoopTargetFilterAlias = "Self" # 'null' OverlapCount = 1 # 0 StartDelayTime = 1 # "+0" [P_Eve_SkillTree_JustParry_BetaGauge2] ActiveTargetFilterAlias = "Self" # "Self" CalculationMultipleValue = 6 # 1.0 LifeTime = 11 # 1.0 LoopIntervalTime = 1 # "+0" LoopTargetFilterAlias = "Self" # 'null' OverlapCount = 1 # 0 StartDelayTime = 1 # "+0"
-
RecoveryCacheZone.toml
:# ... # Game Original Value ['.@: #2 $..[?(@.Name == "ZoneBoundPadOverrides" && @.StructType == "Vector")]'] ZoneBoundPadOverrides = '''=> { val orig = v.orig[Map[String, Any]] orig + ("Z" -> -1999d) }'''
-
TargetFilterTable.toml
:# ... # Game Original Value [N_Drone_Normal_Scan1_1_Target_Enemy] FarDistance = 30000 # 10000.0 TargetCheckValue1 = 3000 # 1000.0 [N_Drone_Normal_Scan1_1_Target_Owner] FarDistance = 30000 # 10000.0 TargetCheckValue1 = 3000 # 500.0
.toml.all
is similar to .toml
, except that it merges TOML patch files after code patches have been applied (see Advanced Script Customizations).