Adding new items

No more replacers! Add your own gear with TweakXL and ArchiveXL

Summary

Created by @manavortex Published November 04 2022

This guide will walk you through adding your own items to Cyberpunk 2077, which can then be spawned via console.

It uses the following versions:

Assumed skill level: You should be able to find your way around WolvenKit, but I aim to keep this as noob-friendly as possible.

The guide was created after reading this one and being left with a bunch of question marks. To get a deeper understanding, refer to the initial guide and follow the linked resources or consult ArchiveXL's documentation.

To troubleshoot your ArchiveXL mods, you can make use of the FileValidation in Wolvenkit >= 8.9.1. As of Jul 22nd that isn't yet released, but you can download a Nightly (for example this one, as it's pretty stable).

Grab the example files

  • Create a new Wolvenkit project

  • Download the prepared files from Nexus and extract them to the root of your new project (overwriting the "source" folder)

If you would rather start from scratch: Check the detailed instructions here.

Understanding of the file structure is not required as long as you follow the guide to the letter, but if you want it anyway, see the item structure explained sub-page.

You should now have the following files:

These files do not contain an Atelier store. If you want to add one, see here.

Start the game

Wait, am I not supposed to do anything first??

Actually, no! This is how you later debug your custom items — by packing your project and checking that everything works in-game. So we're starting with a dry run here.

Press "Install and Launch" in WolvenKit. This will do the following things:

  1. Copy all supported file entries from source to their destination under packed, overwriting older files (but not removing files that you renamed!)

  2. Copy all files under packed into your game directory, again overwriting older files

  3. Launch the game.

  4. Spawn one of the tutorial items via Cyber Engine Tweaks: Game.AddToInventory("Items.my_custom_shirt_redwhite")

    Game.AddToInventory("Items.my_custom_shirt_redblack")

You should now see your the tutorial item. If not, consult the section Troubleshooting below, or retrace your steps and make sure that everything works before proceeding to the step below.

Great! You added items! Now what?

You've successfully pushed a button and everything worked, but so far, you haven't done anything. If you're okay with this, then you're done now.

Otherwise, you will want to complete one or more of the following steps:

Diagram

This is how everything connects. Looks pretty scary, but is actually simple: whenever you want to rename or something, make sure that you catch both ends of the arrow.

You can find a breakdown-by-entry on the corresponding wiki page.

Don't panic, we've got this.

Adding an appearance (example: blackblue)

If you would rather have a step-by-step guide for a gendered variant, see the next section.

To add an appearance, you will have to touch the following files:

  1. *.yaml: Adding an entry

  2. appearance.app: Adding a mapping between rootentity and mesh's appearance

  3. rootentity.ent: Adding a mapping between yaml's appearance and app's appearance

  4. *.mesh:

    1. Adding a MeshMaterialEntry

    2. Adding a MaterialInstance

    3. Adding a material

    4. Connecting those things

For a diagram of how everything connects, go here. To follow the

Step 1: Register it in your *.yaml

  1. Duplicate the entire appearance block for an already working item. ⚠Mind the indent!

  2. Change the first line to a unique name like Items.my_custom_shirt_blueblack

  3. Set the new appearance name for the rootentity.ent appearanceName: appearance_root_entity_black_blue

  4. For lookups in your translation file (translation_strings.json): Change the values of displayName and localizedDescription to the corresponding secondary keys in the json file. This is optional.

      displayName: my_shirt_localization_name_black_blue
      localizedDescription: my_shirt_localization_desc

    ℹIf you make any mistakes here, the worst that happens is an empty string.

  5. Now, add a new entrie to your .json file:

    localizationPersistenceOnScreenEntry - []   
    	femaleVariant: my item - now in black and blue
    	maleVariant:  
    	secondaryKey:  my_shirt_localization_name_black_blue

The total entry should look like this:

Items.my_custom_shirt_blueblack:
  $base: Items.GenericInnerChestClothing
  entityName: my_custom_shirt_factory_name
  appearanceName: appearance_root_entity_black_blue
  displayName: my_shirt_localization_name_black_blue
  localizedDescription: my_shirt_localization_desc
  quality: Quality.Legendary
  appearanceSuffixes: []

