Modding Basics – DayZ

From Bohemia Interactive Community
Jump to navigation Jump to search
mNo edit summary
(Add "start DayZ once" note)
 
(9 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Category:DayZ:Tutorials|Basics]]
{{TOC|side}}
We will be creating a simple mod that will print a message into the script log whenever the player jumps.


__TOC__
In order to do so we have to create the folder structure of the mod and then pack it into a '''.pbo''' file.
 
A mod can have several ''.pbo'' files but most smaller mods will only ever need a single one.
 
Step by step creation of a simple mod for DayZ




== Requirements ==
== Requirements ==
* Steam copy of '''DayZ'''
* '''DayZ Tools''' (Availabe through steam by navigating through Library -> Tools)


== Setup ==
* Steam Version of '''DayZ SA'''  
It is recommended to setup a '''Project Drive''' with extracted game data for optimal workflow:
* '''DayZ Tools''' (Available through steam by navigating through Library -> Tools)
* Launch DayZ Tools from Steam
* Basic syntax understanding of [[DayZ:Enforce_Script_Syntax|Enforce Script]]
* Navigate to Settings
* Understanding of the [[DayZ:Modding_Structure#PBO_structure|PBO Structure]]
* Set a Drive Letter and your Path to the Project Drive
* Click apply
* Navigate to Tools -> Extract Game Data
* Wait for the process to finish


: {{Feature|important|For the Workbench to detect the game, {{dayz}} must have been started at least once! Otherwise a "game is not installed, exiting" error message will stop Workbench on its track.}}


If you wish to use '''Workbench''' and its '''Script Editor''', follow the setup guide here https://community.bistudio.com/wiki/DayZ:Workbench_Script_Debugging#Workbench_Setup


== Creating a mod ==
== Setting up the Project Drive ==
In the spirit of simplicity, let us create a mod which will print a message into the log upon a certain condition.


In order to do so, we will need to pack our mod into a '''.pbo''' file and load it when launching the game. A mod can have several .pbo files but most smaller ones will only ever need a single one.
Create a '''Project Drive''' to store a representation of the DayZ filesystem and all of its files.


'''Scripting syntax''' documentation is located here https://community.bistudio.com/wiki/DayZ:Enforce_Script_Syntax
* Launch DayZ Tools from Steam, selecting "Play DayZ Tools"
 
* In the menubar, click '''Settings'''.  
=== Step by step ===
* Adjust the path to the '''Project Drive''' by unchecking '''Default''' and then choosing a path that has a minimum of 20gb free space on the drive.
* Start by creating a mod folder, in this example we will create one in our P: drive called '''FirstMod'''
* In the dropdown for '''Drive Letter''', select one. Make sure to note which one you selected. It is recommended to use 'P:\'.
* Click apply
* In the menubar, navigate to '''Tools''' and then select '''Extract Game Data'''.
* Wait for the process to finish


* Inside the '''FirstMod''' folder, create another folder which will contain our modded class. We will call it '''WorldScripts'''


* '''PlayerBase.c''' contains a function suitable for our mod named '''OnJumpStart()''' which is called every time player jumps - we will use it in this example
== Folder Structure and config.cpp ==


* Create '''MyScript.c''' file in the '''WorldScripts''' folder with the following contents
* Start by creating a folder that will house the mod namesake. This is otherwise called the root prefix of a mod. In this example, we will create one in our 'P:\' drive called '''FirstMod'''.
[[Image:dz_modbasics_structure.png]]
* Within that folder let's create another folder called '''Scripts''' and then within that folder create another folder called '''4_World'''.  
<syntaxhighlight lang="c++">
* Let's first create the mod configuration. Within the '''Scripts''' folder create a new file called '''config.cpp''' and then copy the following sample:
modded class PlayerBase // modded keyword for modding existing class
:<syntaxhighlight lang="cpp">
{
override void OnJumpStart() // overriding existing function
{
super.OnJumpStart(); // call the original jump function so we don't break stuff
Print("My first mod, yay!"); // our modded print
}
}
</syntaxhighlight>
 
 
* All we need now is '''config.cpp''', which is a representation of our pbo as described here https://community.bistudio.com/wiki/DayZ:Modding_Structure#PBO_structure
[[Image:dz_modbasics_structure2.png]]
<syntaxhighlight lang="c++">
class CfgPatches
class CfgPatches
{
{
class FirstMod
class FirstMod
{
{
requiredAddons[]=
requiredAddons[] =
{
{
// ""
// ""
Line 69: Line 50:
class FirstMod
class FirstMod
{
{
    type = "mod";
type = "mod";
 
    class defs
class defs
    {
{
class worldScriptModule
class worldScriptModule
{
            {
value = "";
                value = "";
files[] = { "FirstMod/Scripts/4_World" };
                files[] = {"FirstMod/WorldScripts"};
};
            };
};
        };
};
    };
};
};
</syntaxhighlight>
</syntaxhighlight>
: Read up on the config.cpp [[DayZ:Modding Structure#PBO structure|CfgMods structure]]


DayZ standalone has 5 script modules that can be modded. In order that they load they are 'engineScriptModule', 'gamelibScriptModule', 'gameScriptModule', 'worldScriptModule' and 'missionScriptModule'. Using the correct '''script module''' is '''{{Color|red|very important!}}'''


Using correct '''script module''' <span style="color: red;">'''is important!'''</span>
Vanilla file PlayerBase.c (which contains PlayerBase class we are modding) is located in '''4_World''' so we need to define path to '''worldScriptModule''' scripts in our config.cpp in order for our PlayerBase script mod to work.


* Done! It is time to pack our mod into a .pbo
== Packing the Mod ==


== Packing into pbo ==
Although we are not ready to test, let's pack the mod. This is so we can create and edit scripts through file patching.
* Using the DayZ Tools launcher, open '''Addon Builder'''


* Set addon '''source''' directory, in our case ''P:\FirstMod''
When packing a mod, make sure the addons (and keys) folder are in lower case and that the files within ''addons'' are also lowercase. This is so your mod will work with the DayZ Linux Server binaries.


* Set '''destination''' directory, for example ''P:\PackedPbos''
* To start off, let's create a folder where we will place all of our packed mods. Within your '''work drive''', create a new folder called '''Mods'''.
* Within that folder let's create the folder that will be our first mod. Let's name it '''@FirstMod'''. All mods require an '''addons''' folder so let's also create that within the mod folder.
* Launch DayZ Tools from Steam, selecting "Play DayZ Tools"
* Click "Addon Builder"
* Set the '''Addon source directory''' directory, in our case it will be '''P:\FirstMod\Scripts''''
* Set the '''Destination filename''', in our case it will be '''P:\Mods\@FirstMod\addons\'''
* At the bottom left of the window, select '''Options''' and set '''path to project folder''' to your '''work drive'''
* Click '''Pack''' and wait (if this process fails check 'Enable extended logging' to see why or uncheck 'Binarize').


* In options, set a '''path to project folder''', in our case it will be ''P:\''


* Move our freshly packed .pbo into a new mod folder (as described here https://community.bistudio.com/wiki/DayZ:Modding_Structure#Mod_structure):  ''P:\FirstModPacked\Addons'' and put our '''pbo''' inside ''Addons''
== Preparing FilePatching ==


* Done! Mod can now be loaded using launch parameter ''-mod=P:\FirstModPacked''  
* Go to your DayZ installation folder. It will be within the '''steamapps''' folder at 'steamapps/common/DayZ'.
* Copy the full path.
* Open a command line window and run the following command, replacing 'DayZInstallationFolder' with the path you copied earlier.
:<syntaxhighlight lang="batch">
mklink /J "DayZInstallationFolder\FirstMod" "P:\FirstMod"
</syntaxhighlight>
* Navigate back to the DayZ installation folder, you should now see 'FirstMod' there. Enter the folder and you should see 'Scripts' and the files within it as you would see in the work drive.


== Testing the mod ==


<span style="color: red;">'''Make sure to always properly test your mod before releasing to public!'''</span>
== Creating our First Script ==


=== Testing mod in singleplayer ===
Let's create a script inside the world script module that will output to the script log whenever we jump.


Many mods can be tested in SP environment which you can easily set up by creating a ChernarusPlus custom mission folder, for example '''myMission.ChernarusPlus''' with a '''init.c''' file inside of it with following contents
To start navigate to the '4_World' folder created earlier.  


<syntaxhighlight lang="c++">
If you are or ever wish to work with workbench then do the following. Create a new folder called 'FirstMod'. This is because 'Workbench' does not distinguish the files and folders between what mod they come from, or if it was even a mod.
class CustomMission: MissionGameplay
 
Let's create a script that will "mod" an existing class. Let's first create the 'PlayerBase.c' file within the current folder. We do that by adding the 'modded' keyword to the class declaration. Within this new class let's override a method to add our own behavior, in this case, it would be to print to the script log.
 
:<enforce>
modded class PlayerBase // modded keyword for modding an existing class
{
{
  void CustomMission()
override void OnJumpStart() // overriding an existing method
  {
{
  }
super.OnJumpStart(); // call the original jump callback method so we don't break stuff
};
Print("My first mod, yay!"); // our modded print
}
}
</enforce>
 
 
== Testing the Mod ==
 
{{Feature|important|Make sure to always properly test your mod before releasing it to the public!}}
 
=== Singleplayer ===
 
Let's first create a simple singleplayer mission that will spawn a playable character within chernarus on game load.
 
* Within your DayZ installation folder, if it doesn't exist create a new folder named 'missions'. Enter the folder.
* Create a new folder called 'firstMission.ChernarusPlus'. Note that the 'firstMission' is the name of the mission and 'ChernarusPlus' is the name of the world as named within 'CfgWorlds'.
* Within the newly created mission create the entry point script 'init.c' and paste the following player spawn script
: <enforce>
Mission CreateCustomMission(string path)
Mission CreateCustomMission(string path)
{
{
  return new CustomMission();
return new MissionGameplay();
}
}
 
void main()
void main()
{
{
PlayerBase player;
ItemBase item;
// Create player
// Create player
PlayerBase player = PlayerBase.Cast( ( GetGame().CreatePlayer( NULL, "SurvivorF_Linda", "2200 10 2200", 0, "NONE") ) );
player = PlayerBase.Cast( GetGame().CreatePlayer(NULL, "SurvivorF_Linda", "2200 10 2200", 0, "NONE") );


// Set your gear
// Spawn a black t-shirt
player.CreateInInventory("TShirt_Black");
item = player.GetInventory().CreateInInventory("TShirt_Black");
 
// Select player
// Spawn a green short jeans
GetGame().SelectPlayer(NULL, player);
item = player.GetInventory().CreateInInventory("ShortJeans_Green");
}
</syntaxhighlight>


Modify the init.c to suit your testing needs, then launch '''DayZDiag_x64.exe''' with the following parameters
// Spawn a brown working boots
item = player.GetInventory().CreateInInventory("WorkingBoots_Brown");


// Spawn an apple in the t-shirt, don't redefine 'item' so we can still spawn other items in the t-shirt
item.GetInventory().CreateInInventory("Apple");


''-mission=pathToMission\myMission.ChernarusPlus -mod=P:\FirstModPacked''
// Select player the client will be controlling
GetGame().SelectPlayer(NULL, player);
}
</enforce>


Open a command-line window and run the following command, replacing 'DayZInstallationFolder' with the path dayz is installed at.


which will start the game with a mod in SP environment.
<syntaxhighlight lang="batch">
start /D "DayZInstallationFolder" DayZDiag_x64.exe "-mod=P:\Mods\@FirstMod" "-mission=./missions/firstMission.ChernarusPlus" -filePatching
</syntaxhighlight>


Additional mods can be added by being delimited by a semi-colon. For example: ''-mod=P:\Mods\@FirstMod;P:\Mods\@SecondMod''.


If you are using the '''Script Editor''', you will now see the custom message in the output section every time you jump. If you are not, navigate to your profiles folder ( default: ''WindowsProfilePath\AppData\Local\DayZ'' ) and open the most recent '''script.log''' file, which will contain the printed message.
We are using the singleplayer mission created earlier.


=== Testing in multiplayer ===
If you are using the '''Script Editor''' within '''Workbench''', you will now see the custom message in the output section every time you jump.
If you are not, navigate to your profiles folder ( default: ''"%localappdata%/DayZ"'' ) and open the most recent file starting with '''script'''. This will contain the message.


When testing in MP environment, launch the '''DayZDiag_x64.exe''' in a server mode using the launch parameters
=== Multiplayer ===


Open a command-line window and run the following command, replacing 'DayZInstallationFolder' with the path dayz is installed at.


''-server -config=serverDZ.cfg -mod=P:\FirstModPacked''
<syntaxhighlight lang="batch">
start /D "DayZInstallationFolder" DayZDiag_x64.exe "-mod=P:\Mods\@FirstMod" -filePatching -server -config=serverDZ.cfg
</syntaxhighlight>


where the '''serverDZ.cfg''' can be copied from the DayZ Server distribution on Steam. It is loading the 'dayzOffline.ChernarusPlus' mission by default. Within the server configuration, you will need to modify the following options:


where '''serverDZ.cfg''' can be copied from the DayZ Server distribution on Steam. You will need to modify following options:
<syntaxhighlight lang="cpp">
BattlEye = 0; // turn off BE since diag exe does not run with it
verifySignatures = 0; // if testing mods which aren't properly signed yet
allowFilePatching = 1;  // allow clients with unpacked data to join
</syntaxhighlight>


<syntaxhighlight lang="c++">
You can then join the server by using the following command:
BattlEye = 0; // turn off BE since diag exe does not run with it


verifySignatures = 0; // if testing mods which aren't properly signed yet
<syntaxhighlight lang="batch">
start /D "DayZInstallationFolder" DayZDiag_x64.exe "-mod=P:\Mods\@FirstMod" -filePatching -connect=127.0.0.1 -port=2302
</syntaxhighlight>
</syntaxhighlight>


You can then join the server using '''DayZDiag_x64.exe''' with ''-mod=P:\FirstModPacked'' parameter
You can also use ''-connect=127.0.0.1 -port=2302'' launch parameters to connect to the server directly, skipping the need to go through menu


== Publishing ==
== Publishing ==


Additional steps you will need to go through when you want to share the mod with the world
Before publishing disable filepatching by removing the launch parameter and pack all the ''.pbo'' files again. Verify that everything works without filepatching enabled.


Additional steps you will need to go through when you want to share the mod with the world through the steam workshop:
* Use '''DS utils''' (DayZ Tools) to create a private and public bikey and use it to sign your pbo, as well as include the public bikey in your mod
* Use '''DS utils''' (DayZ Tools) to create a private and public bikey and use it to sign your pbo, as well as include the public bikey in your mod
* Use '''Publisher''' (DayZ Tools) to upload to Steam Workshop


* Use '''Publisher''' (DayZ Tools) to upload to Steam Workshop
 
{{GameCategory|dayz|Tutorials}}

Latest revision as of 04:19, 17 June 2023

We will be creating a simple mod that will print a message into the script log whenever the player jumps.

In order to do so we have to create the folder structure of the mod and then pack it into a .pbo file. A mod can have several .pbo files but most smaller mods will only ever need a single one.


Requirements

  • Steam Version of DayZ SA
  • DayZ Tools (Available through steam by navigating through Library -> Tools)
  • Basic syntax understanding of Enforce Script
  • Understanding of the PBO Structure
For the Workbench to detect the game, DayZ must have been started at least once! Otherwise a "game is not installed, exiting" error message will stop Workbench on its track.


Setting up the Project Drive

Create a Project Drive to store a representation of the DayZ filesystem and all of its files.

  • Launch DayZ Tools from Steam, selecting "Play DayZ Tools"
  • In the menubar, click Settings.
  • Adjust the path to the Project Drive by unchecking Default and then choosing a path that has a minimum of 20gb free space on the drive.
  • In the dropdown for Drive Letter, select one. Make sure to note which one you selected. It is recommended to use 'P:\'.
  • Click apply
  • In the menubar, navigate to Tools and then select Extract Game Data.
  • Wait for the process to finish


Folder Structure and config.cpp

  • Start by creating a folder that will house the mod namesake. This is otherwise called the root prefix of a mod. In this example, we will create one in our 'P:\' drive called FirstMod.
  • Within that folder let's create another folder called Scripts and then within that folder create another folder called 4_World.
  • Let's first create the mod configuration. Within the Scripts folder create a new file called config.cpp and then copy the following sample:
class CfgPatches
{
	class FirstMod
	{
		requiredAddons[] =
		{
			// ""
		};
	};
};

class CfgMods
{
	class FirstMod
	{
		type = "mod";

		class defs
		{
			class worldScriptModule
			{
				value = "";
				files[] = { "FirstMod/Scripts/4_World" };
			};
		};
	};
};
Read up on the config.cpp CfgMods structure

DayZ standalone has 5 script modules that can be modded. In order that they load they are 'engineScriptModule', 'gamelibScriptModule', 'gameScriptModule', 'worldScriptModule' and 'missionScriptModule'. Using the correct script module is very important!


Packing the Mod

Although we are not ready to test, let's pack the mod. This is so we can create and edit scripts through file patching.

When packing a mod, make sure the addons (and keys) folder are in lower case and that the files within addons are also lowercase. This is so your mod will work with the DayZ Linux Server binaries.

  • To start off, let's create a folder where we will place all of our packed mods. Within your work drive, create a new folder called Mods.
  • Within that folder let's create the folder that will be our first mod. Let's name it @FirstMod. All mods require an addons folder so let's also create that within the mod folder.
  • Launch DayZ Tools from Steam, selecting "Play DayZ Tools"
  • Click "Addon Builder"
  • Set the Addon source directory directory, in our case it will be P:\FirstMod\Scripts'
  • Set the Destination filename, in our case it will be P:\Mods\@FirstMod\addons\
  • At the bottom left of the window, select Options and set path to project folder to your work drive
  • Click Pack and wait (if this process fails check 'Enable extended logging' to see why or uncheck 'Binarize').


Preparing FilePatching

  • Go to your DayZ installation folder. It will be within the steamapps folder at 'steamapps/common/DayZ'.
  • Copy the full path.
  • Open a command line window and run the following command, replacing 'DayZInstallationFolder' with the path you copied earlier.
mklink /J "DayZInstallationFolder\FirstMod" "P:\FirstMod"
  • Navigate back to the DayZ installation folder, you should now see 'FirstMod' there. Enter the folder and you should see 'Scripts' and the files within it as you would see in the work drive.


Creating our First Script

Let's create a script inside the world script module that will output to the script log whenever we jump.

To start navigate to the '4_World' folder created earlier.

If you are or ever wish to work with workbench then do the following. Create a new folder called 'FirstMod'. This is because 'Workbench' does not distinguish the files and folders between what mod they come from, or if it was even a mod.

Let's create a script that will "mod" an existing class. Let's first create the 'PlayerBase.c' file within the current folder. We do that by adding the 'modded' keyword to the class declaration. Within this new class let's override a method to add our own behavior, in this case, it would be to print to the script log.

modded class PlayerBase // modded keyword for modding an existing class { override void OnJumpStart() // overriding an existing method { super.OnJumpStart(); // call the original jump callback method so we don't break stuff Print("My first mod, yay!"); // our modded print } }


Testing the Mod

Make sure to always properly test your mod before releasing it to the public!

Singleplayer

Let's first create a simple singleplayer mission that will spawn a playable character within chernarus on game load.

  • Within your DayZ installation folder, if it doesn't exist create a new folder named 'missions'. Enter the folder.
  • Create a new folder called 'firstMission.ChernarusPlus'. Note that the 'firstMission' is the name of the mission and 'ChernarusPlus' is the name of the world as named within 'CfgWorlds'.
  • Within the newly created mission create the entry point script 'init.c' and paste the following player spawn script
Mission CreateCustomMission(string path) { return new MissionGameplay(); } void main() { PlayerBase player; ItemBase item; // Create player player = PlayerBase.Cast( GetGame().CreatePlayer(NULL, "SurvivorF_Linda", "2200 10 2200", 0, "NONE") ); // Spawn a black t-shirt item = player.GetInventory().CreateInInventory("TShirt_Black"); // Spawn a green short jeans item = player.GetInventory().CreateInInventory("ShortJeans_Green"); // Spawn a brown working boots item = player.GetInventory().CreateInInventory("WorkingBoots_Brown"); // Spawn an apple in the t-shirt, don't redefine 'item' so we can still spawn other items in the t-shirt item.GetInventory().CreateInInventory("Apple"); // Select player the client will be controlling GetGame().SelectPlayer(NULL, player); }

Open a command-line window and run the following command, replacing 'DayZInstallationFolder' with the path dayz is installed at.

start /D "DayZInstallationFolder" DayZDiag_x64.exe "-mod=P:\Mods\@FirstMod" "-mission=./missions/firstMission.ChernarusPlus" -filePatching

Additional mods can be added by being delimited by a semi-colon. For example: -mod=P:\Mods\@FirstMod;P:\Mods\@SecondMod.

We are using the singleplayer mission created earlier.

If you are using the Script Editor within Workbench, you will now see the custom message in the output section every time you jump. If you are not, navigate to your profiles folder ( default: "%localappdata%/DayZ" ) and open the most recent file starting with script. This will contain the message.

Multiplayer

Open a command-line window and run the following command, replacing 'DayZInstallationFolder' with the path dayz is installed at.

start /D "DayZInstallationFolder" DayZDiag_x64.exe "-mod=P:\Mods\@FirstMod" -filePatching -server -config=serverDZ.cfg

where the serverDZ.cfg can be copied from the DayZ Server distribution on Steam. It is loading the 'dayzOffline.ChernarusPlus' mission by default. Within the server configuration, you will need to modify the following options:

BattlEye = 0;			// turn off BE since diag exe does not run with it
verifySignatures = 0;	// if testing mods which aren't properly signed yet
allowFilePatching = 1;  // allow clients with unpacked data to join

You can then join the server by using the following command:

start /D "DayZInstallationFolder" DayZDiag_x64.exe "-mod=P:\Mods\@FirstMod" -filePatching -connect=127.0.0.1 -port=2302


Publishing

Before publishing disable filepatching by removing the launch parameter and pack all the .pbo files again. Verify that everything works without filepatching enabled.

Additional steps you will need to go through when you want to share the mod with the world through the steam workshop:

  • Use DS utils (DayZ Tools) to create a private and public bikey and use it to sign your pbo, as well as include the public bikey in your mod
  • Use Publisher (DayZ Tools) to upload to Steam Workshop