Tutorials

Tutorials for modding the game.

Extracting the Game's Files

If you just want to export a few items, use Diesel Bundle Viewer

This guide will go over how to extract the game’s assets. If you simply want to install mods, this guide is not for you! If you want to make some, you’re in the right place.

Prerequisites

To begin, you’ll need all of these. You don’t need to do anything with them yet, just make sure you have them all:

Installation and Prep

Got everything? Let’s get started.

  1. First, go ahead and run the installer for Microsoft .NET Framework 4.5. This should be fairly straight forward.

  2. Once that’s done, go ahead and open up the .zip for the Bundle Modder that you got. You should see this:

Extract all of the files to a folder of your choosing. I’d recommend putting it in a folder called “Payday Bundle Modder”, to keep it organized:

  1. Next, you’ll want to open the PAYDAY 2 Hashlist zip. Extract the file inside to your Bundle Modder directory, as shown:

Once you've done this, you're ready to start with the Bundle Modder.

Using the Bundle Modder for extraction

Now that all of the prep work is out of the way, we can get started with the Bundle Modder. Despite the name, the Bundle Modder can be used to extract the game’s files. It used to be the only way to install mods in the past, but became outdated as modding tools improved. It’s still the preferred way to extract files however.

The UI is unfortunately a bit clunky and unintuitive, but this guide walk you through it:

  1. In the folder where you extracted the Bundle Modder files, run “PDBundleModPatcher.exe”. This should pop up if it’s your first time using it:

Ignore the scary warning and hit OK.

  1. You should see this screen now with a bunch of options:

Luckily, you can ignore most of it. The only part we care about is where it says “Game Asset Folder” on the top:

Hit “Browse” and locate PAYDAY 2’s “assets” folder. By default, this is:

C:\Program Files (x86)\Steam\steamapps\common\PAYDAY 2\assets

Not there, or forgot where you installed it? Click here for a guide on finding your install location.

Once you’ve found it, hit OK.

  1. After you’ve done that, the following message will pop up:

Ignore it and hit OK.

Click on the “Game File Extraction” tab:

  1. You can specify a Custom Extract Folder if you wish, but all you have to do is hit “Start” in the bottom right to start the extraction process:

If you did not specify a custom extract folder, this will pop up:

Hit “Yes” to proceed, or “No” if you want to go back and specify one.

  1. Wait until it’s done. This depends on the speed of your hard drive, so find something else to do in the meantime.

  2. When it’s done, this message will pop up:

The extracted files should be in the directory you specified, or

C:\Program Files (x86)\Steam\steamapps\common\PAYDAY 2\assets\extract

by default.

Congrats! You’ve successfully extracted the game’s files. Now you can get to work on a mod.

Re-Extracting the Game's Files After an Update

As you might be aware, PAYDAY 2 tends to update frequently with new content. It won’t magically appear in your extract folder however; you’ll need to extract the files once more.

This guide assumes that you're familiar with the Bundle Modder and already have an extract. If you don't have an extract or the Bundle Modder, check out the Extraction guide by clicking here.

Re-Extracting the Files

  1. Check here to see if the Hashlist has been updated for the latest patch.. If it hasn’t, it’s recommended that you wait for an update before continuing. Otherwise, any content added by the patch will be extracted with an improper filename and file path. If it has, download it.

  2. Open up the .zip, then extract “hashlist” to your Bundle Modder folder. Make sure you replace files if prompted.

  3. Open up “PDBundleModPatcher.exe”. It should detect that the game has updated:

Just hit OK and go to the Game File Extraction tab:

  1. If you want to speed the extraction up, check the box that says “Ignore existing files” on the Game File Extraction page:

As the name implies, this will skip over the files you’ve already extracted to drastically reduce the extraction time. You can leave this option unchecked if you want to make sure all of your files are updated.

  1. Hit “Start” in the bottom right, and wait.

And you’re done! Now you have the latest content extracted.

WeaponLib Mod Preparation

