RoboMat's Mod Tutorials

Contents

Introduction

Hello there, this is my attempt to write a few modding tutorials for the community. I will try to update this whenever I have some spare time, but please note that I can't make any promises.

Where to start

First things first. When I started looking into the code of Project Zomboid and the different mods I was a bit confused. There was the source code in Java, the additional code in Lua and the scripting language and I didn't really know which one to look into. To spare you this confusion I'll explain their purpose shortly:

  • Java: Most of the source code of Project Zomboid is written in Java. While you can modify the java files it is not recommended.
  • Lua: There already are parts of the source of PZ that have been ported to lua. If you really want to get into modding, you won't get around learning its syntax.
  • Scripting: At the moment it is only used for easily adding items to the game.

While we will cover some of the basics of the scripting language we will mostly work with lua coding. According to the developers changing the java source code won’t be necessary in future versions of Project Zomboid, so we also won’t look into that.

What is needed

Basically to edit a lua file you can use any standard text editor that is capable of saving simple (unformatted) text files. So Wordpad (Windows) or TextEdit (Mac OS) will do. While it is possible to create a script with those programs they miss many features a specific IDE will give you (syntax-highlighting, auto-formatting, etc...).
I prefered working with Eclipse IDE with an extra lua plugin installed for quite some time, but recently switched to IntelliJIdea - haven't been looking back ever since. There are other free alternatives like gedit, Notepad++, ZeroBraneStudio or XCode for example. Find one that works for you and stick with it. Remember: It's not the program that does the work. None of them will turn you into a RobertJohnson over night, they only make your work easier.

Lua Tutorials

If you have some experience with programming already Lua will probably be fairly easy to pick up for you. I mainly used the official manual to learn the language, but of course there are many other great tutorials out there.

What this tutorial won't be

Just to be as clear about this as possible: This won't be a tutorial about lua. It will be a tutorial about modding Project Zomboid. If you don't understand parts of my code, you probably should learn some basic lua syntax first. If there is one thing I don't like then it's people who don't even take the time to read through the tutorial notes, then copy&paste the code and finally spam the thread with questions about "why it doesn't work".
Don't be that person

Other resources

For more tutorials you should visit pz-mods.net and the tutorial section on the indiestone forums. If you have further questions you can post them in the mod help section of the the indiestone forums and one of the many coders will help you for sure.

Last updated: 28.08.2013

 

The first steps

Okay now that we got that out of the way let's move on to the actual modding part.

Getting the connection

To mod the game we somehow have to interact it. Lua's main purpose lies on extending existing programs written in other programming languages. As mentioned in the previous chapter the main base of Project Zomboid was written in Java. That's where the connection between lua and the java source code happens. With lua we can access all the public functions written in the Java source code.

-- lua function
function doStuffInLua(_player)
        -- getSpecificPlayer() is a public method defined in the java source code 
        -- that returns the player. We can access it through lua.
        getSpecificPlayer(_player); 
end

But how do we know which methods there are!? Well, we can look at the javadoc. It's basically a complete list of all methods in the Java source code and it has even been updated to 2.9.9.15 recently. If you want to be on the save side I suggest that you open the source code and look through it yourself. I use a small programm called JD-GUI for that purpose. It has a useful search function that can search through the whole source code. In the course of this tutorial I will mark methods we call from java so you don't have to worry too much about that at the moment.

The entry points: Events

So now we know that we can call Java methods from our lua code, but we still don't know how we actually execute our lua code. We need something that runs our code, when Project Zomboid runs. This will be done with Events. You can think of events as entry points to the source code of the Project Zomboid source code. Once Project Zomboid encounters an Event from a mod it calls the associated function.

-- the function we want to execute
function sayStuff()
	-- Java: we get the first player
	local player = getSpecificPlayer(0);

	-- Java: let the player speak
	player:Say("I like turtles.");
end

-- this event will be fired every ten ingame minutes.
-- In this case sayStuff() is the associated method and
-- thus will be executed every ten minutes. 
Events.EveryTenMinutes.Add(sayStuff);

This short "mod" lets the player talk about his love for testudines every ten minutes in the game. Nothing great but it gets the point across. There are already many different events added to the game which we can use for our mods and the developers are constantly adding new ones. For a complete list check out the Event Reference on pz-mods.net. Don't worry though, we will use some of them throughout this tutorial so you will slowly get the hang of it.

Last updated: 14.08.2013

 

The first mod

Let's continue with a little more complex example. We will create a small cheat script that adds some items to the player's inventory when a certain key is pressed. At first we'll create the function which will add the items to the player's inventory:

Adding Items to the player's inventory

-- We will store all global variables in this table 
CheatMod = {};