Step 2: Add it to the rootentity.ent

Find the step-by-step guide in the root entity section on the "Item structure explained" page.

If you want to add a dynamic appearance, make sure to add the DynamicAppearance tag here.

Step 3: Add it to my_custom_shirt.app

Find the step-by-step guide in the appearance section on the "Item structure explained" page

Step 4: Add it to the .mesh

This tutorial assumes you already know how to recolour an item. Quick reminder about the mlsetup:

  1. Export it to json

  2. edit the mlsetup.json with the MLSetupBuilder

  3. Import it back

Find the step-by-step guide in the mesh file section on the "Item structure explained" page

Test it

Now, log into the game and spawn the item variant. The name is the header you defined in the yaml file, in this case

Game.AddToInventory('Items.my_custom_shirt_blueblack')

Adding a Male Instance

Before we proceed with the tutorial, it's important to address a common issue you might have encountered while creating your mod.

If you've tested the mod on a Male V, you might have noticed some weird glitches like mesh clipping or wonky shapes.

You see, we've been using a mesh designed specifically for Female V, and that's why we've been running into some roadblocks. But don't worry, we're here to help you overcome this challenge!

Preparing the mesh file for the male variant

To fix this issue, we'll need a mesh that's compatible with Male V.

In the interest of keeping things simple, we've found just the mesh for you! It's called t1_024_ma_tshirt__sweater.mesh and it can be found in the base\characters\garment\citizen_casual\torso\t1_024_tshirt__sweater directory.

Now, add the file to your project, move it to the tutorial\torso\my_custom_shirt\ folder and rename it from t1_024_ma_tshirt__sweater.mesh to my_mesh_m.mesh.

Next, follow the steps you used for the original my_mesh.mesh by removing any unnecessary entries and adjusting the indices.

Creating a .ent File for Your Custom Mesh

It's time to set up the .ent file for our mesh. Don't worry, it's easy!

Start by making a copy of the mesh_entity.ent file that you previously created for the female version by duplicating it, and rename it to mesh_entity_m.ent.

duplicating mesh_entity.ent and creating the new mesh_entity_m.ent for out new mesh

Inside the mesh_entity_m.ent file, find the first component of the type entGarmentSkinnedMeshComponent. Set the following values:

mesh:   DepotPath:   tutorial\torso\my_custom_shirt\my_mesh_m.mesh      << path to your mesh  
        Flags:       Default                               << leave this alone  
name:   my_shirt_m    << this corresponds to the appearanceOverride in appearance.app  
All of the changes made to mesh_entity_m.ent file

Edit the yourModName.yaml

Inside the yourModName.yaml file set the appearanceSuffixes array to itemsFactoryAppearanceSuffix.Gender

Items.my_custom_shirt_redwhite:
  $base: Items.GenericInnerChestClothing
  entityName: my_custom_shirt_factory_name
  appearanceName: appearance_root_entity_white_red
  displayName: my_shirt_localization_name_white_red
  localizedDescription: my_shirt_localization_desc
  quality: Quality.Legendary
  appearanceSuffixes: [ itemsFactoryAppearanceSuffix.Gender ]
  icon:
    atlasResourcePath: tutorial\torso\my_custom_shirt\ops\preview_icons.inkatlas
    atlasPartName: slot_01

If you are unclear about why this step was taken, we recommend reading up on suffixes!

Edit the rootentity.ent

  1. Find the array appearances.

  2. Expand the first entry.

    1. Append &Female to the name attribute. This will change the name from appearance_root_entity_white_red to appearance_root_entity_white_red&Female.

  3. Duplicate the first (and only) entry to create a new one.

  4. Expand the newly create entry

    1. Set name : appearance_root_entity_white_red&Male.

    2. Set appearanceName : my_shirt_m.

All of the changes made to rootentity.ent file

Edit the appearance.app

  1. Find the array appearances

  2. Duplicate the first entry to create a new one and expand it

  3. Set the name attribute to my_shirt_m (as defined in the root_entity)

  4. Find the array partsValues

    1. Set the resource path to your new male mesh entity file: resource : tutorial\myshirt\mesh_entity_m.ent

  5. Find the array partsOverrides

    1. Find the array componentOverrides

      1. Set componentName : my_shirt_m

    2. Set partResources : tutorial\torso\my_custom_shirt\mesh_entity_m.ent

