Jump to content

[Guide] Modding Practices: Introduction to Modding


Recommended Posts

Chapter 02: Introduction to Modding
 
Introduction
In the previous chapter you learned how to set up your workstation to achieve the maximum efficiency and productivity. In this chapter you will be introduced to Lua the language behind Don't Starve and Don't Starve Together modding. You will also learn how to begin creating Don't Starve and Don't Starve Together mods at a basic level. At the end of this chapter you will have successfully created your very first mod.
 
Let's begin todays lesson.
 
Understanding Lua
Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-drive programming.
 
What does this really mean?
In short, it means Lua consists of a very loosely written and case-sensitive syntax.
 
What does syntax mean and how is it relevant?
A language syntax is the arrangement of the code which is written; it is what gives life to all programming languages and must be followed at all times. If you break from the language syntax you will ultimately receive errors or bugs, many of which can be avoided by following the language syntax.
 
In lua you will use identifiers as your variables. An identifier can be any string of letters, digits and underscores, but cannot begin with a digit. Most names which begin with an underscore followed by a capital letter are reserved for internal global variables used by Lua. It is recommended to never start a name with an underscore to maintain language integrity.
 
Lua offers many of the conventional keywords and operators that exists in other programming languages.
 
What are keywords?
Keywords are special variables which a programming language uses to denote special functions. We will go into more details about these in a moment.
 
What are operators?
Operators are much like keywords except they are special symbols which denote special functions. We will go into more deatils about these in a moment.
 
Now that you understand a little more about lua, let's learn about the different keywords and operators.
 
Keywords
The following keywords are reserved and cannot be used as variable names.
and          break         do
else         elseif          end
false        function      if
in             local           nil
not           or               repeat
return      then            true
until         while
 
Lua is a case-sensitive language, this means that only and is reserved. You may name an identifier And or AND, because they are valid names. Let's talk a little more about what each keyword accomplishes.
 
and
The and keyword is used to determine whether one variable and another variable both return true.
 
break
The break keyword allows us to jump out from a loop. This statement breaks the inner loop (for, repeat, or while) that contains it; it cannot be used outside of a loop. After the break, the program continues running from the line immediately after the broken loop.
 
do
The do keyword is used to create an inner block and must be used with the for and while loop. You can use it independently along with the end keyword to create an inner block.
 
else
The else keyword is used in conjunction with the if-then keywords to denote that if false then do something differently.
 
elseif
The elseif keywords is used in conjunction with the if-then keywords to denote that if false then check for another true/false statement.
 
false
The false keyword returns false.
 
function
The function keyword is used to create a specific task to be done. This keyword is the main mechanics for abstraction of statements and expressions in Lua.
 
if
The if keyword is used to determine if an equation is true or false. The if statement must always return true or false.
 
in
The in keyword is used in conjunction with the for keyword to create an object oriented loop.
 
local
The local keyword initializes the variable as a local variable or function instead of a global variable or function.
 
nil
The nil keyword will return a nil or nonexistent value.
 
not
The not keyword is used in true/false equations to determine if the equation is not true.
 
or
The or keyword is used to determine whether one variable or another variable returns true.
 
repeat
The repeat keyword creates a loop which will repeat until the conditions of the loop are met. Unlike the while loop, this condition is checked after the code in the inner block is executed.
 
then
The then keyword is used in conjunction with the if keyword to denote that if true then do something.
 
true
The true keyword returns true.
 
until
The until keyword is used in conjunction with the repeat keyword to create a loop until the conditions of the loop are met.
 
while
The while keyword is used to create a loop while the conditions of the loop has not been met. Unlike the repeat loop, this condition is checked before the code in the inner block is executed.
 
Operators
The following operators are reserved.
+     -     *     /
%     ^     #     ==
~=    <=    >=    <
>     =     (     )
{     }     [     ]
;     :     ,     .    ..    ...
 
