Necrogiant
Leviathan January - 4 - 2012 Articles2 COMMENTS

This guide will teach you how to script a simple mod loader using only a word processor (such as Wordpad or Notepad). Along the way you will learn a few concepts and lines of code which you can apply to any of Painkiller’s Lua scripts.

I wrote this guide using Painkiller + Battle Out Of Hell expansion, but I assume that this will also work with any Painkiller game.

Why Use the Mod Loader?

Easily choose which mods are loaded when you run Painkiller- enable/disable mods individually or just turn mods off altogether. You don’t even have to uninstall or reinstall any mods!

Creates a clean modding environment- each mod is put into a single PAK file and all mods are controlled by a single LUA file. This means any extra files in the Painkiller folder are files from your own mod projects- this removes any confusion as to which files are “your mods” and which are “other mods” (especially if two mods use the same file).

Easy install and uninstall of mods- all you have to do is move (or delete) the relevant PAK file then update the mod loader. No more manually deleting dozens of files spread across many folders!

Help solve mod compatibility issues by turning mods off one by one until you find the problem. Some compatibility issues may be solved just by rearranging the order of each mod’s loader code (more on this in a future update).

Making the Mod Loader

Before I begin, let me tell you something- the developers at People Can Fly created a hook within Painkiller’s code that allows mods to be easily attached to the core game. Each time you run Painkiller it searches the Data/LScripts folder for a file called local.lua and, if it exists, it will run it. There is no default local.lua file, so the developers must have left this hook in the code for modders to use.

Lets create our own local.lua file that allows you to easily enable or disable mods individually (or altogether) without having to uninstall them.

First, open a blank document with Notepad. Go to “File > Save As…” and at the bottom of the save window change “save as type” to All Files. Now save the document as “local.lua” (don’t use quotes or capital letters and don’t forget to add .lua to the end of the filename).

So now you should have a blank document named “local.lua”. Depending on your computer’s configuration, the LUA file type may not be recognized. If double-clicking the file does not open it with Notepad, then right-click on local.lua and select Open With… > Notepad.

Now let’s start our mod loader. First, let’s set a boolean (true/false) variable that determines whether mods are loaded when Painkiller is run. Enter the following line into the local.lua document:

ModLoader = true

Now press enter to start a new line in the document, then type in the following line:

if ModLoader then

What the above line means is this: “If the ModLoader variable is true, then perform all the following lines of code until the ‘end’ line is reached.” Now we will insert our mods, also as boolean variables. I will use the HUDmod and Powermad mods as examples:

HUDmod = true
Powermad = true

So, if ModLoader = true, then the HUDmod and Powermad mods will also be set to true. If ModLoader = false, then the above lines are skipped, which means that the above mods will default to false.

Once you’ve entered lines for each mod, enter the following line to end the ‘if ModLoader then’ statement:

end

That concludes the first half of the mod loader. Simple, isn’t it? Now we will add lines code which will load these mods if they have been set to ‘true’. For each mod you will need AT LEAST these lines of code:

if MODNAME then
FS.RegisterPack(“../Data/Mods/MODNAME.pak”, “../Data/”)
end

Replace both instances of MODNAME above with the name of the mod.

Notice the path to the mod’s PAK file- make sure that the PAK file is located where the path is set to (paths begin in the Painkiller folder). The above example is set to check within Painkiller’s Data/Mods folder (which is where I place my mods), but you can change it if you want to.

Also, make sure that the name used for each mod matches the name in the top section (where the mod variable was set to true or false).

This is all you need to do for mods which do not contain any LUA files themselves. If the mod does contain LUA files then additional code must be added. Look at the following example:

if HUDmod then
FS.RegisterPack(“../Data/Mods/HUDmod.pak”, “../Data/”)
DoFile(path..”Main/Cfg.lua”)
DoFile(path..”HUD/Menu/Options/HUDConfig.lua”)
DoFile(path..”HUD/HUD.lua”)
end

Notice that after the FS.RegisterPack line there are 3 DoFile lines. Each of these DoFile lines will load a LUA file from within the mod’s PAK file. Also notice that the paths are different- instead of starting at the Painkiller folder, DoFile paths begin in the LScripts folder (within Painkiller’s data folder).

