Skip to content

Latest commit

 

History

History
289 lines (241 loc) · 6.35 KB

modop-replace-merge.md

File metadata and controls

289 lines (241 loc) · 6.35 KB

ModOp Type replace and merge

Content

Other docs

ModOp Type replace

Replace to swap content

Type completely replaces the selected nodes with the content.

<ModOp GUID="123" Type="replace" Path="/Values/Standard">
  <Standard>
    <GUID>456</GUID>
    <Description>Hello</Description>
  </Standard>
</ModOp>

Result:

<Asset>
  <Values>
    <Standard>
-     <GUID>123</GUID>
-     <Name>some name</Name>
+     <GUID>456</GUID>
+     <Description>Hello</Description>
    </Standard>
    <Cost />
  </Values>
</Asset>

Note: the element to be replaced (Standard in this example) needs to be mentioned as well.

Replace to remove content

<ModOp GUID="123" Type="replace" Path="/Values/Cost">
  <Cost />
</ModOp>

Result:

<Asset>
  <Values>
    <Standard>
     <GUID>123</GUID>
    </Standard>
    <Cost>
-     <Item />
    </Cost>
  </Values>
</Asset>

Replace to remove node

An empty replace is essentially the same as remove.

Both ModOps have the same output:

<ModOp GUID="123" Type="replace" Path="/Values/Cost">
</ModOp>

<ModOp GUID="123" Type="remove" Path="/Values/Cost" />

Result:

<Asset>
  <Values>
    <Standard>
     <GUID>123</GUID>
    </Standard>
-   <Cost>
-     <Item />
-   </Cost>
  </Values>
</Asset>

Best Practice: avoid large replace

Imagine you want to do a change in a production chain. It is better to insert, merge or do a very small replace instead of replacing the whole chain to not overwrite other mods doing little changes in the same location.

ModOp Type merge

Merge is order independent

The order of nodes do not matter anymore for successful merges. Before you had to have the exact same order as the game.

<ModOp GUID="123" Type="merge" Path="/Values/Building">
  <AllowChangeDirection>1</AllowChangeDirection>
  <AllowChangeVariation>1</AllowChangeVariation>
</ModOp>

Result:

<Asset>
  <Values>
    <Standard>
      <GUID>123</GUID>
    </Standard>
    <Building>
-     <AllowChangeVariation>0</AllowChangeVariation>
-     <AllowChangeDirection>0</AllowChangeDirection>
+     <AllowChangeVariation>1</AllowChangeVariation>
+     <AllowChangeDirection>1</AllowChangeDirection>
    </Building>
  </Values>
</Asset>

Merge adds missing nodes

<ModOp GUID="123" Type="merge" Path="/Values/Building">
  <AllowChangeVariation>1</AllowChangeVariation>
  <BuildModeStartVariation>0</BuildModeStartVariation>
</ModOp>

Result:

<Asset>
  <Values>
    <Standard>
      <GUID>123</GUID>
    </Standard>
    <Building>
-     <AllowChangeVariation>0</AllowChangeVariation>
+     <AllowChangeVariation>1</AllowChangeVariation>
+     <BuildModeStartVariation>0</BuildModeStartVariation>
    </Building>
  </Values>
</Asset>

Merge does not remove nodes

<ModOp GUID="123" Type="merge" Path="/Values">
  <Building />
</ModOp>

Result:

<Asset>
  <Values>
    <Standard>
      <GUID>123</GUID>
    </Standard>
    <Building>
     <AllowChangeVariation>1</AllowChangeVariation>
    </Building>
  </Values>
</Asset>

Use replace or remove instead if you want to remove content.

Merge supports lists

Since GU17.1

Merging with multiple same name nodes (usually Item) is not supported anymore.

<ModOp Type="merge" GUID="100780" Path="/Values/Maintenance">
  <Maintenances>
    <Item>
      <Product>1010017</Product>
      <Amount>50000</Amount>
      <InactiveAmount>30000</InactiveAmount>
    </Item>
    <Item>
      <Product>1010367</Product>
      <Amount>50</Amount>
    </Item>
  </Maintenances>
</ModOp>

Result:

<Maintenance>
  <Maintenances>
    <Item>
      <Product>1010017</Product>
-     <Amount>400</Amount>
-     <InactiveAmount>200</InactiveAmount>
+     <Amount>50000</Amount>
+     <InactiveAmount>30000</InactiveAmount>
    </Item>
    <Item>
-     <Product>1010367</Product>
-     <Amount>50</Amount>
+     <Product>1010117</Product>
+     <Amount>150</Amount>
      <ShutdownThreshold>0.5</ShutdownThreshold>
    </Item>
  </Maintenances>
</Maintenance>

But be aware, relying on index is prone to compatibility issues.

Merge can be used like add or replace

The following to merge operations lead to the same result.

Used like add, will only add if not there already:

<ModOp GUID="123" Type="merge" Path="/Values/Building">
  <AllowChangeVariation>1</AllowChangeVariation>
</ModOp>

Used like replace including the last path element (i.e. Building):

<ModOp GUID="123" Type="merge" Path="/Values/Building">
  <Building>
    <AllowChangeVariation>1</AllowChangeVariation>
  </Building>
</ModOp>

You need to use the second approach in some rare cases when parent and child element have the same name - which happens in localizations for example (Texts/Text/Text/GUID). It only applies if there is exactly one top-level element in the ModOp that has the same name as the last path element.

Note the following changed behavior since modloader10 / GU17.

The following ModOp doesn't update AllowChangeVariation anymore. Yes, it did before... It will instead add the node to Values.

<ModOp GUID="123" Type="merge" Path="/Values/Building">
  <AllowChangeVariation>1</AllowChangeVariation>
  <Building>
    <BuildModeStartVariation>0</BuildModeStartVariation>
  </Building>
</ModOp>

Result:

<Asset>
  <Values>
    <Standard>
      <GUID>123</GUID>
    </Standard>
    <Building>
      <AllowChangeVariation>0</AllowChangeVariation>
+     <BuildModeStartVariation>0</BuildModeStartVariation>
+     <Building>
+       <AllowChangeVariation>1</AllowChangeVariation>
+     </Building>
    </Building>
  </Values>
</Asset>