+
The + operator performs addition.
 
-
The - operator performs subtraction.
 
*
The * operator performs multiplication.
 
/
The / operator performs division.
 
%
The % operator performs modulo operations.
 
^
The ^ operator performs exponential operations.
 
#
The # operator returns the length of a string or number of values in a table.
 
==
The == operator performs an equal to check.
 
~=
The ~= operator performs a not equal to check.
 
<=
The <= operator performs a less than or equal to check.
 
>=
The >= operator performs a greater than or equal to check.
 
<
The < operator performs a less than check.
 
>
The > operator performs a greater than check.
 
=
The = operator is used to set a value to a variable. e.g. i = 10; i will now contain the value 10.
 
()
The ( ) operators are used to enclose parameters of functions or to denote order of an mathematical equations.
 
{ }
The { } operators are used to create tables in Lua.
 
[ ]
The [ ] operators are used to access a specific variable in a table.
 
;
The ; operator is used to start a new line of code on the same line.
 
:
The : operator is used when calling a function. The self variable will be sent when the function is called.
 
,
The , operator is used to denote a change in parameters on functions.
 
.
The . operator is used to call a function. The self variable will not be sent when the function is called.
 
..
The .. operator is used to concatenate two variables or strings together.
 
...
The ... operator is used to denote there are an unknown amount of variables being sent to a function.
 
Keywords and Operators are used commonly throughout the lua language and should be studied until you understand what each one does. By understanding what each keyword and operator does you will be able to create beautifully optimized code that is bug free in the future.
 
Commenting our code.
Commenting code in any programming language is a core concept that most new modders do not realize the importance. By commenting our code we can write a description of what a line or function does in order to refresh our memory if we leave the project for several weeks.
 
In order to comment a line out in Lua you simply use a double hyphen symbol (--) and then the text you would like to comment out. You may also use (--[[) to start a multiple line comment; to stop comment simply use (]]).
 
Don't Starve Basics
In order to begin creating mods for either Don't Starve or Don't Starve Together you need to understand the very basic core to mods themselves. In this section you will learn the files you need to create in order to create your first mod and how to properly debug the mod if you receive errors.
 
Required Files
The following are the required files to create a mod:
 
modinfo.lua
The modinfo.lua file is used to contain informtion about your mod including, but not limited to the name, version number, author, description and configuration options.
 
modmain.lua
The modmain.lua file is the core file that is used to load your mod. This file is required even if it's empty.
 
modworldgenmain.lua
The modworldgenmain.lua file is required if you are creating a mod which alters the world generation. Otherwise this file is not required.
 
Icon Files
Both a .tex and .xml file are required in order to give your mod an identifying picture or icon in the games mod menu. It is recommended to name these "modicon" or equivalent to denote the purposes of the files.
 
Folder Structure
The folder structure of a mod is identical to the folder structure of the game. That is a new prefab is located in scripts/prefabs, a new component is located in scripts/components.
 
Debugging your mod.
In order to debug your mod you need to first understand where the debug information is found. The file in question can be found at the following location:
 
Windows
Documents\Klei\DontStarveTogether\log.txt
 
Linux
.\Klei\DontStarveTogether\lox.txt
 
In this file, if an error occurs, you will find it near the bottom. It should look similar to the following error message:
[string "scripts/componentaction.lua"]:766: attempt to index to index field '?' (a nil value)LUA ERROR stack traceback:   scripts/componentaction.lua:766 in (method) CollectActions (Lua) <753-780>    scripts/components/playeractionpicker.lua:39 in (method) GetSceneActions (Lua) <36-60>   scripts/components/playeractionpicker.lua:152 in (method) GetLeftClickActions (Lua) <117-171>   scripts/components/playeractionpicker.lua:223 in (method) DoGetMouseAction (Lua) <210-228>   scripts/components/playeractionpicker.lua:980 in (method) OnUpdate (Lua) <894-1213>   scripts/update.lua:151 in () ? (Lua) <118-180>/spoiler]
 