function CheatMod.addItems()
	local player = getSpecificPlayer(0);    -- Java: get player one
	local inv = player:getInventory();   -- Java: access player's inventory

	-- Java: add the actual items to the inventory
	inv:AddItem("Base.Axe");
	inv:AddItem("Base.RippedSheets");
	inv:AddItem("camping.TentPeg");
end

As with the previous examples our starting point is the player. We need to "get" him first with getSpecificPlayer(0) (getSpecificPlayer(1) would've given us player two btw). We then can access his inventory with the getInventory() call. Now we can use all the java functions defined for the ItemContainer class and one of them is the nifty AddItem function. It will take an item as parameter and add it to the player's inventory. As you can see, instead of just putting the item name in there, I had to use the prefixes "Base." and "Camping.". These are basically the modules in which the items are defined and only tell the mod where to look for the items. At this point you might wonder how to find out the item and module names. All items are located in /media/scripts/items.txt, /media/scripts/newitems.txt, /media/scripts/camping.txt and /media/scripts/farming.txt at the moment im writing this. Just take a look at these files - the rest should be self explanatory. The code above would give the player an axe, some bandages and a tent peg from the camping module.

Handling keys

But we haven't defined an event yet so the function is pretty useless right now. We want the items to be added whenever the player presses a key and luckily the devs have given us the great OnKeyPressed event for that purpose. Let's add it to our mod:

-- We will store all global variables in this table.
CheatMod = {};

function CheatMod.addItems()
    local player = getSpecificPlayer(0);    -- Java: get player one
    local inv = player:getInventory();   -- Java: access player's inventory

    -- Java: add the actual items to the inventory
    inv:AddItem("Base.Axe");
    inv:AddItem("Base.RippedSheets");
    inv:AddItem("camping.TentPeg");
end

-- ----------------------------------------------------------------------------
-- Hooks
-- ----------------------------------------------------------------------------
-- this will be fired whenever a key is pressed
Events.OnKeyPressed.Add(CheatMod.addItems);

This event will be called whenever a key is pressed in the game. The only problem is, that the event doesn't care which key that is. If we would leave our mod as it is the player would get spammed with countless items. We need to fix that!

Detecting the correct key press

One of the great things about events is, that some of them pass useful parameters to the function which is called through the event. The OnKeyPressed event for example passes the number of the pressed key to the function. The called function in this case is of course our CheatMod.addItems. To use the parameter we have to modify our code another time:

-- We will store all global variables in this table.
CheatMod = {};

-- We added the parameter to the function which
-- will be passed to the function as soon as the
-- event fires.
function CheatMod.addItems(_keyPressed)
    print(_keyPressed); -- prints the pressed key to the console.

    -- We test if the correct key is pressed.
    if _keyPressed == 25 then
        local player = getSpecificPlayer(0); -- Java: get player one
        local inv = player:getInventory(); -- Java: access player's inventory

        -- Java: add the actual items to the inventory
        inv:AddItem("Base.Axe");
        inv:AddItem("Base.RippedSheets");
        inv:AddItem("camping.TentPeg");
    end
end

-- ----------------------------------------------------------------------------
-- Hooks
-- ----------------------------------------------------------------------------
-- This will be fired whenever a key is pressed.
Events.OnKeyPressed.Add(CheatMod.addItems);

Notice the _keyPressed parameter that was added to our function (btw., it is good coding style to add an underscore to parameters to distinguish them from local variables within the code). As I said this will be a number from 0 to 223 (IIRC) with each number standing for a different key on the keyboard. Unfortunately I'm not to sure which numbering method is used but I think it might be the one from LWJGL. But with the print call in the function you will be able to easily find out which number is connected to which key anyway. Save the code as CheatMod.lua and move it to your Project Zomboid /lua directory. When you play the game now, you should be able to cheat the items into your character's inventory by pressing the 'P' key on your keyboard.

Last updated: 02.08.2013

 

X
Basically to edit a lua file you can use any standard text editor that is capable of saving simple (unformatted) text files. So Wordpad (Windows) or TextEdit (Mac OS) will do. While it is possible to create a script with those programs they miss many features a specific IDE will give you (syntax-highlighting, auto-formatting, etc...).
I prefered working with Eclipse IDE with an extra lua plugin installed for quite some time, but recently switched to IntelliJIdea - haven't been looking back ever since. There are other free alternatives like gedit, Notepad++, ZeroBraneStudio or XCode for example. Find one that works for you and stick with it. Remember: It's not the program that does the work. None of them will turn you into a RobertJohnson over night, they only make your work easier.

Comments

  • JoshOfDoom

    Oh! P = the 25th key on your keyboard if you count from left to right from ~ to ENTER! Thanks! I understand so much more about modding Project Zomboid now!

    Mar 6. 14
    1 liked this comment.
You need to be logged in to write comments