You boot up Payday 2, intend to enjoy a few of new weapon mod that have appeared on the front page of MWS, but found out that most of them have the big red word Requires WeaponLib. You shudder in fear, you don't know what it is, how to use it, or where the other long list of Requires have gone.

This wiki will show you what needs to be done in order to move to WeaponLib

First of all, WeaponLib is a combination of previously-separated-standalone weapon functionality mod, into 1 big code library for weapon to use. Spearheaded by Cpone, many of the combined mod is Cpone's mod that you probably already heard of and then some other.



So if you want to move to WeaponLib, check first for this list of mod that you need to remove:


Almost all of them are located in mods folder, except a few that are probably in mod_overrides.
Nevertheless check assets/mod_overrides as well in case those old mod are left there from previous version.
After removing those mods you can place WeaponLib folder nicely into mods folder.

And you have successfully moved to WeaponLib! Where even bigger things are awaiting weapon modding!


Check out WeaponLib Fixes as well to fix several outstanding bug while the base mod is in 'hiatus'.

WeaponLib is still in "development", and many more standalone weapon functionality mod are considered to be integrated.
This wiki will be updated alongside for more mod that would be integrated (and removed from running in the game).




For Mod Developer

This is your resource on how to convert existing code/function to use WeaponLib standard: https://gitlab.com/cpone/WeaponLib/wikis/Home
For any other specific question, you can direct it to Cpone on MWS discord

Troubleshoot Custom Weapons/Attachments for Modders

You're working on a custom weapon/attachment and run into a specific issue you have no idea how to deal with?
Then this is for you, this is a collection of known common/uncommon problems you might run into while working on a custom weapon/attachment and how to deal with them.


Softlock

When your game freezes while trying to load an asset (for example trying to inspect a weapon or attach an attachment) its called a softlock.

[Custom Weapon]
You try to preview your new custom weapon for the first time and it causes a softlock, those are the things you can do:

  1. Check your default_blueprint. Are the attachment IDs correct? Are there attachments listed that don't even exist?
  2. Check the BLT Log for any errors related to missing assets on your custom weapon
  3. Check if the paths in your default_blueprint part assets (unit/object/mat_cfg) are all correct.
  4. Use an elimination method in which you only try to preview the gun one attachment at a time and comment the rest out to find the attachment thats causing the issue. Then use step 3.
  5. Check if you didn't forget to add any needed asset paths (unit/model/object/mat_cfg)
    smg_example.png

[Custom Attachment]
You try to preview your new custom attachment for the first time and it causes a softlock, those are the things you can do:

  1. Check the BLT Log for any errors related to missing assets on your custom attachment
  2. Check if the paths in your part assets (unit/object/mat_cfg) are all correct.

Weapon Crash

Equipping or previewing a specific custom weapon crashes your game (can also apply to equipping or previewing an attachment).

The crash looks something like this: (Note the _add_part() lib/managers/weaponfactorymanager)

Application has crashed: access violation

-------------------------------

Callstack:

         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 


-------------------------------

Current thread: Main
Script stack:
                   _add_part()  lib/managers/weaponfactorymanager.lua:743           
                   _add_part()  lib/managers/weaponfactorymanager.lua:708           
     assemble_from_blueprint()  lib/managers/weaponfactorymanager.lua:627           
     assemble_from_blueprint()  @mods/WeaponLib/modules/different_akimbos/menuraycastweaponbase.lua:18  
                        clbk()  lib/managers/menu/menuscenemanager.lua:2186         
                                lib/managers/dynamicresourcemanager.lua:220         