Let's break this down line by line.
[string "scripts/componentaction.lua"]:766: attempt to index to index field '?' (a nil value)LUA ERROR stack traceback:
In this line we see that on line 766 of the file scripts/componentaction.lua we are trying to index field '?' which is a nil value. We learned from earlier in the chapter that a nil value is essentially a nonexistent value.
 
scripts/componentaction.lua:766 in (method) CollectActions (Lua) <753-780>
In this line we see that the method which was called last is the CollectActions function in file scripts/componentaction.lua.
 
scripts/components/playeractionpicker.lua:39 in (method) GetSceneActions (Lua) <36-60>
In this line we see that the method which was called before CollectActions function is the GetSceneActions function in the file scripts/components/playeractionpicker.lua.
 
By understanding this we can figure out exactly where we need to look in order to debug our mod. In this example, we would look at the scripts/componentaction.lua file on line 766 and determine why our variable was nil.
 
Creating your first mod.
Now that we know the core files to create, how to debug our mod if errors occur and a little about Lua it's time to create your first mod. Let's start by creating our mod folder, let's name it "Example Mod 1". Open your favorite text editor and let's begin, remember to review the comments in the code for explanation of what each line does.
 
In your text editor we will start designing our modinfo.lua file. We do this by entering the following code.

name = "Example Mod 1" -- This is the name of the mod.description = "This is an example mod." -- This is the description of our mod.author = "Me" -- This is the author of our mod.version = "0.0" -- This is the version of our mod. It's used for the Steam Workshop, you cannot upload a version which is the same or less than the currently uploaded mod.forumthread = "" -- This is a link directed to a forum thread of the mod.api_version = 6 -- This is the latest Don't Starve api version and is only used for Don't Starve.api_version = 10 -- This is the latest Don't Starve Together api version and is only used for Don't Starve Together.dont_starve_compatible = false -- This is used to denote that the mod is compatible with Don't Starge.reign_of_giants_compatible = false -- This is used to denote that the mod is compatible with Don't Starve: Reign of Giants.dst_compatible = true -- This is used to denote that the mod is compatible with Don't Starve Together.all_clients_require_mod = false -- This is used to denote that players should be forced to download the mod from the Steam Workshop or use a cached version on the clients computer. Setting this to false makes it so that a client does not download this mod. Server only or client only mods should set this to false, all other mods should have this set as true.client_only_mod = false -- This is used to denote that this mod is for clent use only. If all_clients_require_mod is set to true this variable must be set to false. -- We will learn how to create icon.xml and icon.tex files in Chapter 03 of the Modding Practices series. For now we will comment these lines out.--icon_atlas = "icon/file/path.xml" -- This is used to indicate the image in the icon.tex file.--icon = "icon/file/path.tex" -- This is used as the image of the icon.-- This variable is used to denote the fliter tags that a server obtains when your mod is enabled.server_filter_tags = { -- This variable is a table with the name of server_filter_tags."tag 1", -- This is our first filter tag available, remember that a comma must be at the end of this line to allow for more variables to be inserted into the table."tag 2", -- This is our second filter tag available, remember that a comma must be at the end of this line to allow for more variables to be inserted into the table.}-- This varliable is used to create configuration options for our mod. We will learn how to obtain these settings in a later chapter of the Modding Practices series.configuration_options = { -- This variable is a table with the name of configuration_options.{ -- This is a nonnamed table variable.name = "Option.Name", -- This is the name of the option.label = "Option 1", -- This is the label used to visually display the option.hover = "This is a hover description.", -- This is the hover text displayed when a user hovers over the option.options = { -- This variable is a table with the name of options.{ -- This is a nonnamed table variable.description = "Selection 1", -- This is a selectable option for this configuration options.data = true, -- This is the data which the option contains.},{ -- This is a nonnamed table variable.description = "Selection 2", -- This is a selectable option for this configuration options.data = false, -- This is the data which the option contains.},},default = false, -- This is the default value our configuration option is loaded with before setting it.},}
Save the file in our mod folder as modinfo.lua and create a new file in your text editor.
 