All of the changes made to appearance.app file. Paths are not up-to-date!

Testing the mod

To test your mod, it's important to ensure that it works correctly for both male and female V. This means you'll need to have two separate save files, one for male V and one for female V, unless you're using a mod that allows you to quickly switch between them.

Test your mod independently for both cases by loading the appropriate save file and checking that the mod is working as intended. To spawn and equip your item, use the command specified in your YAML file.

Game.AddToInventory("Items.my_custom_shirt_redwhite")

The final touches

If everything is working: Congratulations! You have successfully made a mod!

But before you can share it, you need to do one last thing, which is changing the file structure. Otherwise, everyone will overwrite the same tutorial files, and only one of those mods will work.

You can find a full guide on how to do that here.

Troubleshooting

The easiest way to spot what's wrong is to use Wolvenkit's new FileValidation feature, which will print warnings and errors to the log file for you, starting at version >= 8.9.1.

First of all, check the logs for errors including the name of your mod:

  • red4ext/plugins/ArchiveXL/ArchiveXL.log

  • red4ext/plugins/TweakXL/TweakXL.log

ArchiveXL added clipping!

You have read right past those warning boxes telling you about component name prefixes. Make sure that you add them back.

My item warps weirdly

... deforms incorrectly, or is a puddle on the floor?

Most likely, you have ignored the hint box when picking your mesh_entity.ent: Make sure that you're using an entity file that corresponds with the slot that you are trying to replace (e.g. if your item is a pair of shoes, you need an entity file from base\characters\garment\player_equipment\feet).

If you are here because of a link from a different guide:

You can find out which entity file your item uses by right-clicking on your mesh and selecting "find files using this". Add the .ent file to the list and open it in WolvenKit. Then, replace the contents of the "components" array with those of an .ent file from the correct folder — don't forget to change the path to your mesh again!

I spawn my item, but it's not added to my inventory!

If no additional yaml files are messing things up, then the error is somewhere in the first part of the chain and relatively easy to fix:

Check the following places:

  • yourmodname.archive.xl:

    • Is the indentation correct, as shown in the picture?

    • Did you make any typos?

  • my_tshirt_factory.csv:

    • Is there an entry where the first value matches the entityName from the yaml (my_tshirt in the picture above)?

      • Without leading or trailing spaces?

    • Does the second value of that entry have the correct root entity path? (tutorial\myshirt\rootentity.ent in the picture above) If you moved the root_entity.ent, you have to adjust this entry.

  • rootentity.ent:

    • Do you have an appearance matching your item by name?

      • Without leading or trailing spaces?

    • Are you using any suffixes? Are you using the correct ones?

      • Try setting an empty suffix array in the .yaml, just to see if that works: appearanceSuffixes: [ ]

      • Try creating a fall-back entry without any suffixes in the root_entity.

My item shows empty text instead of name/description!

Something went wrong with your json file:

If there are no errors in any of the log files, check the following places:

  • yourmodname.archive.xl:

    • Does the key localization - onscreens - en-us exist?

    • Is the indentation correct, as shown in the picture?

    • Does it point at the correct file (tutorial\ops\translation_strings.json), or did you rename or move it?

    • Did you make any typos?

  • yourModName.yaml:

    • Is the spelling for the key you defined after displayName and localizedDescription identical to the one in the json file?

  • translation_strings.json:

    • Is the spelling of the key defined in yaml's displayName and localizedDescription identical?

    • Did you set the femaleVariant (default)?

    • Are you using quotation marks? If so, switch to singlequotes!

    • If the field for primary_key is not empty, then its value must be unique (probably on a per-file basis). Just number them.

The item spawns, but…

Congratulations, you've made it into the right half of the diagram! The error will be somewhere here:

If you set your mesh_entity.ent to point at a vanilla mesh, you can rule out your custom mesh and .mlsetup as a source of errors. Original game meshes will always have a working default appearance and will thus always be displayed!

