More detailed explanations for the guide "Adding new items"
Created: by @manavortex Last documented edit: June 10 2023
This page is a part of the Adding new items guide and explains how the different files interact with each other.
If you have come here from the main page because you want to change the existing files, search for Making changes
in each section. To add new appearances, the following files are relevant:
.json (translations)
You do not need to touch the mesh entity.
Unless stated otherwise, any linked resources are optional and might not even be related to this exact guide.
We need four files to tell the game about our new items:
the .yaml, which tells TweakXL about your item's properties
the .xl file, which tells ArchiveXL which files to register
the .csv, telling the game about your custom files
the .json file with the translations
This file will be in the same directory as your mod's .archive file. It lets ArchiveXL register the factory (my_shirt_factory.csv
) and the localization file (translation_strings.json
).
You usually touch this only once, unless you want to add more factories or translation files.
You only need to change this file if you have changed the factory's file path (moved the file) or want to add a second factory file (there is no need to, though).
This is the localization file for language-specific entries (green boxes on the xl file's screenshot). If no entry for a language is defined, then the English one will be used.
An entry will look like this:
If you don't need a male-specific translation, you can leave it blank — by default, femaleVariant
will be used.
You need to change this file every time you want to add a new text entry to your mod. The easiest way to do this is by duplicating an existing entry.
The factory connects your .yaml
to the corresponding rootEntity.ent
via entity_name
.
When reading your .yaml file (e.g.tutorial_my_custom_tshirt.yaml
, next section), the game will find entries like this:
The csv file is where ArchiveXL will find an entry with the yaml's entityName
in the first field. It will then check the corresponding root entity for an appearance with the name in appearanceName.
You only need to change this file when
you move a root entity (update the path!)
you add a new entityName — for example, a second t-shirt that you want to have its own root entity.
When editing this file, please keep in mind that indent is important!
The first line of each block must not have spaces, the blocks below must have the same amount of spaces. More spaces means more nesting.
Making mistakes here might break your entire mod, so if in doubt, run your edited file through an online yaml validator.
This file controls the adding of items to the game. Unless you are using dynamic appearances, an entry looks like this:
The entry above will let you add the item via Game.AddToInventory('Items.my_custom_shirt_redwhite')
Four mappings take place here:
entityName
: Points to the factory.csv (see documentation there as for what it works)
appearanceName
: In the root entity specified in the factory, it will look for an appearance by this name.
The appearance name will only be considered up to the first suffix. If you want to know what those pesky & things are doing, read up the corresponding documentation.
You don't need to know this unless you aren't using dynamic appearances and want to add variants for different genders or camera perspectives. We're making them go away by puttingappearanceSuffixes: []
.
displayName
/localizedDescription
: In the translation_strings.json
, find an array where the value for [3] (the last entry) is identical to this key. Then, check which gender V has, and display either femaleVariant
or maleVariant
.
icon:
This hooks up your custom preview.
$base
defines which slot the item will use. For the full documentation, see "Different equipment slots".
The inherited properties can cause problems (see "Suffixes, and whether you need them" for more detail).
You don't need to know this unless you want to add variants for different genders or camera perspectives: we're avoiding them by puttingappearanceSuffixes: []
.
You need to touch this file every time you want to add a new item (or when you want to change an existing one). It is easiest to duplicate an existing entry.
If you want more than just the base properties, check the documentation for TweakXL's creating records.
Now that we're done with the base structure, we can take a look at the game files. Like for any of the vanilla game items, we have four of them. This guide will only hold information that's directly relevant to adding item, but in the individual sections below, you will find links to more documentation about the files.
With ArchiveXL >= 1.5, there is a new way of making these connections, saving most of the work of making many variants. You can still complete this guide and then see the documentation for dynamic loading on its own page.
If you want to do more than 5 variants (for both body genders and camera modes), that approach is strongly recommended. Since there isn't a detailed guide yet, you can find us on Discord in the #archive-xl channel.
appearance.app
mesh_entity.ent
the mesh file
This is how the files connect to each other. If your head explodes now, don't worry: it's not as complicated as it looks, and the item addition guide will walk you through step by step.
Would you like to know more? Full documentation of the root_entity is on its own page.
Understanding this is not necessary for the purpose of this guide.
The entry point from your yaml, this file is a glorified lookup dictionary: for any appearanceName
, it will specify an .app
file and the name of an appearance in the .app
file.
An entry looks like this:
If you don't know what this means, skip it and wait for the full step-by-step guide!
For using dynamic appearances, you only need one appearance here, which must match the field appearanceName
in the .yaml
up to the variant separator !
Make sure to add the DynamicAppearance
tag here.
Unless you are using dynamic appearances, the root entity's name
field is where you would put suffixes for different appearance variants.
You don't need to know what suffixes are unless you want to make variants for different genders or camera types. In fact, you will want to skip this until you have a confirmed and working mod!
To disable them, each entry in your .yaml contains the following line:
appearanceSuffixes: []
When you change the path of this file, you need to adjust the path inside the factory.csv.
Adding a new appearance:
Expand the list appearances
and duplicate your already working entry.
Change the following fields:
appearanceName
=> everything before the & must match appearanceName
in your *.yaml
name
=> must match the name you're going to put in your app.app
Example:
old (copy):
new:
You do not need to change the appearanceResource
.
For experienced modders
This file replaces the component
array inside the .app!
Check here for how to find the right mesh entity for each equipment slot.
This file holds a collection of components that determine how our equipment item behaves and moves. Each kind of equipment has different types of components, which is why you need to pick the right mesh entity file for each equipment slot.
Would you like to know more?
Full documentation of mesh_entity The mesh entity for dynamic appearances More intel on components
Understanding this is not necessary for the purpose of this guide!
By bundling them in this file, we save ourselves a lot of copy-pasting inside the .app file. The only component we actually need to change is the one with "Mesh" in its name, typically entGarmentSkinnedMeshComponent
:
The component's name
will be used in appearance.app
's materialOverride array (see below)
When changing component names, you want to leave the #component-prefixes (t1_) in place — the game needs them to calculate collisions!
If the text in this box tells you nothing, just ignore it for now
If you're using dynamic appearances, you can use property interpolation in paths. For example, *p{gender}a
will resolve to pwa
or pma
, based on V's body gender.
Read more about this on ArchiveXL's github.
When you move this file, you need to change the path inside every appearance inside the .app file.
Otherwise, you only need to touch this file if you move the .mesh file.
Contains a list of appearances as mapped by rootentity.ent
. Each of the appearances will load mesh_entity.ent
via partsValues.
If you're not using dynamic appearances, you specify the components' appearances and chunkMasks in the partsOverrides
.
For experienced modders
The .app file's component array should be empty: this is not an NPC appearance! :)
An entry will look as follows:
partsValues
will define what mesh_entity file(s) to load (as a list of components), while partsOverrides
tells the mesh which appearance to use.skipp
For ArchivXL >= 1.4.0, appearance overrides can understand the following variables for meshAppearance
:
If you don't know what this means, skip it and wait for the full step-by-step guide!
For using dynamic appearances, you only need one appearance here. In this case, components will be ignored — make sure to put them all into your mesh_entity!
When you move this file, remember to change the path inside the root_entity.ent
You need to touch this file every time you add a new appearance:
Open the .app file and expand the list appearances
.
Duplicate an item and select the new one.
Change its name to the one you just defined in the .yaml (black_blue_appearance_name
)
In the new appearance, find the array partsOverrides
and expand it.
Select the item inside.
Find and expand the Array appearanceAppearancePartOverrides
and expand it.
Select the first item.
Open the array componentsOverride
and select the first item.
Change the value of meshAppearance
to the name of your new appearance in the mesh:
You can leave partsValues
alone - this just points at the file that loads the mesh, and you've already set it up above when setting up the file.
The mesh file maps materials to appearances. To find out how exactly it does that, find the material section on the mesh wiki page.
Would you like to know more?
#appearan
The documentation for .mesh files lives on their own page!
Understanding this is not necessary for the purpose of this guide, but you might want to reference it once you run into trouble.
For our purposes it's enough to say that you can define your individual appearances here.
Find the array appearances
and open it.
Duplicate any meshMeshAppearance
.
Change the name to the one you've defined in the appearance.app
above (in this case: mesh_black_blue
):
Select the array chunkMaterials
and change the entries in the right-hand panel to the name of your new material (e.g. black_blue
)
Find the array materials
and open it.
Duplicate the last entry. (Yes, use the last one, please, it's important for step 3).
Select the new last entry
Set the following values:
If you duplicated the last material, you can just increase it by one.
Find the array localMaterialBuffer
and open it
Duplicate any entry with an mlsetup (You will see an entry MultilayerSetup
under values
)
Drag it to the last position of the array (that's important, because the materials entries match by numeric index)
Select the new item, open values
, and select MultilayerSetup
.
Set baseMaterial/DepotPath
to the .mlsetup
file that you want.
For further information and guides, check here or see https://github.com/CDPR-Modding-Documentation/Cyberpunk-Modding-Docs/blob/main/for-mod-creators/files-and-what-they-do/3d-objects-.mesh-files.
This is how everything plays together:
{gender}
m or w depending on V's body gender
{skin_color}
{hair_color}