In your text editor we will start designing our modmain.lua file. We do this by entering the following code.
-- This function is what will be called by the AddPlayerPostInit function.local function PlayerPostInit(inst) -- The inst parameter is sent to our function and is the instance of our player.-- This line checks to see if the freezeable component is initialized on the current player.if inst.components.freezeable then-- Because it was initialized we want to remove it.inst:RemoveComponent("freezeable") -- This line removes the freezable component from our player.end -- This is to end our check.-- This is used to return the instance of our player so the game picks up the modifications.return instend -- This ends our function.AddPlayerPostInit(PlayerPostInit) -- This function is called every time a player joins the server.
Save this file as our modmain.lua.
 
Congratulations you've just successfully created your first mod. The purpose of this mod is to make all characters immune to freezing.
 
Conclusion
Creating mods for Don't Starve and Don't Starve Together can look very complicated at first glance, but as you learn about each of the items which are required to create the mods you will begin to get both comfortable and confident in your ability to create superb mods that many players will enjoy. Never get discourages and remember that the Klei Official Forums: Mods and Tools section for either game has many veteran modders willing to help. So if you have questions start your own topic and provide as much information including your log.txt and a copy of your complete mod as a .zip file to reduce the hassle and increase response time.
 
Please post any questions, concerns or suggestions below.
 
~Kzisor/Ysovuka
 
Edit:
Grammar and spelling check failed. Most if not all are corrected.
Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, Great continuation of your first guide, though there is some things that I think you could improve.

 

The order in which you introduced keywords (in alphabetical order) is quite strange; it would have been better to introduce a keyword then follow up with its related keywords (why do you start talking about the else keyword if you haven't even introduced the if keyword, as else can't work without an if?).

 

You could also give more examples of those keywords working together. You could have used the if ... else structure to show how if, else, elseif, and and or work together. Same can be said about for, while and repeat/until.

 

You did gave a link to Lua documentation in your previous guide, but if this guide is targeted to beginners, those documentations aren't really beginner-friendly (They use BNF notation!). That documentation is, I think, more targeted to experienced programmers who want to learn the syntax of Lua.

 

Now, I guess it forces beginners to look into the game's code to learn how those keywords work together, as looking into the game's code is a big and necessary part of modding. :razz:

 

Your presentation of modinfo.lua is also a little messy, there's comments everywhere!

Maybe it would have been better to split it into multiple spoilers, one for DS, one for DST, and one for the configuration options?

 

 

Everything else is great though, and well-explained!

 

 

Oh, and about commenting, you forgot to mention multiline comments:

--[[ commentsmore commentsthat's enough commentsthank god no more comments ]]
Link to comment
Share on other sites

@Jjmarco, as usual thank you for the feedback. I could rearrange the keywords, however, the order I didn't feel was important as you said, most modders are required to look into the game files any way and will see exactly how they play in relation to each other. They could also use Google or another search engine to quickly find out how to structure statements.

 

As far as modinfo.lua goes, yes I agree it is messy. However, I felt that no matter the presentation that would be shown to a very beginner it would always be messy and/or incomplete. It is my opinion that modinfo.lua is not beginner friendly in any way. However, it is also my opinion that I don't believe that there could actually be a proper way of handling everything that file handles unless we were to remove the configuration options and put them into a separate file.

 

Edit:

Also about multiple line comments, that completely slipped my mind adding it now.

Edited by Kzisor
Link to comment
Share on other sites

  • Developer

Nice work!

It might be worth adding a section on code style for readability. Things like tab aligned scoping, camel case and '_' separated variable names making reading other people's code and your own code (at a later date) much easier.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...