Each mod may contain a different set of LUA files (or none at all). In order to add the proper DoFile lines you must know which LUA files are in the mod’s PAK file. You can’t see these files until you extract the PAK- for a guide on how to do this click here.

Once you’ve extracted the PAK check to see if there is an LScripts folder in the extracted contents- if there is, add a DoFile line for each LUA file within the LScripts folder (taking care to preserve the path structure).

That’s it- you’ve just created a simple and effective mod loader!

Save your finished local.lua file and place it in Painkiller’s Data/LScripts folder (go ahead and create the folder if it doesn’t exist). Now Painkiller will automatically load the file each time the game is run.

A Note For Powermad Users

I’ll make it easy for powermad users… the powermad mod only requires a single DoFile, “powermad.lua”. This file is located in the LScripts folder, so the path is left blank (since DoFile paths begin at the LScripts folder). The resulting complete loader code looks like this:

if powermad then
FS.RegisterPack(“../Data/Mods/powermad.pak”, “../Data/”)
DoFile(path..”powermad.lua”)
end

Make sure to either put powermad.pak in the Data/Mods folder OR change the above path to match the location of powermad.pak (it defaults to the LScripts folder).

Using the Mod Loader

To disable all mods: Change the ModLoader variable (in the very first line of local.lua) to false. That’s all you have to do. This allows you to load Painkiller mod-free without having to actually uninstall any mods.

To load specific mods: Leave the ModLoader variable as “true” and just change the true/false values of the mods individually. Only mods set to “true” will be loaded.

To add support for a new mod: Add a variable for that mod (in the format MODNAME = true) and then add the necessary loader code. The variable should be placed after the “if CustomLoader then” line but before the first “end” line. The loader code must be placed after the first “end” line. Also, take care not insert a mod’s loader code in the middle of another mod’s loader code- each loader code must flow from it’s “if MODNAME then” line to it’s “end” line without interruption.

To remove support for a mod: Delete that mod’s variable and loader code.

Creating PAKs From Any Mod

The mod loader is perfect for mods in PAK format, but not all mods come this way. Many mods come as a collection of files or an installer. Well, regardless of the mod’s format it can be converted to PAK format so that it can be used with the mod loader. For a basic guide on how to do this click here. I will not be covering the basics, instead I’ll focus on some more advanced aspects of creating a PAK file.

Music and movies files will not work from within PAKs- Painkiller’s Data folder has Music and Movies folders for a reason. These types of files should go into their respective folders and not into the PAK file itself. Generally this only comes into play when creating PAK files from custom singleplayer levels. As far as I know, no current Painkiller mods come with any movie files.

Mods that have their own separate launcher (such as the singleplayer custom level “Hills”) will require some picking and choosing over which files to keep in the PAK. Basically, you will want to take out any custom menus and redundant files so you can splice the mod onto the main game using the mod loader. I will update this guide with more details about this in a future update.

A Note For Future Mod Makers

If you plan on releasing a mod as a PAK file, it might be a good idea to contain the required mod loader code in a readme for that mod. This way users that want to use this mod loader method can just copy and paste the required code instead of having to extract the PAK, determine DoFile paths, then repackage your mod.

You could also create an installer for your mod which asks the user “are you using the local.lua file to load mods?” If the user picks no then the installer creates a simplified local.lua file which contains only the loader code necessary for your mod. If the user picks yes, then the loader code is provided- something like “Paste the following code into local.lua to add support for this mod”. This is the method which I use for my mods.

An alternative solution is to have a “Mod Loader Codes” database online (perhaps here at PKZone.org) which all mod makers can add their loader code to- a user would just have to check the database to find out the necessary loader code for any mod.

Either way, it is important not to force your mod to create a local.lua file… if the user has created their own mod loader then you don’t want to inadvertently overwrite it.

Hopefully this guide has also convinced some of you that mods in PAK format offer a lot of benefits over loose-file-and-folder mods (for both users and mod makers alike).

Happy modding!

~ Leviathan

 

  • THRESHER

    Wow!  Thanks Leviathan!  Maybe I can code in my modules for some updates for PK++ with this.

    • Leviathan

      No problem THRESHER, glad to help :) You can easily use this to add updates… much better than having to download a whole new version.

Categories

Painkiller is a first-person shooter game released on April 12, 2004. The game takes place in Purgatory and Hell. The main character is Daniel Garner.