How to convert your mod to use dynamic variants... in ten minutes
Published: June 30 2024 by mana vortex Last documented update: June 30 2024 by mana vortex
This page will teach you how to convert your existing ArchiveXL mod to the "new" system.
An ArchiveXL mod that you want to convert
We will go through the process step-by-step. I'll explain what I'm doing as I go along.
Instead of one entry per item variant, we only need one entry per item.
Our variants are defined via $instances
and generated via substitutions. Let's take a look at this:
We deleted the appearanceSuffixes
(we'd only need them for Gendered preview icons, and we can't be arsed with that)
We defined a list of $instances
, which will generate all of our different appearances
We replaced all parts that are different with the corresponding key from $instances
. The rest will be magic.
Defines the variants — you'll get a gold star for paying attention, but we're getting to that later (Step 3: The mesh entity)
Instead of one entry per variant and gender, we only need one entry in total.
Our appearance's name
must still match the .yaml
, but only up to the variant separator: we're going with appearance_root_entity_
.
We added the DynamicAppearance
tag to enable the feature
We deleted all appearances but one
We deleted everything variant-related from the appearance
We deleted the appearanceName, so that ArchiveXL will re-use name
for the .app
Instead of one appearance per variant and gender, we will squash everything down so that we have only one appearance per gender. In Let's simplify this even further., I will teach you how to reduce that even further, but for now, we'll be going step by step.
We deleted all but one appearance per gender
We added the condition &gender=w
and &gender=m
We deleted the partsOverrides
Gender matching now happens via condition. The different meshes for male and female body gender are loaded in the different mesh entity files.
Right! You've been paying attention! Let's take a look at that next.
We will only change a single field (meshAppearance
).
Before, it was mesh_white_red
(the default appearance), and each appearance overwrote it via partsOverride
. We're now changing it to dynamic
:
Old: mesh_white_red
New: *mesh_{variant.2}_{variant.1}
By adding a leading *
, we told ArchiveXL that this field is involved in magic (substitution in this case)
By replacing white
with {variant.2}
, we're using the second parameter from the yaml's appearanceName
(shirt).
By replacing red
with {variant.1}
, we're using the first parameter from the yaml's appearanceName
(ribbons).
Let's unpack this.
In this example, we have the following mesh appearances:
mesh_white_red
mesh_black_red
mesh_black_blue
By using !
in the appearanceName
, we're telling ArchiveXL that everything after is part of the mesh appearance definition:
The +
in the variant
splits it up. If we didn't have it, we couldn't use variant_1
and variant_2
.
Let's compare our setup ( *mesh_{variant.2}_{variant.1}
) to the alternative.
yaml:
appearanceName: appearance_root_entity!$(shirt)_$(ribbons)
Our meshAppearance
would be *mesh_{variant}
.
Unless you got hopelessly lost, this should have taken no more than ten minutes, and your mod just works(tm).
You now have one root_entity
entry, two appearanceAppearanceDefinition
s in your .app
, and one mesh_entity
per body gender.
Currently, we have two mesh_entities:
tutorial\torso\my_custom_shirt\mesh_entity_pwa.ent
tutorial\torso\my_custom_shirt\mesh_entity_pma.ent
Each of them points at a different mesh:
tutorial\torso\my_custom_shirt\meshes\t1_custom_shirt_pwa.mesh
tutorial\torso\my_custom_shirt\meshes\t1_custom_shirt_pma.mesh
Delete one of the mesh entities and rename the other:
tutorial\torso\my_custom_shirt\mesh_entity.ent
Delete one of your appearances, and strip the suffix name from the other, leaving only appearance_root_entity_
.
Change the path of your partsValue
to the only remaining mesh entity, and save the file.
You should use the other approach where possible; this is only documented here for the sake of completeness.
Just like with appearances, you can also use Conditions with component names.
Pro: Especially with many body mods, you can just put all the logic into the components
Cons: All of these components will be added to the player entity, even if half of them will be hidden. This is bad for performance, especially if everyone does it.
The best way of dealing with multiple meshes is to have a single component and let ArchiveXL handle all the heavy lifting by using substitutions in the path:
This is our mesh's depot path:
*tutorial\torso\my_custom_shirt\meshes\t1_custom_shirt_p{gender}a.mesh
At runtime, ArchiveXL will substitute {gender}
with w
or m
, so depending on your V's body gender, the game will load one of these paths:
tutorial\torso\my_custom_shirt\meshes\t1_custom_shirt_pwa.mesh
tutorial\torso\my_custom_shirt\meshes\t1_custom_shirt_pma.mesh
You can find a full list of component substitution on ArchiveXL: Suffixes and Substitutions.
By using substitutions, your mesh path will auto-adjust to the current circumstances, and simply load the correct mesh.