Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
An item addition with dynamic appearances, and what you can do for this
Published: 29 Oct. 2023 by Last documented update: Jul 05 2024 by
This guide will cover a sub-case of Adding new itemsvia ArchiveXL (added in 1.13). Dynamic variants are both easier and more flexible. Unless you don't need different appearances, you will want to default to this approach.
If you are an absolute beginner who has never done this before, check out Adding new items. The guide will tell you when to switch over.
You can find the technical documentation for dynamic variants on ArchiveXL's github.
If you want to create an Atelier store, see Your own Atelier Store
To quickly generate instances with up to two keys, check out W's generator (Codepen.IO)
You need at least the following tools and versions (get the most recent):
WolvenKit >= 8.11.0 (you should have it )
TweakXL >= 1.4.4
ArchiveXL >= 1.5.0
Red4ext >= 1.17.0
Cyber Engine Tweaks (for spawning items)
You define an appearance as dynamic by adding the DynamicAppearance
tag to the visual tags in its root entity.
If you don't know what that means yet, read on — it will hopefully become clear soon.
TL;DR: It just is, source: trust me bro. Proceed to the next section.
With vanilla item additions, you need one entry in the root entity per suffix. This gets out of hand quickly. When making stockings, there are four feet states (flat
, flat_shoes
, lifted
and high_heels
), and two body genders (Male
and Female
) . That leads to 4x2 entries for a single item.
For 15 appearances (colour variants) per mesh, I (manavortex) ended up with
120 entries in the root entity (4*15 per body gender)
120 entries in the .app file, (4*15 per body gender)
six mesh_entity files (flat
, lifted
, and heels
for each body gender. I used the same for flat
and flat_shoes
, or I'd have ended up with eight.)
The most frustrating part was that everything was just duplication. Each set of entries in the .app file would only differ by name (_pwa
and _pma
to select it from the root entity), and the mesh entity path in partValues
. Everything else was virtually identical, but I had to copy-paste and maintain 120 entries.
I cried to psiberx, who went and made the problem go away.
Dynamic variants put the logic into the mesh entity
file. Instead of defining appearances with suffixes, I can conditionally define which component gets loaded, and ArchiveXL does the rest.
number of root_entity entries
120
1
number of .app entries
120
1
number of mesh entity files
6
1
number of components per mesh entity
2
5
If you still aren't convinced, go to Adding new items and start duplicating entries. Everyone else, to the batmobile!
This guide contains the minimal amount of fluff and will link background information rather than giving it. Any links will tell you what you're supposed to read.
For that reason, you shouldn't skip or skim unless the section tells you that it's optional.
That being said, make sure to check the section
This guide assumes that you have access to the prepared example project, so go and grab it.
Find the template project on Nexus.
Download it and extract the files to your project's root folder, so that the source
directory merges with the existing one.
You will be able to change the template project just by following the steps, but if you want to make your own mods, then you're going to want to understand this.
Depending on how you learn best, you can also fuck around and try to understand the connections yourself. In that case, check #exercise-1-create-more-records at the end of the section.
For a general explanation of what the yaml file does, check #the-control-file-yourmodname.yaml. This section will only cover the differences between a dynamic and a regular yaml.
This file contains the biggest part of the dynamic magic.
This is your dynamic project's yaml file, minus any properties that aren't influenced by the dynamic appearances:
This section will explain how that works - except for the appearanceName, you will find that in #the-root_entity.
TweakXL will generate one record per entry in $instances
, according to the rules that you're using in the item name. This happens via property interpolation.
The example above will generate three item entries by substituting $(property_name)
with the value of the property from the entry. If that isn't clear enough, check the example and the resulting item codes at the end of the line.
Like the record names, the displayName
property is also generated for each entry:
All you need to do is to make sure that such an entry exists in your localization file.
The icon name in the record is also generated for each entry. They are all using the same inkatlas, but you can generate that as well if you want - I've done it for the Netrunner suits, since I needed more than 100 icons.
The only important thing here is that the naming follows your inkatlas file's slot definitions.
If you want to make gendered icons, please check Gendered preview icons -> #does-this-work-with-dynamic-variants
With clever hook-ups in the mesh entity, you can set up your items so that they can be changed with a simple .yaml
edit — that means, the user can switch out the ribbon colour without ever starting Wolvenkit!
We'll use that here to enable "hidden" appearances.
I have hooked up the example project to support two base colours:
black
white
and three ribbon colors:
red
blue
green
By editing the $instances
block in the .yaml
, you should be able to spawn 6 different shirt in the game without touching any of the additional files!
For a general explanation of the root entity, check #root_entity.ent. This section will only cover the differences between a dynamic and a regular root entity.
This is where you enable the feature by adding the tag DynamicAppearance
to the visualTagsSchema
(the last entry in the file):
For dynamic appearances, your root_entity
file will contain one entry. Each item should have its own root entity.
The appearance name in the root entity corresponds to the appearanceName
property in the .yaml
without the variant:
You can leave the appearanceName
blank. In that case, ArchiveXL will look for an appearance with the same name as the name
attribute.
Since the appearance in the .app is called app_file_dynamic_appearance
for clarity, and there is no root_entity_dynamic_appearance_
in the .app, this will not work for the example project.
For a general explanation of the .app file, check #appearance.app. This section will only cover the differences between a dynamic and a regular .app file.
For dynamic variants, components in the .app file will be ignored. You have to use a mesh entity.
You can define appearances for different circumstances by changing the appearance names. This will let you influence the mesh entity even further by e.g. hiding parts of the mesh via #chunkmask. And the best part is: you don't even need to touch your root entity.
In the context of our example project, this means that you can define your appearances like this:
app_file_dynamic_appearance
Your regular appearance. Is displayed when none of the conditional ones apply.
app_file_dynamic_appearance&camera=tpp
This is only active in third person perspective. The item will be completely invisible in first person.
app_file_dynamic_appearance&camera=fpp
app_file_dynamic_appearance&gender=male
For a general explanation of the mesh entity, check #mesh_entity.ent. This section will only cover the differences between a dynamic and a regular mesh entity.
Unless you are using #app-file-conditional-switching, this is where the magic happens.
Like appearance definition names, components in the mesh entity support #ent-file-conditional-switching. On top of that, they also support #substitutions.
Check #the-diagram's bottom left corner for a demonstration of both, or read up the ArchiveXL documentation on how they work.
In your mesh entity, you can use substitutions in path names to load different meshes. This is better than #ent-file-conditional-switching because it won't create extra components.
To enable substitution, your depot path must begin with an asterisk *
. Each substitution needs to be enclosed in braces, e.g. {gender}
.
For a list, check #which-substitutions-exist
ArchiveXL will create all components, hiding those that aren't matched by your current conditions. If possible, use #substitutions instead.
Just like in the .app file, you can apply conditional switching to component names. It works exactly like #app-file-conditional-switching:
Now let's look at what we just did and check the diagram. You'll see that the control files are almost identical to the vanilla variants, but that the rest of the files has gotten a lot more manageable:
And that's it! With this and the original guide, you should hopefully be able to add items to your heart's content!
I have written a Python script to auto-generate display names, you can find it on my github. If you don't know how to use this, check Running Python Scripts.
Please see the original guide's #troubleshootingsection.
Create a
If you your project, you can immediately spawn them in Cyberpunk via Cyber Engine Tweaks:
This becomes active whenever you are in first person perspective. You'll usually want this to via .
You shouldn't do this — instead, use in the mesh file path.
can help you spot errors in your paths.
How dynamic appearances can use different meshes/submeshes in a single root entity file.
Published: Sep 09 2024 by Sumi Last documented edit: Sep 09 2024 by manavortex
This page is an extension of ItemAdditions: Dynamic Appearances and explains how to fine-tune item visibility conditions beyond the basic scope.
You can use yaml instances to create different appearance names. These let you use different root entity entries which can point at different appearances in the .app file – letting you use partsOverride
to show or hide different parts of your item!
Let's look at an example.
We're adding the type
parameter to the custom t-shirt's definition array.
Since the variants
only start after the exclamation mark, we can generate different appearance names:
before:
after:
This will look up the following names in your root entity:
root_entity_dynamic_appearance_sleeves_
root_entity_dynamic_appearance_nosleeves_
Then you would add the following entries to your .app
file with the name
s :
root_entity_dynamic_appearance_sleeves_
root_entity_dynamic_appearance_nosleeves_
Now you have options. The next step will depend on your goals. In the .app
file, you could use partsOverrides
to hide different parts of the mesh for each appearance (like the sleeve submesh for the no-sleeve version. See Chunkmasks: partially hiding meshes), or you could set partsValues
to different mesh.ent
files (like a standard and looser-fitting version).
Yes, probably. During your exploration of the wiki you will likely come across many different ways to create item variants. The benefit is that you don't have to manage as many root entity files, but it's just a matter of preference and what works best for your project.
How to set up the folder structure from scratch
Created: by @manavortex Last documented edit: June 10 2023
This page is a part of the Adding new items guide and deals with finding the correct files for an ArchiveXL item addition.
For an explanation of the file structure, see ItemAdditions: File structure explained.
If you want to add an atelier store, see Your own Atelier Store.
If you want to add preview items, check Your own inventory preview icons.
If you want to port a mesh from a different game to Cyberpunk, check Porting 3d objects to Cyberpunk
TL;DR: If you can't be arsed doing this by yourself, find a template project with one working item (female rigged) here.
rootentity.ent
base\gameplay\items\equipment\underwear\player_underwear_item.ent
appearance.app
base\gameplay\items\equipment\underwear\appearances\player_underwear_item_appearances.app
mesh_entity.ent
⚠
Check the red hint box ⚠
base\characters\garment\player_equipment\torso\t1_080_pwa_tank__judy.ent
my_mesh.mesh
base\characters\garment\gang_monk\torso\t2_135_jacket__monk_shirt\t2_135_wa_jacket__monk_shirt.mesh
my_tshirt_factory.csv
base\gameplay\factories\items\clothing.csv
translation_strings.json
base\localization\en-us\onscreens\onscreens.json
preview_icons.inkatlas
base\gameplay\gui\common\icons\items\item_icons6.inkatlas
preview_icons.xbm
base\gameplay\gui\common\icons\items\item_icons6.xbm
tutorial_my_custom_tshirt.archive.xl
Wolvenkit -> New File -> ArchiveXL
tutorial_my_custom_tshirt.yaml
Wolvenkit -> New File -> TweakXL
For mesh_entity.ent,
your entity file needs to correspond to your item's body part. If you put a shirt in an entity file for shoes, it will deform badly once you put it on.
If you rename your components, we recommend using CDPR's naming prefixes for reasons of garmentSupport. You don't need to understand how this works, just name your component like l1_myCustomPants
instead of myCustomPants
and call it a day.
For further details, check here.
It is good practice to keep local copies of everything that you change (=> custompathing
) instead of overwriting files under base
. This makes sure that no other mods will overwrite your changes.
ℹ Only keep files under base
if you are okay with them being overwritten!
Open the file translation_strings.json
in WolvenKit.
Expand the array root
and then the array entries
. Delete all entries but one.
Open the file my_shirt_factory.csv
in WolvenKit.
In compiledData
, delete all entries but one. In data
, delete everything - these will get autogenerated.
Open the file root_entity.ent
.
Expand the list appearances
. Delete all entries but the first (most likely default
).
Open the file my_custom_shirt.app
.
Expand the list appearances
. Delete all entries but default
.
Open the file mesh_entity.ent
Select resolvedDependencies
and delete all the entries. (We don't need Judy's top anymore.)
Make a back-up copy of your t1_custom_shirt.mesh
, then open it.
Expand the first appearances
at the top of the file. Open the appearance default
and check which material is linked in the chunkMaterials
array.
Now is a good time for a backup.
How to determine the item type
Created & Published: June 10 2023 by @manavortex
This page is a part of the Adding new items guide and contains the steps necessary to create different equipment types.
For an overview of prefixes for the different component types, see here.
TL;DR:
Change equipmentSlot
in the yaml (for options, see Step 1)
Replace the mesh_entity
(see Step 2)
Replace the .mesh
(e.g., instead of a shirt, find in-game shoes)
Optional: Port an external item
You define the item slot in your .yaml file by specifying the root entry type via a $base
record. Base records come in many different types, some include intrinsic modifiers that add slight stat improvements to items, or add special sound to items. A complete page with clothing items, their intrinsic modifier, and their baseids can be found on the official Cyberpunk 2077 wiki's article for clothing here.
You can use the following base types:
Head
Helmet,
HelmetHair,
Helmet_Intrinsic, HelmetHair_Intrinsic,
Helmet_EP1_Intrinsic_Armor,
Helmet_EP1_Intrinsic_Runner,
Helmet_EP1_Intrinsic_ExplosionDmg,
Helmet_EP1_Intrinsic_Zoom,
Hat,
Cap,
Scarf,
ScarfHair,
Balaclava,
Balaclava_Intrinsic
Face
Glasses, Mask, Mask_Intrinsic, Visor,
Visor_Intrinsic_QH,
Visor_Intrinsic_Zoom, Tech, Tech_Intrinsic_Zoom
Outer Torso
Coat, Coat_Intrinsic, Dress, FormalJacket, FormalJacket_Intrinsic, Jacket, Jacket_Intrinsic_Armor, Jumpsuit, Jumpsuit_Intrinsic,
LooseShirt, Vest, Vest_Intrinsic_Armor, Vest_Intrinsic_Reload, Vest_EP1_Intrinsic_Armor, Vest_EP1_Intrinsic_Grenade, Vest_EP1_Intrinsic_Inhaler
Inner Torso
FormalShirt,
Shirt, TankTop,
TightJumpsuit, TightJumpsuit_Intrinsic,
TShirt, Undershirt, Undershirt_Intrinsic
Legs
FormalPants, Pants Pants_Intrinsic_Armor, Pants_Intrinsic_Carry,
Shorts, Skirt
Feet
Boots, Boots_Intrinsic, CasualShoes, FormalShoes
Special
Outfit, Outfit_EP1
You can absolutely set up a shirt and then put $base: Items.GenericHeadClothing
- V is the only person I know of who can wear their undies on their head without impairing their functionality.
However, before you start abusing the system that way, you might want to look into EquipmentEx.
psiberx's mod EquipmentEx (github | nexus) adds a whole new wardrobe system, providing extra slots that CDPR forgot to include with the basegame. This feature requires the mod to be installed — without it, only the $base
types from step 1 will be considered.
All you need to do is adding the last two lines to your .yaml:
Find a full list of outfit slots in the github readme.
Some item properties are defined in the file mesh_entity.ent
via components. If you use the wrong kind of entity, you might end up with your shirt being a puddle around your feet, or string cheese. To get around that, you need to make sure to pick a file that correspond's to your item's body part.
You can find all entity files under base\characters\garment\player_equipment:
If you want to be super thorough, you can stick to the right gender
If you want to know more about components, check the wiki page. This is completely unnecessary for the purpose of this guide!
You can hide items most easily via ArchiveXL tag. Check the linked page for how to do that.
To find the correct tags for footstep sounds, check ArchiveXL: Tags -> #footsteps-setting-footwear-sounds.
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
:
{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!
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:
No more replacers! Add your own gear with TweakXL and ArchiveXL
Created & Published: November 04 2022 by @manavortex Last documented Update: July 05 2024 by manavortex
This guide will walk you through adding your own items to Cyberpunk 2077, which can then be spawned via console.
It has been verified with the following versions (yours should be equal or higher)
8.12.1
8.9.0
1.5.2
1.1.4
1.8.1
1.4.3
1.18.0
1.12.0
1.28.1
1.28.1
Assumed skill level: You should be able to find your way around WolvenKit, but I aim to keep this as noob-friendly as possible. In case you prefer visual learning, there is also a video version of this guide available here - https://www.youtube.com/watch?v=r3nyFm-9h9o&t=3s
This guide will give you a working mod with a very basic structure. In the section #great-you-added-items-now-what, you're guided through various processes that will help you to understand how things connect, and teach you how to use ArchiveXL to add your own items.
For experienced modders
I have repeatedly observed that newbies are fine with this guide, while people who know how to mod are not. Watch out for boxes like this one to avoid those pitfalls.
The guide was created after reading this one and being left with a bunch of question marks. This guide is horribly outdated and I'm only citing it here because it got me started into the rabbit hole. To get a deeper understanding of the process, you can follow the linked resources, or consult ArchiveXL's documentation.
Visual learners rejoice: You can find a video of this guide on youtube (https://www.youtube.com/watch?v=r3nyFm-9h9o)
To troubleshoot your ArchiveXL mods, you can use 's .
If you want to convert a mod to dynamic appearances, check the ArchiveXL: Dynamic conversion guide
If you want to use dynamic appearances out of the box, check ItemAdditions: Dynamic Appearances (this is the preferred approach as soon as you're creating different options).
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.
⚠ Do not edit those files outside of WolvenKit, and whatever you do, do not let Microsoft Excel touch the clothing.csv! ⚠
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.
We're starting with a dry run to get you familiar with the process.
Wipe the folder packed
Copy all supported file entries from source
to their destination under packed
Copy all files under packed
into your game directory (it will overwrite without prompting)
Now, you can
Launch the game.
Spawn one of the tutorial items via Cyber Engine Tweaks and equip it:
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 all mods are installed correctly before continuing with #great-you-added-items-now-what
Before you can publish your mod, you must complete the steps at #the-final-touches.
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'll want to keep reading.
If you want to have many colours or both body genders:
Do yourself a favour and use ItemAdditions: Dynamic Appearances.
You might have been given the Easy Item Additions tool, or you might be familiar with older tutorials. Please believe me: even doing this by hand is less effort than filling out all the fields.
To familiarize yourself with the process, you can follow the ArchiveXL: Dynamic conversion guide and convert the example project.
Otherwise, you will want to complete one or more of the following steps:
change the mod to use Different equipment slots (e.g. shoes or glasses)
Learn about #variants-and-suffixesfor e.g. #adding-a-male-instance or check the #hiding-body-parts-diagram
Learn about making more variants:#adding-an-appearance
Create Your own Atelier Store
Learn about Porting 3d objects to Cyberpunk
To start changing the existing files, check the ItemAdditions: File structure explained page for "Making Changes
" headers.
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 connecting lines.
You can find a breakdown-by-entry on the corresponding wiki page.
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.
Before you add an appearance, make sure that your item is loading up correctly and looking as expected. If you have to debug, you will have to look through every appearance you made!
For experienced modders: This includes you! :)
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:
*.yaml: Adding an entry
appearance.app: Adding a mapping between root_entity and mesh's appearance
root_entity.ent: Adding a mapping between yaml's appearance and app's appearance
*.mesh:
Adding a MeshMaterialEntry
Adding a MaterialInstance
Adding a material
Connecting those things
For a diagram of how everything connects, go here.
Duplicate the entire appearance block for an already working item. ⚠Mind the indent!
Change the first line to a unique name like Items.my_custom_shirt_blueblack
Set the new appearance name for the root_entity.ent
appearanceName: appearance_root_entity_black_blue
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.
ℹIf you make any mistakes here, the worst that happens is an empty string.
Now, add a new entrie to your .json file:
The total entry should look like this:
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.
Find the step-by-step guide in the appearance section on the "Item structure explained" page
This tutorial assumes you already know how to recolour an item. Quick reminder about the mlsetup:
Export it to json
edit the mlsetup.json
with the MLSetupBuilder
Import it back
Find the step-by-step guide in the mesh file section on the "Item structure explained" page
Now, log into the game and spawn the item variant. The name is the header you defined in the yaml file, in this case
If it works, this is an excellent moment to take a backup! If not, check #troubleshooting at the end of the page, fix your problem, and make a backup after.
This is a great opportunity to switch over to the ItemAdditions: Dynamic Appearances approach.
For a step-by-step guide on how to convert your mod, checkArchiveXL: Dynamic conversion guide.
If an item is rigged for the female body gender, it will look wonky if worn by a male-rigged V. (But we have a snarky tooltip, so that's OK!)
This section of the guide will teach you how to fix that, adding versions for both body genders.
Screenshots in this part of the mod may be outdated.
To keep things simple, we'll be using a different mesh here, rather than walking you through the whole refitting and conversion process. If you want to do that, you can check out
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.
If you plan on using other meshes for your mod, ensure that they have _ma_
or _pma_
in their name.
Keep in mind that some ma
meshes may still have clipping issues when paired with certain types of clothing, while pma
meshes are specifically designed for V and don't have this problem.
If you decide to create your own mesh, be sure to fix any potential issues before using it in your mod. Check out our 3D modeling guide for helpful tips and resources.
Remember, a little extra effort in the beginning can save you a lot of headaches down the line!
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.
To avoid any issues, it's crucial to pay close attention to this step and double-check that the correct materials are present in the localMaterialBuffer
and materialEntries
, and that the indices are adjusted correctly.
This will ensure that your mod works as intended without any glitches or errors. If you need a refresher, click here to return to that section.
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
.
Inside the mesh_entity_m.ent
file, find the first component of the type entGarmentSkinnedMeshComponent
. Set the following values:
Inside the yourModName.yaml
file set the appearanceSuffixes
array to itemsFactoryAppearanceSuffix.Gender
If you are unclear about why this step was taken, we recommend reading up on suffixes!
Find the array appearances
.
Expand the first entry.
Append &Female to the name attribute. This will change the name from appearance_root_entity_white_red
to appearance_root_entity_white_red&Female
.
Duplicate the first (and only) entry to create a new one.
Expand the newly create entry
Set name : appearance_root_entity_white_red&Male
.
Set appearanceName : my_shirt_m
.
Find the array appearances
Duplicate the first entry to create a new one and expand it
Set the name
attribute to my_shirt_m
(as defined in the root_entity)
Find the array partsValues
Set the resource path to your new male mesh entity file:
resource : tutorial\myshirt\mesh_entity_m.ent
Find the array partsOverrides
Find the array componentOverrides
Set componentName : my_shirt_m
Set partResources : tutorial\torso\my_custom_shirt\mesh_entity_m.ent
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.
Consider reviewing the guide to ensure that all steps have been followed correctly and that the values have been set appropriately. Ensure that the mesh is compatible with the male variant of V. If errors persist, review the troubleshooting section for further assistance.
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.
That's it! If everything works, you're done!
Before starting to troubleshoot, make sure that you have all the requirements installed — Red4ext, ArchiveXL and TweakXL.
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
You have read right past those warning boxes telling you about component name prefixes. Make sure that you add them back.
... 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!
Before you start digging into your file structure, check if there are any leftover yaml files from earlier versions/deploys in your tweaks directory. Do a full text search in e.g. Notepad++ in any files in the folder with the name of the item you want to spawn.
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? You can use yamllint to check.
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\root_entity.ent
in the picture above)
If you moved the root_entity.ent
, you have to adjust this entry.
root_entity.ent:
Do you have an appearance with the name
matching your item's appearanceName
in the yaml?
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
.
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? You can use yamllint to check.
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 single quotes!
If the field for primary_key
is not empty, then its value must be unique (probably on a per-file basis). Set it to 0.
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!
There is a short glitch (or maybe not), but the previous item is still visible, and nothing happens. Or, for head items, V is bald all of a sudden because their hair is gone.
Let's check if the game finds your root entity. For that, we'll do two things (don't forget to un-do them later):
Change the base type
Add a tag to the root entity
Helmets are hiding hair by default, unless you tell them not to. We'll make use of that by changing your item's $base
in the .yaml
:
In your root entity
, open visualTagsSchema
-> visualTags
-> tags
(create any entries that are missing) and add the following CName:
You can now start the game and equip your item again.
Your root entity is working, and the error is somewhere here:
Your root entity is not recognized and the error is somewhere here:
Try using other equipment slots
, just to check. E.g., if your item is a face item (mask), set its $base
in the yaml to e.g. Items.GenericOuterChestClothing
You have an incorrect material assigned. Check your chunkMaterials in the mesh.
No, it does not. You have an incorrect material assigned. (And I'm totally not writing this after 3 hours of troubleshooting -.-)
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.
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.
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 an original game item
doing a gdb import
replacing the arrays appearances
, localMaterialBuffer.materials
and materialEntries
with those from your previous mesh.
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.
Either an appearance is incorrectly selected (app file), or it is incorrectly resolved (mesh file). Check the following places for copy-paste/duplication mistakes:
yourModName.yaml - is the appearanceName
correct, or did you forget to change it?
If you are not using dynamic variants, also check the following two files:
root_entity.ent - does the name
corresponding to the field above point to the right appearanceName
in the right .app 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 - do the chunk entries point to the material that you want?
materialEntries - is the index correct, or is it pointing at a different material?
localMaterialBuffer - does the CMaterialInstance
use the correct .mlsetup
file?
Finally, check the .mlsetup
itself: does it actually use different colours, or is it just a duplicate?
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 questions:
Does file validation yell at you?
If not: The error is between the yaml and the root entity. Check the .yaml
, the .xl
, and the root entity
itself. The most common cause are incorrectly spelled appearanceName
s.
If yes: Unless the errors are warnings, fix them first.
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.
That's due to garment support - check the link to learn more.
If you are hiding components via visual tags, these tags have to go into the .app
file rather than the root entity
. File validation should complain about this.
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.
Tutorial for gonks
Published: December 2023 by destinybu Last documented edit: Feb 07 2024 by
We'll be making a fully featured new Iconic weapon in this guide, which is designed for first-timers and goes into details into every aspect about weapon modding. (not appearances)
You can find another guide about this topic under
For an overview of weapon properties, check
For an overview of weapon audio profiles, check
Before beginning, ensure you have the following software installed and properly set up:
WolvenKit (8.12+) -
MLSB (MultiLayerSetupBuilder 1.6.7+) -
A text editor: or, if you want to get fancy,
Cyberpunk 2077 - 😑
Core mods: , ,
Optional: ,
Each Iconic weapon is a variant of a base weapon, with an hidden (from the player) mod. This "hidden" mod contains a statModifiers array (to list all the stat changes this Iconic will have from the base weapon) and an OnAttach array. The OnAttach array is where you'll want a GameplayLogicPackage to go. You may or may not need to define conditional effectors in there, but if you want your weapon to have the customary Iconic yellow description then be aware that there is where it's written (in the UIData of the GameplayLogicPackage).
The rest of this guide will hold your hand through a deep dive, step-by-step, of your first custom Iconic made from zero. If you get lost through it, or if you'd rather find your own flow, you'll be well served by returning to check the code of an Iconic weapon already in the game (as you'll be building up from a base weapon in the same way, and it's solid footing).
Start by opening WolvenKit and create a new project. This will be the base for your new iconic weapon mod.
Decide on the weapon you want to modify to make a new new iconic.
After locating the Unity gun in the tweak browser, right-click on the item and select "Add TweakXL Override". This allows you to modify and customize the weapon’s attributes to create your new iconic weapon.
For first time modders, understanding all this in one go will be difficult. You can just keep these explanations handy and revisit them when required.
The .yaml file may seem complex at first glance, but the actual structure is extremely simple. Your weapon has properties – those stand on the left side of the :
, such as ammo
. The properties have different values, and those stand on the right side of the :
, such as Ammo.RifleAmmo
.
Making a new weapon is fairly simple. In your tweak file, change the Item ID in the very first line to "Items.Hand_Of_Midas" and save (Hotkey: Ctrl+S
).
That's it, you've created a new weapon now. This weapon will look & behave exactly like the Unity handgun, but trust me, it's new.
To test it out, boot up your game and load any save.
Type in the command below and hit Enter.
You can now see your newly created weapon in your inventory.
Unfortunately, there is no way to tell it apart from the Unity handgun.
We'll get to fixing that, but first, a little cleanup: open up your WolvenKit & rename your overridden tweak file to "hand_of_midas.yaml". We will store all the edits that need to be done to our new weapon in this file.
Let's change something that will differentiate our weapon from the default Unity.
To do this, open your renamed tweak file & find the crosshair
tag (hotkey: Ctrl+F
). Replace it as shown below, and save your file.
Now hot reload your game (Insert how to link here) or close it, reinstall your mod in WolvenKit & relaunch your game (From here on, this will be referred to as hot reload).
Spawn in both the Unity & Hand of Midas using the CET console:
You should now be able to see that both the Unity & Hand Of Midas, although otherwise identical, now have different crosshairs.
How do we know that it's called "Crosshairs.Tech_Round" ?
If you have the REDmod DLC installed, you can use a text editor like Notepad++ to do a full-text search under Cyberpunk 2077/tools/REDmod
. By searching for crosshair:
, you can find all value assignments in the game files.
By searching for "Crosshairs." in the Tweak Browser. Most things we find inside the weapon tweak will be searchable within the Tweak Browser, and some within the Asset Browser.
Editing the Tweak will allow us to modify all of our gun's behaviors, and I encourage you to play around with these.
We're only changing a single property in the Hand of Midas. For that, we have a tweak file with more than 200 lines of code. Can't we do this in a better way?
We can, and we should!
As shown above, when using $type
to define a tweak, we need to add all the required properties for the type, but when using $base to define one, we only need to add the properties we are changing, the rest are taken from the parent.
Now go ahead and change it so we use a $base
& only define the crosshair. Your entire tweak should now look like this:
What good is a new gun without a new name? We need to tell our game about these.
Open your WolvenKit project and navigate to the archive folder
Create a new folder named after your mod, for example midas_collection
Within this folder, make a subfolder named localization
In your full tweak file, search for the field called displayName
. You'll likely encounter something like displayName: LocKey#49794
.
This connects the displayName property of your item with a locaization key, which is the mechanism that the game uses to support multiple languages. Think of the LocKey
of a list entry, with different lists being used for different languages.
Open the file in Wolvenkit and create a new entry in localizationPersistenceOnScreenEntry
. It has the following properties:
secondaryKey
s must be globally unique, or they will overwrite each other.
Create another entry with the secondaryKey of MC_gun_description
and write a little fluff text for the description.
In your WolvenKit project, go to the resources folder and create a plain text file with the following contents:
Rename this file to midas_collection.archive.xl
.
Wolvenkit will move the .xl file to the same directory as your mod's .archive file, where ArchiveXL will see and process it.
Next, revisit your "hand_of_midas" tweak file to establish the weapon's name and description in the game.
Add the following lines under the existing properties:
This localizedDescription:
is not the yellow text you see on the weapon, but the red-colored description that is shown in the Inspect screen.
The text that is shown (as yellow-colored) on the weapon is instead defined in the UIData
of the Iconic Mod (at Step 12)
These lines set the display name and the description of your weapon using the keys defined in your localization file. The values on the right side of the :
must match the secondaryKey
values from your en-us.json
file and be globally unique.
After completing these steps, install your mod and launch the game. Your new weapon, "Hand Of Midas", should now appear with its unique name and description, fully integrated into Cyberpunk 2077's multi-language environment.
To elevate the 'Hand of Midas' to its iconic status, we need to modify the .yaml
again, where we set all of the gun's unique features:
The new things you're seeing are arrays
, which is a technical term — you can think of them as lists, since they can hold multiple items.
statModifiers
will hold all the stats for your gun. from recoil to damage. Since the $base: Items.Preset_Unity_Default
already defines statModifiers
, and we'd like to keep those.
So we're adding an entry to the list, using!append-once
followed by the new entry Quality.IconicItem
.
This makes the weapon iconic, which means:
it has a fancy golden background
there's a dialogue box when you disassemble it
To prevent it from being disassembled, we also add IconicWeapon
to its tags
array.
We make sure that the weapon updates correctly by setting the
What exactly it does is somewhat of a mystery, so let me know if you find out.
Once these modifications are in place, install your mod and enjoy the newfound Iconic status of the 'Hand of Midas' in the game.
Technically, you've already made a new Iconic weapon & I should call quits on this tutorial, but it's never as easy as that, is it? Give yourself a pat on the back & onto the next step.
Let's talk theme.
The gun is called Hand Of Midas, so it would be fitting to have the gun sounds be more… gold-ish, right? How do we achieve this?
We could add custom sounds using RedMod, but due to how that works, we could end up with conflicts that we don't want to bother with. So let's look for guns that already have a sound like that.
Dex's gun Items.Preset_Liberty_Dex
already has a nice metallic ring to it, so let's just steal its sound effect. To do this, find the gun in Tweak Browser and look for the property audioName
.
Now add this value to your weapon tweak as shown below.
Install your mod and test it out, Hand Of Midas now sounds metallic like we intended it to.
So now let's make it completely overpowered and take all fun out of using it!
Joking. Let's talk about how we can avoid that trap.
The 'Hand of Midas' is envisioned to be a unique piece with its own character - ideal for players who relish precision and skill. So we need strengths and limitations to give it a clear identity. Here's how we achieve this:
Increased Recoil: This adds a layer of complexity and skill. High recoil means each shot requires careful consideration, appealing to players who enjoy a challenge and the satisfaction of mastering a weapon.
Smaller Magazine Size & Increased Reload Time: Every bullet counts. A smaller magazine encourages accuracy over spray-and-pray, and a longer reload time not only adds a strategic layer to combat but also gives players time to appreciate the weapon's aesthetics.
In summary, these design choices don't just balance the weapon; they enhance its identity. The "flaws" don't destroy the gun — instead, they contribute to making the 'Hand of Midas' feel powerful and rewarding for those who can wield it effectively.
Building on Strengths
Once the limitations are set, focus on the weapon's strengths to complement its defined character.
Increased Headshot Damage & Crit Chance: This change rewards accuracy and skill, making the weapon ideal for players who excel in precision shooting.
Increased Zoom on ADS & Extended Effective Range: Enhances the weapon's utility in long-range combat, aligning with its identity as a sharpshooter's choice.
To change the stats discussed in the step above, we again need to tinker with the statModifiers
& statModifierGroups
in your weapon tweak. Open up the tweak for Items.Preset_Unity_Default
and navigate till you find the two arrays.
You can add the code below to a new tweak (.yaml
) file, or add it to your weapon's file.
To change the gun's recoil, we'll add a new statModifierGroup
tweak as shown below
Now add this stat group to your weapon's tweak (see the last line).
Install your mod, launch the game and test your changes. You should see that the gun's recoil is increased, but doesn't feel overwhelming.
You now know how to change your weapon's behavior. Play around & discover other stats and modify your gun to make it feel unique.
Stats can be added individually to statModifiers
or in groups to statModifierGroups
.
After a bit of tinkering, this is what my weapon tweak now looks like (expand the box below):
There are a lot of values to play around with in a tweak file. You are often better off leaving most of them alone. These are some properties you probably should look at when designing a gun.
Blueprint
Item Quality
Buy & Sell Price
The main thing that makes an iconic weapon so special is its iconic mod. These are like any other weapon mod, but hidden from the UI. Before you start hacking up your own, it is very important you have a look at the existing Iconic Mods in game.
For now, let's look at Items.Preset_Lexington_Wilson
(also known as "Dying Night").
A big part of tweak modding is exploration — poking through tweaks until you find just the right thing to copy or change, or looking for something specific in hundreds of files.
We'll end up with WilsonWeaponModAbility
, which defines the abilities and stats that we care about.
Condition: Prereqs.ProcessHitTriggered - Does the bullet hit anything? Effect: MultiplyDamageWithVelocity - Increases the guns damage with 25% if the Player velocity is greater than 10.
Condition: Perks.IsHitQuickMelee - Is the attack a Quick Melee attack? Effect: MultiplyDamage - Increase damage by 50%
Since our weapon demands perfection, we'll punish the player for not hitting headshots & reward them for hitting headshots. And because we want to make it hurt, we'll use HP reduction & Healing rewards.
You can add the tweaks below to your weapon's file or create a new tweak file.
In this section, we first define our special ability Cranial_Cashback
:
The ability contains
the description for our iconic ability as a localizedDescription
Let's start by registering the description.
Add another entry (you can duplicate an existing entry)
Set the secondaryKey
to the value in your tweak file, MC_gun_iconic_description
Set femaleVariant
to your text — this will be showin on the tooltip in yellow.
. Make sure that it has the correct secondary key , and enter your fluff text as femaleVariant
.
Now that we have an ability, we need to register it as a mod:
Now we can finally add the mod to the weapon by adding it to the slotPartListPreset
:
Everything hangs together now, let's see if it works.
Install your mod — if your gun shows the yellow iconic description on hover, you're good to go. If not, you may have to respawn it via CET.
We'll heal for 80 HP every time the player pops somebody else's skull with the Hand of Midas. How do we do that?
However, the prerequisite for this effector is Items.MemoryReplenishmentEffector_inline0
, which doesn't sound helpful.
We could now try to find an existing preReq that checks for headshots, but we can also write our own.
Now we have a custom preqrequisite, but we still have to fine-tune and link it:
Conditions are at the heart of a prerequisite, and here we have four.
Perks.IsHitTargetAlive_inline2
-> We don't want headshots on deadbodies to heal the player
Perks.HitIsBodyPartHead_inline0
-> Actual condition to check for headshots
Prereqs.Is_Attack_Ranged
-> (Custom) We don't want quick melee attacks to heal
Prereqs.Is_Weapon_Ranged
-> (Custom) We don't want grenades to be counted for this check.
Now let's change our effector to use this prerequisite.
Instead of punishing the player for just missing headshots, we can make our job easier by removing the HP every time they shoot, and compensating for the reduction in HP when hitting headshots by increasing our heal. Here's how we can do that:
We've done a lot so far, so I'll leave all our changes here:
Uncomment the effector in your weapon tweak and test your mod. You should now be healing every time you hit headshots.
Here's a demo for how iconic weapon should behave.
You've created/modified a tweak but it doesn't show effect in game, what next?
Open Cyberpunk 2077\red4ext\plugins\TweakXL\TweakXL.log
and look for any error messages towards the end, this can help when TweakXL has issues loading a tweak.
Check for other mods with same Tweak/Archive names.
Tweak Folder - Cyberpunk 2077\r6\tweaks
Archive Folder - Cyberpunk 2077\archive\pc\mod
Look at WolvenKit logs located towards the bottom. Yellow or Red text means there's warnings/errors in your file that need addressing.
How to set up an atelier store for your mod
This guide will detail how to add an Atelier store with your items. It is part of the ArchiveXL tutorial, but you can complete these steps independently.
Find a guide on
Learn more about
If you are using , you can use to quickly create spawn codes and Atelier entries
You need to install the mod for this.
You also have to add it to your mod's requirements, as atelier stores will cause script errors if users don't have it installed.
First of all, the template archive (kindly provided by Apart) and find the folder virtual_atelier_inkatlas_icon_template
with the following files:
Put the .inkatlas and .xbm into your project (if you're using the , you can put them into the ops
folder). Then, rename them to atelier_icon
:
Now, add your item.
In atlasResource
, you have to replace all \
with /
Your atelier store will cause script errors if you don't.
Ignore "Icon path" and "description", we have these in the item itself.
Click "Add Item". Repeat the process with as many items as you want.
Click "Generate".
In the downloaded file, check that atlasResource
has forward slashes /
instead of backwards slashes \
, as per the warning box above.
In your project's resources
folder, create a subdirectory r6/scripts (if it doesn't exist already), and move the atelier file that you downloaded into there:
Now, it's time to test! Install the mod and start Cyberpunk.
I'm not sure how you managed to read past all the red and yellow boxes on this page, but make sure that the path under atlasResource
has forward slashes /
instead of backwards slashes \
.
If that wasn't it, you might have to re-generate your Atelier store.
That happens when there are two atelier stores with the same store ID. Do a full-text search for the store ID (MyTutorialAtelierStore
) in r6\scripts
and make sure that you don't have any duplicates.
How to mod weapon attachments
Created: July 11 by @manavortex Last documented update: July 11 by @manavortex
This page will tell you how to mod weapon attachments and scopes.
This page is a work in progress. If you're missing any information, please and edit it in!
Component visibility is defined by the visibilityAnimationParam
:
To always display a component, set the value to None
(clear the field).
TODO: which values are allowed here? Where do we get them from?
Adding weapons
Published: July 08. 2023 by Last documented update: Feb 07 2024 by @manavortex
This guide will teach you how to change the ArchiveXL item addition process to make it work for a weapon.
For a much more detailed step-by-step guide, check
For an overview of weapon properties, check
For an overview of weapon audio profiles, check
Weapons work a little different from regular ArchiveXL items, starting right at the root entity. With the help of @Apart and psiberx, I was able to figure out the process and document it for you.
Start by finding the .app file of an original weapon of the type you want to make (Theres a list ) and adding it to your project. We will change that file, rather than assembling anything by hand.
In the app file, you can also find the value for the yaml file's $base
property:
You need the correct mesh entity to go with your appearance file. You can find them under base\weapons
\ - search for the name of your weapon, or just navigate through the folders.
This file makes the weapon show up in photo mode. Instead of going into the PartsValues, it will be linked in the app file's root as baseEntity
(there's a screenshot below). Leave it alone for now, it's easier to make the appearances working correctly in the .app file and then copying over an entire component array.
For guns with a receiver, you have to edit two .app
files instead of just one. The name of the extra file will contain _rcv
.
Instead of a root entity file, you need to point your factory.csv directly to your iron's app file (the one from the section above).
An equipment item's lookup chain goes from the appearanceName
in the yaml to the root_entity
, where the appearanceName
will lead to the correct appearance in the .app
file.
With a weapon, all that happens through visualTags
.
Native weapons often use one shared VisualTags
to reference multiple appearanceName
and randomize the result. If you want to use a specific native appearance present in a VisualTags
native group, you can use appearanceName
to specify which. E.g:
visualTags: [ Neon ]
appearanceName: neon2
visualTags (violet): Must match the visualTags in your .yaml
file. If multiple entries match, one will be chosen at random.
Unlike with an entity file, the appearance name doesn't matter. You can name all of them foo
, and as long as you had the visual tags right, it still works (I would advise against it, though)
As the process is finicky and there can be all sorts of sudden unexpected behaviour, here's the best way to go about this.
The list links you to sections of the guide which tell you to change things. Optimally, you do a dry run with one appearance to make sure that something shows up in the game at all, then start fine-tuning, but you do you.
Here's what's worked for me (@manavortex):
Find the .app file of a suitable base weapon, add it to your project, and rename it. Don't change anything for now, future you might need the original data for troubleshooting later.
Find the correct .ent file. It might be linked in the .app's baseEntity
field. If not, you can find it with the following Wolvenkit search query:
Optimally, the number of components in the .ent
file should be the same as in any appearance's component
array (red arrow on the screenshot above).
If it's not, that could indicate that you have the wrong .app file. It could also mean nothing, but if you run into trouble in step 6, this might be why.
Start the game and make sure that you can spawn a custom weapon with the appearance you picked and that it
shows up in inventory/photo mode
shows up in first person
If that doesn't help, you may have taken the wrong .app file - go looking again.
You haven't changed anything at this point: the goal here is to make sure that your visual tags are correct and that you can spawn a weapon addition.
It's crucial that you make this work — anything you do after this point will add complexity and make troubleshooting more difficult, so this is where you shore up your bases.
Optional: You just added a weapon to the game that didn't exist before. Take a moment to bask in the success!
Create a copy of the file and move it to a custom folder
rename it
Change the baseEntity
path in your .app file
Optional, but recommended: Repeat step 5 and make sure that everything spawns
Now it's time to actually change things. Open your appearance's component array and make sure that the MeshComponents load your custom stuff (anything that has a depotPath
pointing to a .mesh file).
After you've changed the paths, launch the game and make sure that your weapon
shows up in your inventory with your meshes
shows up in first person with your meshes
shows up in photo mode at all (it shouldn't be invisible, but will still have the default appearance)
all parts and extra meshes are visible
is in the right position in regards to V's hands (at least as much as for the Tactician shotgun)
all parts and extra meshes show the correct appearances
Fix any issues that might arise before you proceed.
This is why we kept the original appearances around: if you run into any issues here, you can compare your stuff with the original, un-changed game variants.
Don't forget that you can
split off meshes or submeshes for individual pieces (for chunkmask hiding or extra materials)
add more components (duplicate existing ones, or copy them from the mesh entity)
Once everything works, delete all the default appearances, then duplicate and adjust the one you customized to show your color variants.
Luanch
When exporting an existing weapon mesh for your custom weapon, make sure to uncheck LOD Filter — the lower LOD mesh is used for calculating the hitbox.
This is especially important if you add a melee weapon of a different size than the original: if you only replace LOD 1, there will be a separate, invisible hit box that does not align with your new weapon.
In Blender, put your custom mesh in both LODs.
If your weapon is significantly bigger than the original one, you'll notice that the hitbox won't auto-scale with your mesh. If you know how to solve this problem or want to brainstorm, hit up @Mx_OrcBoi
on Discord!
First of all, unequip and re-equip the item. If that doesn't fix it, try respawning it.
To make it work again, you need to either
Add the following line to your .yaml:
Set $base like this:
Make sure all the items under "resolvedDependencies" are deleted in your appearances, especially if they are using "Soft" or "Embedded" flags. The game might load vanilla meshes instead of your own meshes.
How to make a custom projectiles for throwing weapons
Created by @manavortex Updated October 05 2023
This page is a sub-page of and tells you how to create a custom projectile for a throwing weapon.
To create a custom throwing weapon, check the parent guide and use knife as a base type.
Everything but the yaml works exactly like adding regular items (with a or , an and your weapon's mesh). This example will use a root entity.
This process is about as finicky as the one for weapon additions. Make sure to test your changes after each step.
We now need to register our projectile. We already have a weapon, so let's define our projectile:
Now, we need to tell our weapon about it. Add the following lines to its definition:
If your weapon wasn't throwable before, it is now — but the projectile is still invisible. Time to change that.
A projectile needs an .ent
file as the factory's entry point, not an .app
.
You can find all projectile entities in base\gameplay\projectiles
.
Ignore anything that has default
in its name.
There are two kinds of .ent files: the ones that support multiple appearances, and the ones that don't. You can tell them apart by opening them and checking the appearances
array (the first entry in the list).
Pick the right kind of entity for your weapon:
Use e.g. this entity file if you want to use multiple appearances:
Use e.g. this entity file if a single appearance is enough for you:
Add the file to your project, then rename it and (if you have one) move it to your weapon's folder.
Now it's time to connect everything by registering the projectileTemplateName
from your .yaml
file in your factory.csv. As a reminder, this is the line we're talking about:
Your factory should have two entries: one for the projectile, one for the weapon itself.
From now on, your projectile will no longer be invisible. If it is, try setting your factory path to one of the game's original projectile entities - debugging time.
If you're using a mesh entity (with an empty appearances
array), you can skip this step.
Expand the appearances
array
Select any of the appearances
Check the appearanceResource's depot path
Add this file to your project
Rename it and move it to your custom folder.
Open your root entity. For all of the appearances, change the appearanceResource
path to that of your .app
.
If you are using a mesh entity (without an .app
file), that's where you will find the component
s. Skip step 1 on the list below.
Open your .app
file . For each of the appearance
s, do the following:
Expand the components
array
For any components that have Mesh
in their type name:
Change the mesh depotPath
to your weapon's custom mesh
Change the meshAppearance
to one of your weapon's appearances
Open resolvedDependencies
and replace the path to the original mesh with your own.
If you did everything correctly, you should now have a custom projectile for thrown weapons.
(for spawning items)
Press in WolvenKit. This will do the following things:
Congratulations, you've made it into the lower left part of the diagram, and can also make use of Wolvenkit's now! The error will be somewhere here:
can help you catch the error.
The easiest way to troubleshoot your mesh is by using Wolvenkit's and keep an eye on the log view.
The easiest way to troubleshoot your materials is by using Wolvenkit's and keep an eye on the log view.
If you are stuck, refer to the at the end of the page.
RedMod tweak files are much more legible than a "TweakXL override" from WolvenKit for this, as each step there inherits redundant stuff passively and won't clutter your screen. Plus you'll see inlines content directly without having to track down flats. Just use something to search the insides of the files for the definitions (VS can, or some free tools like )
For this tutorial, we will use the gun 'Unity' as our base (Items.Preset_Unity_Default).
If you want to use a different weapon, you can refer to or find a list of all in-game items .
To understand how the base gun works, open the in WolvenKit and search for Items.Preset_Unity_Default
.
To read more about Tweak modding, check . This isn't necessary for understanding this guide!
Open the overridden tweak file in a code editor of your choice (such as or VS Code). You will be presented with a .yaml
file containing roughly a million fields.
Now open up the CET :
In later steps of this guide, you'll need to look up properties. Either keep a copy of your full tweak file (e.g. on your desktop), or refer to above.
If you want to take a look at these lists, use WolvenKit's or for onscreens.json
.
Good thinking, but no. In Cyberpunk, only one mod can edit any given file. That is why exists, and we'll use it to create a new translation entry for us.
Place a dedicated file in your midas_collection
\localization
folder. This is where we'll add our own translation entries – after that, we only need to tell ArchiveXL about the file and lean back.
For more detailed guidance on these properties, check out the .
You can read more about how array operations work in .
You can find an overview of existing weapon stats under
These arrays don't directly contain the stats, but have inline objects, which in turn will contain the actual stats. I recommend browsing to each of these stats in the Tweak Browser to find out what each one does. You can also read about and what they do here.
The example (together with instructions on finding your way around the TweakDB) has moved to ->
For an explanation of what these do, please see ->
We have found an iconic mod in the for Wilson's gun, so now let's see that we apply this to the Hand of Midas.
two , which we are yet to implement
Open the .json
file that you've created when
Now that we have , we'll fill in the two , one to punish the player for missing, and the other to reward them for headshots.
Let's do what Edison did — we find something to be inspired by. A search for effector
in the finds an awful lot of entries, so I've picked an example for us — a Netrunner item that restores memory:
The player's health is also a statPool item, it's called BaseStatPools.Health
. We can copy this example and change it to meet our needs (for the final result, see ):
For more information on this, check ->
You are now a certified weapon modder. Pat your self on the back twice, you've done it. A special request from me (@DestinyBu). If you found this guide helpful, go ahead and document your own findings on the Wiki and maybe ping me if you ever get around to finishing your Mod. A big thanks to for (inspiring) forcing me to do this.
Open the CET Console in game search for your Tweak in the . If your tweak doesn't show, there's a validation error in the tweak.
Validate your .yaml tweaks to check for errors.
Now, create your icon. The process is the same as for "". The resulting slot will be named slot_01
.
Visit website and fill out the information:
Here's an explanation for the fields below. Rather than filling them by hand, you should use website to generate your store files.
Configure the yaml
Set up one (1) appearance for testing by . Do not delete the other appearances yet, future you might need them for troubleshooting.
If that's not the case, check the (see the blue box in step 2).
Custompath your :
Now, finally, copy a working appearance from the .app file to your . This will make your weapon show up in photo mode.
If you wish to add a custom icon, follow the steps in the .
To make your own HUD icons for the lower right corner, check .
You can change which weapon audio preset your custom iron uses by changing the following property in the .yaml
(see a list under ):
You can set up throwing weapons just like a regular weapon, but the projectile (when you throw it) will default to . Check for how to have custom projectiles.
That is due to a base game change (bug?): iconic weapons don't show fluff texts anymore (huge thanks to for learning that).
Make sure that the corresponding entry points at your projectile's entity file from .
For troubleshooting steps, please see the page.
femaleVariant
Hand Of Midas
the default translationse
maleVariant
only set this if you want to show a different translation when your item is equipped by a person of the male body gender
primaryKey
0
The actual entry in the translation list, make sure to set this to 0 so that it's autogenerated
secondaryKey
MC_gun_name
The key used in tweak files to identify this translation string
Store ID (characters only, w/o spaces, '-', '_' and etc.)
MyTutorialAtelierStore
Store Name
My Tutorial Atelier Store
Atlas Resource
tutorial/torso/my_custom_shirt/ops/atelier_icon.inkatlas
Texture Part
slot_01
TweakDBID
as defined in your yaml, e.g.
Items.my_custom_shirt_redwhite
Price
Whatever price you want, 0 means that it's free
Quality
Are we settling for anything but legendary here?
Allowed values are:
- "IconicItem"
- "Legendary"
(LegendaryPlus, LegendaryPlusPlus)
- "Epic"
(EpicPlus)
- "Rare"
(RarePlus)
- "Uncommon"
(UncommonPlus)
- "Common"
(CommonPlus)