-
Notifications
You must be signed in to change notification settings - Fork 7
Home
ArchiveXL 1.5.0 introduces new approach for creating clothing mods called dynamic appearance.
The main goal is to eliminate repetitive work. This is accomplished by interpolating properties values and applying conditions directly to appearance definitions and components, instead of having to manage tons of entity appearances for each color variant and suffix.
In many cases you'll need just one appearance.
To activate the new feature, you must add a visual tag DynamicAppearance
to your root entity template (visualTagsSchema
).
Then you have to add only one template appearance without suffixes and one appearance definition. For example:
name: my_item
appearanceResource: mod\my_item.app
appearanceName: my_item
Instead of defining different appearances that depend on appearance suffixes, you can use property interpolation to substitute parts of mesh path and mesh appearance name with dynamic values.
To activate interpolation for a property, the value must start with *
.
For example:
mesh: *mod\meshes\my_item_{gender}.mesh
meshAppearance: default
All available attributes representing current state:
Placeholder | Substitution |
---|---|
{camera} |
fpp or tpp
|
{gender} |
m or w
|
{body} |
base_body or body mod name in snake case |
{arms} |
base_arms , mantis_blades , monowire , projectile_launcher
|
{feet} |
flat , lifted , high_heels , flat_shoes
|
{sleeves} |
full , part
|
{skin_color} |
skin color name from customization |
{hair_color} |
hair color name from customization |
To define different variants of your item you have to use a new syntax for item record's appearance name.
The name of the variant must be separated from appearance name by !
.
The appearance name must match the name in entity template.
For example:
Items.my_item_black:
$base: Items.GenericFaceClothing
entityName: my_item
appearanceName: my_item!black
Then you can use a variant name as a substitution in your component:
mesh: *mod\meshes\my_item_{gender}.mesh
meshAppearance: *{variant}
Composite variant can be defined using +
separator.
For example:
Items.my_item_black:
$base: Items.GenericFaceClothing
entityName: my_item
appearanceName: my_item!black+arasaka
In this case you can use different parts of variant name separately. For example, one part for color name and another part for decal name.
Variant parts can be accessed using .
and part index (starting from 1):
Placeholder | Substitution |
---|---|
{variant} |
black+arasaka |
{variant.1} |
black |
{variant.2} |
arasaka |
You can define activation conditions for appearance definitions or single components. The concept is similar to appearance suffixes in its purpose: you can load different parts, apply different parts overrides, activate/deactivate components depending on the current state.
To add condition you have to add the expression directly to appearance definition name (in .app
) or component name.
For example, appearance named my_item&camera=tpp
will be used only in TPP and replaced with a blank one in FPP.
You can define multiple elements with the same name but different conditions. If several elements with the same name match the criteria, then one with the highest priority will be used. if several elements with the same name and highest priority match the criteria, then the first in the order of definition will be used.
Appearance/Component | Priority | Description |
---|---|---|
my_item!variant&camera=tpp |
1 | Has the highest priority because it requires a specific variant and one state condition. |
my_item!variant |
2 | Has second priority because it requires a specific variant. |
my_item&gender=w&camera=tpp |
3 | Has third priority because it has two state conditions. |
my_item&camera=tpp |
4 | Has fourth priority because it has one state condition. |
my_item |
5 | Has the lowest priority and will be used when no other elements match the criteria. |
You can register your body mod as a body type with ArchiveXL to allow clothing items to automatically select a corresponding refit.
To register a body type:
-
Register body name using
.xl
configuration file:player: bodyTypes: [NewBody]
-
Add visual tag with the same name to any of your
.ent
or.app
.
Body type detection works with simple body replacements and with customization system.
The suffix itemsFactoryAppearanceSuffix.BodyType
represents currently used body mod.
It can be used to load a corresponding refit.
To activate a new suffix, you must add it to appearanceSuffixes
:
Items.MyGloves:
appearanceSuffixes:
- !append itemsFactoryAppearanceSuffix.BodyType
The value of the suffix will be the name registered by body mod author or &BaseBody
when no body mods used.
The suffix itemsFactoryAppearanceSuffix.ArmsState
represents what type of cyberarms are used by the character.
It can be used to properly render wrists and hands items depending on whether the character uses cyberarms.
To activate a new suffix, you must add it to appearanceSuffixes
:
Items.MyGloves:
appearanceSuffixes:
- !append itemsFactoryAppearanceSuffix.ArmsState
Cyberware | Suffix |
---|---|
None | &BaseArms |
Mantis Blades | &MantisBlades |
Monowire | &Monowire |
Projectile Launcher | &ProjectileLauncher |
The suffix itemsFactoryAppearanceSuffix.FeetState
represents the state of the feet of female characters.
It can be used to properly render tights or other legs clothing depending on whether the character is wearing shoes.
To activate a new suffix, you must add it to appearanceSuffixes
:
Items.MyTights:
appearanceSuffixes:
- !append itemsFactoryAppearanceSuffix.FeetState
Character | Footwear | Suffix |
---|---|---|
Female | Unequipped | &Flat |
Female | Equipped without tags | &Lifted |
Female | Equipped with HighHeels tag |
&HighHeels |
Female | Equipped with FlatShoes tag |
&FlatShoes |
Male | Any | (empty) |
To hide submeshes of the owner entity, such as body parts, in your appearance definition you must
add a partsOverrides
entry with a blank partResource
and add componentOverrides
using entity's component names.
It's similar to how you override parts of your own meshes, but instead you use the component names of the entity
that wears your item, such as t0_000_pma_base__full
or l0_000_pwa_base__cs_flat
.
To apply visual tags to an item you must add them to visualTags
property of your appearance definition
or to visualTagsSchema
of your root entity template.
Known visual tags defined by the game:
Tag | Effect |
---|---|
hide_H1 |
Hides an item in the Head slot. |
hide_F1 |
Hides an item in the Eyes slot. |
hide_T1 |
Hides an item in the Chest slot. |
hide_T2 |
Hides an item in the Torso slot. |
hide_L1 |
Hides an item in the Legs slot. |
hide_S1 |
Hides an item in the Feet slot. |
hide_T1part |
Toggles the partial suffix (&Full →&Part ) when applied to Torso item. |
hide_Hair |
Hides hair. |
hide_Genitals |
Hides genitals in uncensored mode and underware in censored mode. |
Custom visual tags defined by the mod:
Tag | Effect |
---|---|
hide_Head |
Hides head. |
hide_Torso |
Hides the whole torso. |
hide_LowerAbdomen |
Hides lower abdomen. |
hide_UpperAbdomen |
Hides upper abdomen. |
hide_CollarBone |
Hides collar bone area. |
hide_Arms |
Hides head. |
hide_Thighs |
Hides thighs. |
hide_Calves |
Hides calves. |
hide_Ankles |
Hides ankles. |
hide_Feet |
Hides feet. |
hide_Legs |
Hides the whole legs. |
force_Hair |
Forces visible hair for head items. |
force_FlatFeet |
Forces flat feet for female characters. |
The mod doesn't modify original files such as factories.csv
and onscreens.json
and doesn't produce new archives,
instead it merges your own resources with the originals at runtime.
The workflow is pretty simple:
- Create CR2W resources with your content and add them to the archive as usual
- Create a loader config that specifies which resources from your archive should be merged with the original game files
- Include the loader config in the mod along with the archive
mymod\factories\clothing.csv
:
{
"Header": {
"WKitJsonVersion": "0.0.3",
"GameVersion": 1600,
"DataType": "CR2W"
},
"Data": {
"Version": 195,
"BuildVersion": 0,
"RootChunk": {
"$type": "C2dArray",
"compiledData": [
[
"mymod_item",
"mymod\\items\\clothing\\item.ent",
"true"
]
],
"compiledHeaders": [
"name",
"path",
"preload"
],
"cookingPlatform": "PLATFORM_PC"
},
"EmbeddedFiles": []
}
}
Despite the name the factory can contain both entities (.ent
) and appearance (.app
) resources.
mymod\localization\en-us.json
:
{
"Header": {
"WKitJsonVersion": "0.0.3",
"GameVersion": 1600,
"DataType": "CR2W"
},
"Data": {
"Version": 195,
"BuildVersion": 0,
"RootChunk": {
"$type": "JsonResource",
"cookingPlatform": "PLATFORM_PC",
"root": {
"HandleId": "0",
"Data": {
"$type": "localizationPersistenceOnScreenEntries",
"entries": [
{
"$type": "localizationPersistenceOnScreenEntry",
"secondaryKey": "MyMod-Item-Name",
"femaleVariant": "Samurai Mask & Aviators"
}
]
}
}
},
"EmbeddedFiles": []
}
}
When creating you own localization it's recommended to always use the secondaryKey
.
If you don't need gender specific translations you should set femaleVariant
only and it'll be used for all genders.
If you want to edit original translations you must use the primaryKey
.
The config file is a YAML file with a .xl
extension that must be placed in the same directory with the archive:
<Cyberpunk 2077>\archive\pc\mod\mymod.archive
<Cyberpunk 2077>\archive\pc\mod\mymod.archive.xl
Or if you use REDmod packaging:
<Cyberpunk 2077>\mods\betsmod\archives\mymod.archive
<Cyberpunk 2077>\mods\betsmod\archives\mymod.archive.xl
In this example, the config file is named after the archive for convenience. But you can name it as you want.
In the config file you have to specify factories and/or localization resources to load:
factories:
- mymod\factories\clothing.csv
- mymod\factories\weapons.csv
localization:
onscreens:
en-us: mymod\localization\en-us.json
de-de: mymod\localization\de-de.json
The first language in the list is also a fallback language and will be used when the user enables a language that is not supported by the mod.
Language codes used by the game:
Code | Language | Code | Language |
---|---|---|---|
pl-pl |
Polish | ru-ru |
Russian |
en-us |
English | pt-br |
Brazilian Portuguese |
es-es |
Spanish | jp-jp |
Japanese |
fr-fr |
French | zh-tw |
Traditional Chinese |
it-it |
Italian | ar-ar |
Arabic |
de-de |
German | cz-cz |
Czech |
es-mx |
Latin American Spanish | hu-hu |
Hungarian |
kr-kr |
Korean | tr-tr |
Turkish |
zh-cn |
Simplified Chinese | th-th |
Thai |