-------------------------------
  1. First find the attachment thats causing this issue (If you can't find it use an elimination method like on Softlock step 4)
  2. Your based_on for the attachment is not the same as the .object/.unit files. (For example the luger magazine as based_on for magazine assets from the 5/7)

The crash looks something like this:

PAYDAY 2 Crash log
Application has crashed: C++ exception
[string "lib/managers/weaponfactorymanager.lua"]:984: attempt to index a nil value
SCRIPT STACK
get_ammo_data_from_weapon() @mods/WeaponLib-Release/modules/weaponfactorymanager_caching/weaponfactorymanager.lua:51
original() @mods/WeaponLib-Release/modules/general_fixes/newraycastweaponbase.lua:211
_update_stats_values() @mods/base/req/core/Hooks.lua:260
make_fakeweaponbase() @mods/More Weapon Stats/lua/blackmarketgui.lua:787
mws_get_popup_data() @mods/More Weapon Stats/lua/blackmarketgui.lua:614
original() @mods/More Weapon Stats/lua/blackmarketgui.lua:560
show_stats() @mods/base/req/core/Hooks.lua:260
on_slot_selected() lib/managers/menu/blackmarketgui.lua:6672
ddi_original_blackmarketgui_mousepressed() lib/managers/menu/blackmarketgui.lua:6282
mouse_pressed() @mods/Drag and Drop Inventory/blackmarketgui.lua:19
mouse_pressed() lib/managers/menu/menucomponentmanager.lua:1458
mouse_pressed() @mods/base/lua/MenuComponentManager.lua:24
mouse_pressed() lib/managers/menu/menurenderer.lua:368
mouse_press() lib/managers/menu/menuinput.lua:570
lib/managers/mousepointermanager.lua:341
-------------------------------
Callstack:
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     zip_get_name                                        
         payday2_win32_release  (???)     zip_get_name                                        
-------------------------------
  1. First find the attachment thats causing this issue (If you can't find it use an elimination method like on Softlock step 4) (NOTE: this crash is caused by a stock type attachment)
  2. Your attachment tries to add a stock_adapter that doesn't exist on the gun, either add the stock_adapter to the gun or remove the line that tries to add the stock adapter.

Weapon Crash 2

Clicking on the weapon causes a crash. The crash looks something like this:

PAYDAY 2 Crash log
Application has crashed: C++ exception
[string "lib/managers/weaponfactorymanager.lua"]:1617: attempt to index a nil value
SCRIPT STACK
_check_sound_switch() lib/units/weapons/newraycastweaponbase.lua:694
original() @mods/WeaponLib-Release/modules/general_fixes/newraycastweaponbase.lua:83
_update_stats_values() @mods/base/req/core/Hooks.lua:260
make_fakeweaponbase() @mods/More Weapon Stats/lua/blackmarketgui.lua:787
mws_get_popup_data() @mods/More Weapon Stats/lua/blackmarketgui.lua:614
original() @mods/More Weapon Stats/lua/blackmarketgui.lua:560
show_stats() @mods/base/req/core/Hooks.lua:260
on_slot_selected() lib/managers/menu/blackmarketgui.lua:6672
ddi_original_blackmarketgui_mousepressed() lib/managers/menu/blackmarketgui.lua:6282
mouse_pressed() @mods/Drag and Drop Inventory/blackmarketgui.lua:19
mouse_pressed() lib/managers/menu/menucomponentmanager.lua:1458
mouse_pressed() @mods/base/lua/MenuComponentManager.lua:24
mouse_pressed() lib/managers/menu/menurenderer.lua:368
mouse_press() lib/managers/menu/menuinput.lua:570
lib/managers/mousepointermanager.lua:341
-------------------------------
Callstack:
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     zip_get_name                                        
         payday2_win32_release  (???)     zip_get_name
  1. You probably forgot to close one of your xml tags like <Weapon>, either try to find the unclosed tag manually or run it through an XML validator

Weapon Crash 3

Going into a heist with a custom weapon causes a crash. The crash looks something like this:

Application has crashed: C++ exception
[string "lib/units/weapons/newnpcraycastweaponbase.lua"]:19: attempt to index a nil value
SCRIPT STACK

spawn_unit() =[C]
add_unit_by_factory_blueprint() lib/units/beings/player/huskplayerinventory.lua:144
add_unit_by_factory_name() lib/units/beings/player/huskplayerinventory.lua:134
_perform_switch_equipped_weapon() @mods/Third Person/thirdperson.lua:199
synch_equipped_weapon() lib/units/beings/player/huskplayerinventory.lua:21
set_equipped_weapon() lib/network/handlers/unitnetworkhandler.lua:61
@mods/BeardLib/Hooks/NetworkHooks.lua:105
send_to_peers_synched() @mods/Third Person/lua/basenetworksession.lua:52
send() lib/network/base/extensions/networkbaseextension.lua:11
_send_equipped_weapon() lib/units/beings/player/playerinventory.lua:389
equip_selection() lib/units/beings/player/playerinventory.lua:344
original() lib/units/beings/player/states/playerstandard.lua:5185
_start_action_equip_weapon() @mods/base/req/core/Hooks.lua:260
_update_equip_weapon_timers() lib/units/beings/player/states/playerstandard.lua:3291
_update_check_actions() lib/units/beings/player/states/playerstandard.lua:883
original() lib/units/beings/player/states/playerstandard.lua:435
update() @mods/base/req/core/Hooks.lua:185
original() lib/units/beings/player/playermovement.lua:271
@mods/base/req/core/Hooks.lua:260
  1. Note the _perform_switch_equipped_weapon() @mods/Third Person/thirdperson.lua this crash is caused by using both WeaponLib and the ThirdPerson mod, to fix it either disable or remove the ThirdPerson mod. If this exact crash still keeps hapening afterwards contact me on Discord (Killerwolf#2636)

Weapon Crash 4

Trying to preview your custom weapon causes a crash. The crash looks something like this:

Application has crashed: access violation

-------------------------------

Callstack:

         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     zip_get_name                                        
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     zip_get_name                                        
         payday2_win32_release  (???)     ???                                                 


-------------------------------

Current thread: Main
Script stack:
        _spawn_and_link_unit()  lib/managers/weaponfactorymanager.lua:894           
                      _spawn()  lib/managers/weaponfactorymanager.lua:791           
               complete_clbk()  lib/managers/weaponfactorymanager.lua:803           
                        load()  lib/managers/dynamicresourcemanager.lua:123         
                   _add_part()  lib/managers/weaponfactorymanager.lua:768           
     assemble_from_blueprint()  lib/managers/weaponfactorymanager.lua:627           
     assemble_from_blueprint()  @mods/WeaponLib/modules/different_akimbos/menuraycastweaponbase.lua:18  
                spawn_weapon()  @mods/WeaponLib/modules/different_akimbos/menuscenemanager.lua:43  
           spawn_item_weapon()  @mods/WeaponLib/modules/different_akimbos/menuscenemanager.lua:51  
                     done_cb()  lib/managers/blackmarketmanager.lua:4663            
                        func()  lib/managers/blackmarketmanager.lua:2018            
  call_next_update_functions()  lib/setups/setup.lua:236                            
                      update()  lib/setups/setup.lua:843                            
                      update()  lib/setups/menusetup.lua:352                        
                      update()  @mods/base/lua/MenuSetup.lua:5                      
                                core/lib/setups/coresetup.lua:557                   

  1. Note the _spawn_and_link_unit() lib/managers/weaponfactorymanager.lua this crash is caused by having a broken attachment model, either use the elimination method or look for suspiciously small attachment model files (less than 12kb for example). To fix it either replace that broken model or remove it.

Weapon Crash 5

Loading into a heist with your custom weapon causes a crash. The crash looks something like this:

Application has crashed: C++ exception
[string "--mods/BeardLib/Classes/Utils/Utils.lua..."]:142: attempt to index local 'fac_part' (a nil value)
  1. Note the attempt to index local 'fac_part' this crash is caused by having a caused by using non existing ID for based_on. You probably made a spelling mistake, fix that by using the exact ID from the weaponfactorytweakdata in your based on.

Weapon Crash 6

Trying to preview your custom weapon causes a crash. The crash looks something like this:

Application has crashed: access violation

-------------------------------

Callstack:

         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     zip_get_name                                        
         payday2_win32_release  (???)     zip_get_name                                        
                         ntdll  (???)     RtlUpcaseUnicodeChar                                
                         ntdll  (???)     RtlRestoreLastWin32Error                            
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 
                           ???  (???)     ???                                                 


-------------------------------

Current thread: Main
Script stack:
                spawn_weapon()  @mods/WeaponLib/modules/different_akimbos/menuscenemanager.lua:36  
           spawn_item_weapon()  @mods/WeaponLib/modules/different_akimbos/menuscenemanager.lua:51  
                     done_cb()  lib/managers/blackmarketmanager.lua:5121            
                        func()  lib/managers/blackmarketmanager.lua:2339            
  call_next_update_functions()  lib/setups/setup.lua:252                            
                    original()  lib/setups/setup.lua:871                            
                      update()  @mods/base/req/core/Hooks.lua:188                   
                      update()  lib/setups/menusetup.lua:358                        
                      update()  @mods/base/lua/MenuSetup.lua:5                      
                                core/lib/setups/coresetup.lua:557                   
  1. This crash is caused by having a wrong root point in your main weapon model, say the object file has the root point (orientation_object) rp_mauser1891 while the model itself still has the vanilla root point, in this case rp_wpn_fps_snp_mosin. To fix either replace the orientation_object in the object file with them model root point, or replace the model root point with the orientation_object from the object file.

Weapon Crash 7

Opening the black market causes a crash. The crash looks something like this:

Application has crashed: C++ exception
[string "lib/managers/menu/blackmarketgui.lua"]:13508: attempt to index a nil value



SCRIPT STACK

callback() lib/managers/menu/blackmarketgui.lua:13418
first_btn_callback() lib/managers/menu/blackmarketgui.lua:12656
press_first_btn() lib/managers/menu/blackmarketgui.lua:7089
mouse_double_click() lib/managers/menu/blackmarketgui.lua:6996
mouse_double_click() lib/managers/menu/menurenderer.lua:413
lib/managers/mousepointermanager.lua:381


-------------------------------

Callstack:

         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     ???                                                 
         payday2_win32_release  (???)     zip_get_name                                        
                         ntdll  (???)     RtlAllocateHeap       
  1. This crash can be caused by having an inconsistent/non-existent GlobalValue in your xml. For example finn.png finn3.png

Weapon Crash 8

Loading into a heist with a custom weapon causes a crash. The crash looks something like this:

  1. This crash can be caused by badly written stance code (note the PVM mention in the crash log). For example
  2. The rotation here is missing the 4th value, it should instead look like this
  3. A good way to avoid this is using the Copy to Xml button in the Perfect View Model UI (the button only copies the values to your clipboard, so you have to paste them manually in the xml). This is how a correct stance setup would look like after copying the PVM values

Custom Attachment Points Issues

Custom attachment points from your weapontweakdata don't have an effect ingame, i.e changing the values doesn't move them.

  1. Check if you weapontweakdata is hooked
  2. Check if your hook has a unique name and isn't being overwritten by a post hook with the same name (this usually happens when copying files from another custom weapon and then forgetting to change stuff for the new weapon)
  3. If all the above isn't the issue check if your weapons .unit and npc.unit have the correct values example:
	<extensions>
		<extension class="ScriptUnitData" name="unit_data" />
		<extension name="base" class="NewRaycastWeaponBase" >
			<var name="name_id" value="tti" /> <!-- value should be the same as your weapons ID -->
		</extension>
	</extensions>

Weapon disappears from your inventory

When you restart your game the custom weapon is gone from your inventory.

  1. A part defined in the default_blueprint is either not in the uses_parts or doesn't exist at all

Note:

This is a WIP page, more problems and solutions will be added over time. Everyone who knows a specific issue and how to deal with it is welcome to contribute.

Voice Over Modding

Things you need:

Post extraction/downloaded from gdrive

Easy steps

What you should do:

Side note: Some of the character lines such as AI war cry, marking specials on control phase (more for characters older than Bodhi) are encoded ogg files and since we don't have a proper tool we can't replace them for the time being. Replacing them with encoded wave files will result in not playing anything. If you have the game files extracted you will see that wwise_ima_adpcm can't decode all stream files which are encoded .ogg files. My decompiled extract on Gdrive included with extracted .ogg based stream files, sort the folder by bit rate. For char_name folders they are 768 kbps if mono, 1536 kbps if stereo, mostly same for robbers_mission_gen though some are 576, 512 kbps

There are some misinformations going on regarding voice over modding:

  1. Some people still think they have to match replacement audio's length with the vanilla's otherwise it won't work which is NOT true, longer audio files may make it spammy
  2. Renaming the .wav/.ogg extensions to .stream does NOT work
  3. Trying to compress .ogg to .rar/zip and renaming the extension to .stream does NOT work, stop with this shit, seriously.

Legendary Armor Skins/LAS/MOOG/Outfit Module Guide

This guide as also made by Columbus, if you'd like to contact me on Discord, please join the modworkshop.net server and ping me if you have any questions in #payday2-modding.

DISCLAIMER: THIS IS STILL A WORK IN PROGRESS, NOT EVERYTHING HAS BEEN EXPLAINED YET.

I just wanted to get this out to anyone who wanted to get started and have prior knowledge with Blender and modding other games first. If you a complete beginner, please wait until this guide is fully finished. Thank you.

Now to start...

Prerequisites:

  1. Blender, you could either download it at Blender.org

  2. You could also download Blender through Steam

  3. For the version, I use 3.2.2, but you could also use 4.X.X

  4. PAYDAY 2 Model Tool (install .net version 6 if it does not run)

  5. Any image editing software, such as Paint.Net, Photoshop, or GIMP

These are all the bare essentials you'll need to begin your path down modeling and porting models to PAYDAY 2.

Got them all downloaded and everything is running correctly? Good. Now, let's move on.

Model Tool

If this is your first time modding for PAYDAY 2, and you don't know what does what on the model tool, I'll explain a basic run down of each section, and tab.

  1. For the import screen, this is where all the magic happens, The first section "Select Base Model" this is where you'll import the base model of what you're modifying. (side note by thot_patroll, if you are making a new model instead of replacing one then this can be turned of with the checkbox)

  2. The second section "Script" is what you'll be using the most (or least) to import your .glb file and have it be read by the model tool.

  3. Object is the alternative to Script, where instead of using a script to import your model and have it be saved/converted into a .model, you'll just import the .glb file by itself with no .mscript file to assist you in doing so.

  4. Pattern UV can be safely ignored since it is more suited for weapon modders, and that's what we're not here for.

  5. Animations can also be safely ignored.

  6. The check boxes, Importing objects not in base file, and Import transforms, it's best to always keep those two ticked on, no matter the circumstances.

  7. "Save To: is where you wish to place your newly generated .model file in a folder.

    This is the export screen of the model tool, this is where you drag and drop your .model file and convert it to either a .dae .obj .gltf .glb or .animation

All I should say for this is that always keep your export format as a .glb format.

I will not go through a preview of the Objects tab since it is more meant for users who are more well-versed in model editing.

Now that we've gone through the basic rundown of the Model Tool, let's start to move into Blender. To export your first .model file, select the .model you want to export, I'll for example use Kento's model, located at "units\pd2_dlc_des\characters\civ_male_des" in the game files. you can use Diesel Bundle Viewer to extract the models.

Blender

Importing

When you export the model to a .glb a new file should appear with the same name in a glb format. Open up blender, and at the left of the screen there should a piece of text called "File" click on it and a new menu should appear, and hover over import, it should look like this if you've done it correctly.

You're import file list won't be as big as mine since I have several plugins installed, but click the glTF 2.0 option and a new menu should appear.

Right before you import, change the setting at the right side of the new window called Bone Dir, change it from Temperance to Blender, Blender 4.X has this option automatically selected. Dont mind the weird looking skeleton, if this step is not done then the model will be broken in game.

You've now imported your model that you'll be using as a base. Unfortunately if you're a new Blender user, this could be extremely complex at first, but if you're a experienced Blender user, new to PAYDAY 2 modding, this should be easy.

Now to begin, let me start off by saying that the model you want to insert must be in a humanoid shape or a human. Anything that involves animals that were meant to originally be a quadruped, will be impossible to import or to even look good. Additionally most models will have different proportions then the payday characters so you will have to either edit the model itself or scale/move the bones to try and cram it in.

I won't bore people with the details, since the process of converting a rig to PAYDAY 2's rig is different with each character since all rigs are made differently, but if you want a more fleshed out guide to wanting to make your model work with the engine, I suggest looking at THOT_PATROLL's guide linked here

Exporting

Once you have completed your model in Blender, and would like to export, there are some settings you should check or uncheck before you export it.

Tangents

It is highly important that you export with tangents on your model so that your normals will not look bad when importing the model into the game and previewing it. The setting can be found under

Data > Mesh > Tangents (Tick tangents so that there is a checkmark)

Vertex Colors

While this setting is highly situational for some users, most models will not need this setting enabled. The setting can be found under the same tab where tangents are located, just under the "Vertex Colors" tab, uncheck "Export all vertex colors" and when the file won't export the mesh with any vertex colors.

Materials

The materials are controlled by the material_config file. Each material will need to have a render template which is what tells the game what the material will do. So if you want a material to glow or have transparency then you will need a render template that supports that. There is a file that contains all the templates but most of the time you will only be using a few basic ones unless you need a special one.

For first person models you will need special materials that have "depth_scailing" in the render template. This makes the object render "infront" of everything else so it wont clip with other objects in the world.

Textures

Got your model all setup now? Good, now it's time to move on to texturing. The basic textures you will most commonly see with character models are color/diffuse textures or albedo depending on the game, a specular or roughness map, and a normal map. There are some more unique textures like metallic, emissive/illumination, transparency, ambient occlussion and others, but for now let's focus on the most common ones.

Albedo/Color Textures

Let's start with their color/diffuse texture, I will refer to it as diffuse now for simplicity. A diffuse texture is basically what everyone will see on the character and what gives them their look. Without a diffuse texture, the textures will just be a flat color, but let's not dive too deep into what they are, and more of how to work with them. I will use a baked texture I made for Houston's upper suit texture from Payday 3 as an example.

upper_albedo_1k.png

Ambient Occlussion/AO Textures

This is an albedo texture, there is no post processing effects on it, such as ambient occlussion or whatever else. If we were to import this into the game right now, it would not look appealing. To make it look good, see if the textures you extracted or downloaded have a "ambient occlussion" texture or AO for short. This will significantly help how your model would look. To apply the effect over the albedo texture, you will need a photo maniuplation program like Photoshop or GIMP, I will be using Photoshop for the example pictures. To apply a ambient occlussion texture, simply layer the texture on top of the albedo texture and adjust for scaling if the texture resolutions are different from one another, and once you got that all down, change the bar where it says "normal" to "multiply"

layered.png

Once you have done that, your new texture will look like this.

upper_diffuse_1k.png

Notice how the AO helps give the texture more depth and darkens the wrinkles and areas where the suit is less commonly seen, this will help the texture looks much better when ported over to Payday 2.

Payday 2 commonly uses .dds files when creating textures and it is suggested that you should too, if you use Photoshop, you may download the .dds plugin here

Exporting

If you are new to making textures and don't care to mess with a GSMA texture, you could place your specular map into the alpha layer of your diffuse texture and save it from there. If you do make sure you save it as a "DXT5 ARGB 8 bpp | interpolated alpha" texture, if you save as DXT1, you will lose your alpha channel data and the model would end up looking extremely glossy. If however, you want to make a GSMA texture I will explain it now.

GSMA

A GSMA texture is a texture that was used more later down the development pipeline of Payday 2 models. GSMA (Gloss, Specular, Material, Alpha) is probably the closeset we will get to a PBR type texture. To properly use a GSMA texture, place the specular texture you have and insert it into the green channel. If you however have a roughness texture, no worries. Just invert the color of the image and you have a specular. Once inserted, your red channel will be the determining factor of what parts you want the shine from your green channel to be shiny or glossy, think of it like its an anisotropy factor for your specular. The blue channel of the GSMA texture is a masking layer used to determine what part of your texture will have a cubemap reflection or not. This could be useful especially if you are making a texture with a metallic part, and you want to apply a steel reflection cubemap, but don't want the entire material reflecting that texture to have a metallic look to it. It's practically a dumbed down metallic layer that doesn't make the texture look more metallic with it on its own. The alpha layer of the GSMA is used in more rare cases when render templates (shader templates) specify that the GSMA alpha layer will be used for transparency in the material_config file.

Normal Map/NM

Now that you've gotten the most important texture all setup and good to go, let's move on to the second most important texture, your normal map. Normal maps come in all sorts of ways, depeneding on the game engine formats them, your X/Red channel could be layered in the alpha channel, while the Y/Green channel remain in the green layer of the image, which is more commonly seen with DXT5nm formatted normals, either that or your texture will be a blueish/purplish texture, with the X, Y and Z channels being in the red, green and blue channels.

Here is an example of the latter normal map I explained.

upper_normal_1k.png

But it's not as simple as it may look here, some games rendering template could also determine how the normal map will really looks when importing it into the game.

OpenGL Normal Maps Compared to DirectX formatted Normal Maps

Games rendered using OpenGL will have the Y channel set to Y+, and games running on DirectX will have the Y channel inverted at Y-. If your normal map looks like the image on the left side image in the comparison, you will need to invert your green channel of your normal map, so that it looks more alike to the OpenGL normal map.

While this games renders with the DirectX API, you will need to format your normal map to the OpenGL format, this reason is because of when you export with tangents, normal vectors are used to convert normal maps from tangent space to world space normals when previewed in game.

Once you have done that, now comes the time to format the normal map to be compatible with diesel engine. In the channels tab of your texture, right click the red channel of your normal map and select "Duplicate Channel", the duplicated image will be your alpha layer of your normal map, since diesel engine does not use the red and blue channel, it is recommended that you make the channels a solid black or white to save on compression and quality of your green channel. Once you're done with that, you may now export your texture

Illumination/IL Textures

Illumination is the texture used for glowing materials. It will look like a regular albedo/color texture however the non glowing parts will be black and the glowing parts will have the color you want. The brightness and bloom are controlled by variables called il_multiplier and il_bloom. They will look something like the code below and changing the value number will change their strength. There is a premade set of values that you can use which can affect the instensity of the brightness of the illuminated texture.

name="none" value="0.0"/>

name="identity" value="1.0"/>

name="match" value="0.4"/>

name="candle" value="0.5"/>

name="desklight" value="0.6"/>

name="neonsign" value="0.7"/>

name="flashlight" value="0.8"/>

name="monitor" value="0.9"/>

name="dimlight" value="1.0"/>

name="streetlight" value="1.2"/>

name="searchlight" value="1.4"/>

name="reddot" value="2.5"/>

name="sun" value="3.0"/>

name="inside of borg queen" value="6.0"/>

name="megatron" value="8.0"/>

<variable type="scalar" name="il_multiplier" value="1"/>

<variable type="scalar" name="il_bloom" value="1"/>

Opacity/OP Textures

Opacity textures are used for transparent materials, they will be black/white with white being the parts that are visible and black being parts that are invisible. parts that are partially white/black will be semi-visible

You will need a special render template to get this to work, but we'll talk about render templates later.

Opacity textures may seem simple on the surface, but the color channels do serve different purposes

Red = Fresnel Reflection Strength (This is a bit more confusing, if you're unsure how to properly control this channel, keep it the same as the green channel) (This feature is only available with render templates that support Fresnel, editing this channel while using a generic opacity render template causes... interesting visual issues to say the least.)

Green = Opacity (Fairly straight foward, it just controls the scale of the opacity of the texture

Blue = Cubemap Strength (Think of this like a specular channel, this basically just controls the gloss of the texture if you want it to reflect a cubemap or have it be matte)