The game crashes!

That means the chain is working, but something isn't loaded correctly. That's good! Check the following files:

  • appearance.app: Check the partsValues and partsOverrides entries. They need to point at the mesh_entity.ent, not at the mesh.

  • mesh_entity.ent: Does the component entry point to a valid mesh? Try it with a default mesh as detailed above.

If the default mesh is displayed correctly, then we have narrowed down the problem.

If the default mesh is not displayed correctly, then there's an issue between the root_entity and your .app file, or in the .app file's internal logic.

Troubleshooting a mesh

For more detailed error handling, check the sections below, or check this page.

ℹ In the "Mesh Preview" tab of your mesh, you can "Generate Materials for Appearance". If the correct colours show up, you can at least rule out that the error is in the .*mesh or its material.

  • Make sure that you have the same number of entries in materialEntries and localMaterialBuffer.materials .

  • Go through the CMaterialInstances in localMaterialBuffer.materials.

    • Make sure that the files you're loading exist.

    • Make sure that you don't load a mlmask under a key for an mlsetup or vice versa.

If none of that helps, I suggest

  • doing a gdb export

  • throwing away your mesh (don't close the WKit tab yet), falling back to the original one

  • doing a gdb import

  • replacing the arrays appearances, localMaterialBuffer.materials and materialEntries with those from your previous mesh.

My mesh is black and shiny!

Congratulations, this is about the easiest-to-resolve error that you could've had. Your mesh is loaded correctly, there is only a problem with the rendered material.

Check your mesh file:

  • Check the connection between appearance, materialEntry and localMaterial.CMaterialInstance. Are the names correct?

  • Go through the CMaterialInstances in localMaterialBuffer.materials.

    • Make sure that the files you're loading exist.

    • Make sure that you don't load a mlmask under a key for an mlsetup or vice versa.

My mesh has the wrong appearance!

Either an appearance is incorrectly selected, or it is incorrectly resolved. Check the following places for copy-paste/duplication mistakes:

yourModName.yaml - is the appearanceName correct, or did you forget to change it? rootentity.ent - does the name corresponding to the field above point to the appearanceName with the right name in the right appearance file? appearance.app - does the appearance's partOverride set the correct appearance in the componentsOverride?

Now, check the mesh file (close and re-open it to make everything refresh):

appearance - does it use the correctly named material? materialEntries - is the index correct, or is it pointing at the index of the actually displayed material? localMaterialBuffer - does the CMaterialInstance use the correct .mlsetup file?

Finally, check the .mlsetup: does it actually use different colours, or is it just a duplicate?

My mesh is invisible!

Here we go. This is the big one, and it's Not Fun. The error can be anywhere between the yaml and the mesh. You can rule out one of the files with the following question:

Does the glitching stop after <10 seconds? If not: the appearance can't be resolved - ignore the .mesh If yes: the appearance is resolved, but can't be displayed - ignore the .yaml

The fastest way to find your error is Wolvenkit's FileValidation (in version >= 8.9.1). Save the root_entity.ent, and the recursive valudation will check the whole chain for errors and print them to the log files for you.

As of July 2023, you can download the right version from the Nightly page (for example this one, as it's pretty stable).

ℹIf the appearance is resolved, but not displayed (short glitch), the first thing you should do is to change the path in the mesh_entity.ent to one of the game's default meshes. This will rule out errors on your part. (Yes, even if your mesh worked in another mod. No, I'm not speaking from experience, why do you ask?)

If the hint above doesn't solve it, proceed to troubleshoot in the same way as "My mesh has the wrong appearance!" above.

My garment tucks into/under other garments incorrectly

That's due to garment support - check the link to learn more.

Visual tags aren't working!

If you are hiding components via visual tags, these tags have to go into the appearance file rather than the root entity.

I can't find anything, kill me now

Time to restore your files one by one to the last working backup and restart from there. Don't delete them, keep them in a different folder - you will be able to copy a lot of stuff over.

By right-clicking on a tab title, you can move it to a new document group for easier copying.

Good luck, soldier.

Last updated

#647: Add info on downloading Phantom Liberty DLC files for rollback

Change request updated