DRG Mods: A Comprehensive Guide to Blueprint Modding
Please do not hesitate to ask for help on the DRG Modding Discord in #mod-questions!
Buckminsterfullerene - Originally wrote and maintains guide.
- 1. Introduction
- Reading this guide
- Final note
- 2. How blueprints work
- How BP mods are loaded into DRG
- Framework mods
- Methods of BP modding
- Useful acryonyms to know for BP modding
- 3. Setting up your UEE workspace
- 4. No-dummy method
- Creating your first DRG mod
- A bit more complex version
- Outputting time dilation to the HUD
- Toggle HUD button
- Saving and loading settings
- Basic replication
- 5. Dummy method
- Kill player on button press
- Self-destruct Bosco on button press
- 6. Packaging your mod
- Using DRG Modding Automation Scripts
- From UE
- Directories to never cook
- Video Tutorial
Before you can even get started with your mod, you need to install a few tools:
- Unreal Engine
- An IDE (such as Visual Studio 2019, Rider for Unreal Engine or CLion)
- The most up-to-date game dumps (if you are using the BP dummy method explained later)
- The FSD template project (if you are using the C++ dummy method explained later)
IMPORTANT: By the time you are reading this guide, you should already have these tools and have at least the minimum required knowledge to use them (more on UE4 later). If not, I refer you to Rauliken's more general guide on the DRG Modding discord.
Reading this guide
Make sure that you read through every detail of this guide thoroughly as missing something may result in many problems down the line. Of course, you can always refer back to this if you need assistance on anything. Critically important details are highlighted in bold, and optional but useful information is highlighted in italics.
Inline code is used for 'specifics'.
You should know the basics of Blueprinting in Unreal Engine. There are plenty of tutorials on YouTube. You should also know how Blueprinting associates with C++; here is a really good video on that. If you haven't already, watching this video is basically a requirement to understand much of what is going on here.
If you are into other forms of UE modding, please don't hesitate to join the UE Modding discord server.
Please be aware that as BP modding becomes increasingly advanced, this guide may become out of date until I update it. Since I'm really busy all the time this may not happen for a few days or weeks.
2. How blueprints work
How BP mods are loaded into DRG
Native spawning is something that was added by the developers when the modding update dropped. This allows you to load your blueprint from the
BeginPlay event node. If you want your BP mod to have user-interactable UI (like a settings menu), you should use a framework like
Usually, you will only want to use a framework mod if you want the user to be able to change settings for your mod in game. If you don't need this for your mod, you do not need to use a framework. Framework mods so far have always come in two parts:
- The devkit tools that you put into your mod's UE project for interfacing with your mod
- The in-game mod dependency that runs all of the framework's functions and processes
I suggest that for now, as you are learning BP modding, that you don't touch any frameworks, otherwise you'll find yourself spending more time wrangling with widgets than actually learning new techniques.
ModHub is the "official" shared-settings mod interface. If you want a place to put settings widgets for your mods, use this. You can view the source here, and the guide for use here (you need to be in the DRG Modding discord).
Samamster has been developing this framework as a more feature-rich BP modding library. The great thing about this library, is that it provides helper functions and DRG-like UI objects that makes BP modding just that little bit easier. You can view both the source and guide for use here.
Methods of BP modding
There are two methods, in a way that you can use both at the same time or not if you wish:
- No-dummy method. This doesn't require any knowledge in C++ to use. You also won't need the game dumps. This is limited to built-in UE BP functions and events or those you have from a framework devkit, or you created yourself. You can still achieve a fair bit from this but are limited.
- Dummy method. You can manipulate the functions, variables and events that are running in the game. You can figure out what you need from looking at the game's dumps files. You can find the most up-to-date dumps versions here (be aware that GitHub only displays the first thousand classes on its website version).
Useful acronyms to know for BP modding
- ABP – Animated BluePrint
- BP – BluePrint
- GD – Game Data
- GM – GaMe
- ID – IDentifier
- ITM – ITeM
- LIB – LIBrary
- LVL – LeVeL
- MUT – MUTators
- OC – OverClocks
- PRJ – PRoJectile
- UI – User Interface
- UPC – UPgrade Category
- UPG – UPgrade Group
- W – Widget
- WND – WiNdow Widget
- WPN - WeaPoN
3. Setting up your UEE workspace
For ANY Blueprint mods, you MUST name your project
FSD. Therefore, I make all my mods inside the same project and then delete the mods I don't want to pak before I pak them. The reason the name must be
FSD, is because that is what the original game's UE project is called. "FSD" is probably the code-word for DRG (most games have these for various reasons).
First, select the games category, then click next:
Then click on blank and click next:
Select the following options on the project settings:
Then hit create project, and you're ready to move onto the next part!
4. No-dummy method
I'm going to run through the creation of a super simple mod which then outputs text to the screen, and finally saves and loads mod data. Note that my UE might look different to yours – don't worry, I'm just using a couple of plugins that makes it looks nicer.
Creating your first DRG mod
This mod will simply set the global time dilation (the speed) of the game to
5. The purpose of this mod is to just run through the process of making a mod – the time dilation bit will validate that we know the mod is loaded.
To spawn a blueprint into the game, first you need to create a folder with the same name as your mod inside the
Content folder. Then create a blueprint inside of that called one of two things:
InitSpacerig– this will load your blueprint when the player is spawned in the spacerig.
InitCave– this will load your blueprint when the player is spawned in the drop pod at the start of a mission.
To make a blueprint, right click inside the content browser and hit
Create Blueprint Class. Then inherit it from
Double click on
InitSpacerig first, and navigate to the
Event Graph tab. We can ignore
Event ActorBeginOverlap and
EventTick. Drag off
Event BeginPlay and find the set global time dilation node:
Now set this to
To save, hit the
Compile button on the toolbar. Remember to compile and save your project every now and again. Tip: you can compile and save at the same time when you click compile, by clicking the little arrow dropdown to the right of compile button and setting save to "always":
Now we are ready to package and test this simple mod.
Refer to section 6 on packaging your mod.
When you load into the game, everything should be moving 5x as fast! More importantly, now you know how to make blueprint mods!
A bit more complex version
This time around, the mod will change the time dilation based on a key press.
First though, let's streamline the same mod to be loaded by both
InitSpacerig, since we don't want to copy and paste everything into both BPs.
Make a new BP called something like
Mod (it doesn't matter). Now in
InitCave, we want to spawn this actor immediately. Get out a
Spawn Actor From Class node, and set the class to whatever you called your mod BP. Do this in both
We're not quite done yet, we need to set
Collision Handling Override to
always spawn, ignore collisions. Also, right click on that orange
Spawn Transform pin and hit
split struct pin. If you don't do this, it won't know where to spawn the actor. Later on, if you're spawning a physical actor but don't want it to be seen, spawn it at like Z=99999.
Make sure to compile and save when you're done in both BPs!
Now inside of your new mod BP, we want to add the functionality that increments or decrements the global time dilation based on what key you press. Let's say that the hyphen key decrements it by
0.5 and the equals key increments it by
First, let's make a variable that stores the time dilation. Set its default value to
1. Now we need to get the key events. Right click on the graph and type
Hyphen and get out that node, and then do the same for
Equals. Make sure that you enable input when the mod is spawned, otherwise this won't work:
Player index 0 is always host, i.e. your player if you are the only one in the server or hosting a server.
Now make your mod functionality like this (you should have done basic blueprinting before as a pre-requisite to this so you should be able to easily follow what this does):
Now let's make sure that the dilation never goes below 0 (otherwise the game crashes) or higher than
8 (otherwise FPS is reduced the rubble):
Before we go any further, let's compile, package and test the mod.
Outputting time dilation to the HUD
Now we want to output the current dilation to the HUD (Heads Up Display) so we can see the value in-game.
Tutorial folder, make a new widget blueprint called something like
Inside of the widget designer, find the text box widget in the palette and drag it out. Place it anywhere on the window – I recommend putting it about
2/3 the way up the left or right side of the window, which is where we know there is empty space on the DRG HUD. This text will just be some text like "Time Dilation:". Next to it, put another text box with the text "1". This is where we will change the value. The default dilation in the game is
1 so we set the default text to match that.
Now name that second text box to something sensible. You also need to check the
Is Variable box, otherwise we won't be able to change it from our mod BP.
Hit Compile and switch back to the mod BP. To access and set our text box, we need to first construct the widget and get an object reference from it:
HUD Ref variable is our object reference. The variable type is that
Now drag out the
HUD Ref variable and we want to get the object reference to the
Now to set its text, we drag out the
Set Text (Text) node:
Now we want to set the text to the value of time dilation:
Now we can see our time dilation and that it changes when we hit our key binds. But what if we want to toggle the HUD on or off?
Toggle HUD button
First, we need to go back into our HUD designer and set that description text box to a variable so we can control it from our mod:
Now back in our mod, make a variable that will store the boolean value of whether or not the HUD is enabled. Make sure the default value is
When a key, say, '#', is pressed, we want to switch the visibily of the text boxes between
Collapsed (you can read the tooltip regarding the differences between
Let's check to see if this works!
Now… what if we want to save the dilation and if the HUD is enabled so that the next time the mod is loaded we save our settings?
Saving and loading settings
We first need to make a new blueprint that inherits the
Inside of it, simply make the two variables that we want to save, and make sure that they are set to public:
Back in our mod, make a variable that is an object reference to this
Now let's make a function that will load the save. This checks if the save game exists, and if it does, load the game from the slot. If it does not, we create an empty save game object. The save file name is
Mods/<your mod name>/<your name name>. The saves are stored at
FSD/Saved/SaveGames. Here my save name is
Call this function after we construct our widget (I've added a sequence node to tidy up a bit).
Now we want to make another function that loads the save data into our mod variables. We also want it to change the HUD values, i.e. if the HUD is disabled in the save, we want to toggle the HUD off when we load it in:
Chuck it after load save:
Toggle HUD and
Set Dilation Text functions are just what we have already done but put into functions so that we don't have duplicated code.
The last thing we want to do is save our values every time we change them. So let's make a new function that does this:
Now we call this function when we change time dilation and the HUD value. Now the mod looks like this (I've tidied it up with comments):
Now, compile, package and test. If you toggle your HUD off, and set dilation to like
5, then restart the game, your settings should be saved!
But we want this mod to work in multiplayer, so we need to do a bit of basic replication and handling with that.
Before you read this section, I suggest that you go watch some basic UE4 replication video on YouTube as it will explain the basic processes that I will use here. If you're not interested in replication (it's hard), don't worry, you can skip this section without any problems.
While the mod works perfectly fine in singleplayer, it goes all a bit funky in multiplayer. If you're the host, you need to replicate (copy) the time dilation that you're setting for the rest of the clients in the server. Otherwise, anything client side only (like player movement) will not be affected. And if you're not the host, then you shouldn't be able to change the time dilation because otherwise things get even more funky if yours is different to the server's.
So firstly, let's just get the easy bits out of the way. If a client is not the server, disable the input so that they can't change their local time dilation value. We can do this by simply using the
Is Server node:
We also need to prevent the time dilation from being set when the save is loaded. While we could do the same
Is Server check before the entire load save section, we want to still allow all the clients to load the
Is HUD Enabled value from their own saves. So we can just do the check inside of
Load Save Data instead.
Now for the fun stuff. First, we need to change the mod settings to allow replication. Click
Class Defaults on the top bar and change the replication settings like this:
You also need to go into the class defaults for
InitSpacerig and change the replication settings like this:
Next, we need to actually set the
Time Dilation variable to replicate. You can do this by clicking on the variable and setting the
Replication parameter to
RepNotify. The reason we want to use this, instead of just
Replicated, is that we want to notify the clients when the value of it changes.
You may notice that in the functions pane, a new function called
OnRep_<your variable> e.g.
OnRep_Time Dilation, has been created. This function is called by every client whenever the value is changed, including the host. You may also notice that 2 white spheres have appeared on all the variables' getters and setters - this shows that the variable is set to
RepNotify (one sphere is
Replicated). You can also hover over the setters and it'll tell you how it works.
So inside this new
OnRep function, when we then set the global time dilation and HUD value, we need to make sure that it only runs for non-host clients (AKA remotes). To achieve this, we can use the
Switch Has Authority node and pull off execution only when remote. Then we set the global time dilation and the HUD text:
Then you're done! You don't need to call the
OnRep function - this is done automatically everytime the variable is set.
Now to test, you will need a friend (oh no, this isn't looking good for you) to check that all the logic works as expected. To achieve this, you will need to make a new hidden mod on mod.io and use the preview link or add your friend as a moderator so that they can subscribe to it.
5. Dummy method
I'm going to run through making a couple of mods which utilise some of the C++ and dummy methods. Once you know how the basics work, you are then set to much more easily be able to experiment, test, and implement any of your own features that use any of the game's functions and BPs for your mods. The possibilities here are endless. Overview of the two example mods I will step-through in this tutorial:
- Kill player on button press.
- Self-destruct Bosco from a button press.
Both examples will still feature info on how to look at the C++ header dumps.
The very first thing you need to do is download and build the FSD Template project. This has all of the C++ classes automatically reflected in the project source. This saves modders a LOT of time, as there are thousands of classes!
Kill player on button press
Scouting the C++ header dumps
Now, you will notice that there are a LOT of C++ classes in the dumps. Don't be overwhelmed – most of the main functions you will need are in
FSD.hpp (although saying that, the file alone is 20k lines). If you need C++ from another class you know at the time what you are looking for – and if you don't, you can always search for key words that you are looking for and look through those files. You will be doing a lot of searching through files anyway, so you'll get good at this pretty quickly. Don't hesitate to ask in
#mod-chat in the Discord where stuff might be located though.
So, back to this mod example. We need to find the function in the game that deals with killing the player. As you should always do, start by looking in
FSD.hpp as it is most likely to be there. Do
Ctrl + F to open the search function (this is the same for all IDEs and code editors), and type
Kill. You may see about 100 results. You could look through these manually, OR, you could try toggling on "match by word" option that most IDEs and code editors have. In CLion, it is a square button with a "W" on it.
So, here is a function that just kills the player when it is called. An
AActor object is passed through but you can just ignore that as we don't need it. The important thing to do here is to check what class this function is inside. This is again relevant for any other functions you will find for your mods. So here,
Kill() is inside struct
UHealthComponentBase, which is a child class of
UActorComponent, as denoted by the
When you are looking for functions and variables for your mod, you will come across some really interesting looking functions and variables. I have regularly come up with entire mod ideas just from being distracted when looking through the code. Every single function and variable in all these header files can be dummied… which is a lot of possibilities. Feel free to go wild!
Accessing the C++
Now we know where our
Kill function is, we can go about accessing it from our BP mod. Make a new mod (I just made a new one in my tutorial folder and changed the
InitCave to spawn that instead).
Inside your mod, right click and get a node called
Get Component by Class. In the dropdown, you should be able to find the
Then if you drag off the return value pin and type
Kill, you should see a function that pops up called
Kill. This is your function that you created inside the
Now when we press a key, say, the period, we want to kill the player:
There is a problem with this though! You cannot just call the
Kill player function, as you will notice that the component by class node requires a target, which will be the player to kill.
To get the player you want to kill, we need to get the game state player array, loop through that player array then cast the array elements to
BP_PlayerCharacter pawns, which you can then use as the targets.
Dummying player character BP
But what is
BP_PlayerCharacter? This is a blueprint class that the game has that controls all the logic for the player. We need to dummy this in order for our killing player to work.
In the dumps, navigate to
APlayerCharacter : ACharacter. You will see that this is where all the info about the player is stored.
ACharacter inherits from
APawn, which inherits from
AActor. This is important to know because when you dummy blueprints, you can set the parent to be super parent (i.e. the highest in the hierarchy).
Create a folder inside
Character. Here we are recreating the exact file path of the asset (you can find
BP_PlayerCharacter inside of your unpacked files at this location). Now you need to create a new blueprint class called
BP_PlayerCharacter. Inherit it from
Once you create this blueprint, you don't need to do anything with it. Since we aren't dummying this file, we don't want to overwrite anything in the game with it so that is why we don't change any values. All we are doing is accessing the REFERENCE to the blueprint for the mod.
Now, back in your mod, let's get to work on this logic.
First, there is a node from the UE base
Gameplay Statistics library called
Get Game State. Drag off the return value and type
Player Array; we want to get that. Then drag off player array and create
For Each Loop with Break node. This will loop through all players in the player array and stop when it receives the break call. If you are in a multiplayer server, all the players in the game will be registered in this player array. So, if you just use a for each without a break, you could kill all the players in the game, if you wanted. This cluster of nodes will be very useful for your mods.
Now drag off the loop's array element and type
Pawn Private. Then from the output of that read node, type
Cast To BP_PlayerCharacter. Connect the execution node for that cast into the loop body.
Now plug in your
Kill function execution node, and your target from
As BP Player Character from the cast. Then, if you want to kill just the first player in the player array, hook up the end of the kill function execution to the break for the for each loop with break node. You don't have to do that though, as mentioned above.
Make sure that you enable input on
Before you package your mod, you have to make sure that you set your directories to never cook to include the
Character folder. This is because if we pack our dummied
BP_PlayerCharacter, the game will crash. This is explained in section 6, packaging your mod.
Self-destruct Bosco on button press
Scouting the C++ header dumps
First off, we want to find
BP_Bosco in the header dumps. It is nicely called
BP_Bosco.h. You will see a function called
SelfDestruct() inside of it.
If you go into
FSD.hpp, and search for
ABosco (which is what this class inherits from), you will also see
SelfDestruct and a bunch of other functions. Let's say that I also want Bosco to salute before he self-destructs. When writing this tutorial I was just planning on him self-destructing but saw that
PlaySalute() function and just knew I had to include it. That'll happen a lot when you are looking through the dumps :)
Before we make the dummy blueprint, we need to figure out what class it needs to inherit from. So, if you look at the
struct ABosco line, you will see a
:, which as described previously, means "inherits from", then the class it inherits from to the right. So here we see that
ABosco inherits from
If your IDE has the feature, you should be able to just hover over the name and it will tell you what that class inherits from and click to go to the location of it. If not, don't worry, as you can just search the file for that classname manually.
So you will see now that this class is inherited from
AFSDPawn. Now we search for what
AFSDPawn is inherited from, and we will see
APawn is a base UE class so that's as far as we need to go – but now we know, that
ABosco is a child class of
APawn, even though it is a bit down the inheritance tree.
Creating the dummy BP
Now, we need to recreate a dummy blueprint in the same location where this guy is in the game files, like we do for hex mods. So in your unpacked files, search for
BP_Bosco. It should be inside
Inside your project files, navigate to that file location and create a new blueprint class. Since we discovered that
ABosco is a child class of
Pawn, we can select
Pawn class to inherit from. We name the blueprint
BP_Bosco. It should look like this:
Inside of this, all we have to do, is create two functions, one called
SelfDestruct, and another called
PlaySalute. That is literally all you have to do. This now allows us to call these functions without having to touch any C++.
Now, to call on our blueprint, all we have to do is create a node
Get Actor of Class and select
BP_Bosco in the little dropdown. Then drag off the return value and type
Now, let's put a short delay between saluting and self-destructing, and then call the self-destruct function.
6. Packaging your mod
When you want to test your mod, there are two options for packing:
- Automatically using DRGModdingAutomationScripts that Samamstar and DrTurtle made. I really highly recommend using this as it saves a LOT of manual time!
- Manually from UE then using
There's also directories to never cook, which is an extremely important setting, so make sure you scroll down to read that part too.
Using DRG Modding Automation Scripts
First head to this GitHub repository. Then hit the big green
Code dropdown and download the code using your preferred method (e.g. download as
ZIP). Then extract the
DRGModdingAutomationScripts folder and follow the instructions on its
README file. Once you are setup, literally all you need to do is double click a .bat and it'll do whatever the bat says it does in the
Go into the
Untitled tab. Click
File -> Package Project -> Packaging Settings.
Make sure that this
Use Pak File option is
Now, package your project by clicking
File -> Package Project -> Windows (64-bit).
Then selecting a folder to package to:
Tip: if you already have an old cooked folder in there, delete it then click on the parent folder again in the top bar. Because otherwise, since you selected the old folder, it will cook into
WindowsNoEditor again, even though you deleted the old one. This sounds confusing so if you just try it yourself you'll understand what I mean.
Assuming you didn't do anything wrong, your project should package after about 30 seconds (differs on how large your project is - when using the
FSD-Template, the first time around takes many minutes).
Now, navigate to the packaged files and delete any stuff you don't want to pak (other mods etc.).
Now copy both the
AssetRegistry.bin files, and put them into the input folder inside your
Then drag the input folder into
_Repack.bat. Remember to rename the .pak to your mod name. Then navigate to
DeepRockGalactic\FSD\Mods\ and make a new folder with the same name as your mod. Then put the
.pak into that folder.
Directories to never cook
You can set directories to never package, which is useful when you don't want to pack say, any of the dummy BP folders. Although you don't have to do this, it does mean that you don't have to delete these files manually within the cooked files, every time. To do this, click the little dropdown arrow in package settings, just above the
Then in directories to never cook, press the
+ button to add directories to the array. This is what mine currently looks like:
Important announcement: these video guides are now very out of date, with methods inside still working but newer, less tedious methods now exist. I suggest that you follow this written guide first.
These videos are not intended to replace the written guide.
The segments recorded include:
- Introduction info and setting up your workspace
- The basics of setting up native spawning, native spawning with DRGLib & pre-native spawning with BPMM
- The no-dummy BP modding method, using the pre-native BPMM method and then converting the same mod to native using BPMM's interface
- The dummy BP modding method, which includes how to navigate the C++ header dumps, as well as reflect them and dummy BPs
- Reflection demo, which shows exactly how to reflect some certain C++ objects/delegates/functions/properties that weren't covered in episode 4
Hello modder! If you found this guide useful, I invite you to rate it in this form. Feedback is optional, but very welcome.