ℹ️ItemAdditions: File structure explained

More detailed explanations for the guide "Adding new items"

Summary

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:

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.

Structural files: telling the game about your mod

We need four files to tell the game about our new items:

  1. the .yaml, which tells TweakXL about your item's properties

  2. the .xl file, which tells ArchiveXL which files to register

  3. the .csv, telling the game about your custom files

  4. the .json file with the translations

The .xl file

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.

.xl: Making changes

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).

The .json file (custom texts, i18n)

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.

.json: Making changes

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 .csv file (the factory)

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:

Items.my_custom_shirt_redwhite:
  entityName: my_custom_shirt_factory_name             << this is for the factory.csv
  appearanceName: appearance_root_entity_white_red     << this is for the root_entity.ent

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.

Making changes

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.

The control file: yourModName.yaml

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:

  1. entityName: Points to the factory.csv (see documentation there as for what it works)

  2. 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: [].

  1. 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.

  2. icon: This hooks up your custom preview.

What is it, precious? The $base parameter

$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: [].

.yaml: Making changes

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.

The game files

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.

Overview

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.

root_entity.ent

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.

Suffixes

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: []

Root Entity: Making Changes

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):

	appearanceName: black_red_appearance_name
	name: appearance_root_entity_black_red

new:

	appearanceName: black_blue_appearance_name
	name: appearance_root_entity_black_blue

You do not need to change the appearanceResource.

mesh_entity.ent

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.

Mesh Entity: Making Changes

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.

appearance.app

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:

{gender}

m or w depending on V's body gender

{skin_color}

{hair_color}

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!

Appearance: Making changes

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:

  1. Open the .app file and expand the list appearances.

  2. Duplicate an item and select the new one.

  3. Change its name to the one you just defined in the .yaml (black_blue_appearance_name)

  4. In the new appearance, find the array partsOverrides and expand it.

  5. Select the item inside.

  6. Find and expand the Array appearanceAppearancePartOverrides and expand it.

  7. Select the first item.

  8. Open the array componentsOverride and select the first item.

  9. Change the value of meshAppearance to the name of your new appearance in the mesh:

componentName: t1_tutorial_custom_shirt_4711   << no need to change this  
mesh_appearance: mesh_black_blue                << corresponds to meshMeshAppearance.name in my_mesh.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.

Mesh

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?

https://github.com/CDPR-Modding-Documentation/Cyberpunk-Modding-Docs/blob/main/for-mod-creators/files-and-what-they-do/3d-objects-.mesh-files

#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.

Mesh: Making changes

  1. Find the array appearances and open it.

    1. Duplicate any meshMeshAppearance.

    2. Change the name to the one you've defined in the appearance.app above (in this case: mesh_black_blue):

    3. Select the array chunkMaterials and change the entries in the right-hand panel to the name of your new material (e.g. black_blue)

  2. Find the array materials and open it.

    1. Duplicate the last entry. (Yes, use the last one, please, it's important for step 3).

    2. Select the new last entry

    3. Set the following values:

      name:  mesh_black_blue           <<< as defined in step 1 and used by meshMeshAppearance in appearances[]  
      index: <index of item in array>  

      If you duplicated the last material, you can just increase it by one.

  3. Find the array localMaterialBuffer and open it

    1. Duplicate any entry with an mlsetup (You will see an entry MultilayerSetup under values)

    2. Drag it to the last position of the array (that's important, because the materials entries match by numeric index)

    3. Select the new item, open values, and select MultilayerSetup.

    4. 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.

The final result

This is how everything plays together:

Last updated