Paladin's Oath

Paladin's Oath

Not enough ratings
How to create New Scenario Modes (LUA Scripting)
By Yohan
This guide describes how to use the powerful modding system for Paladin's Oath to create new scenario extensions for the game. These extensions allows changing the way the game works in radical ways and require some basic scripting knowledge (like Javascript or LUA).
   
Award
Favorite
Favorited
Unfavorite
Scenario Extension Mods
Since v1.7.0 the game supports the creation of Mods containing scripts written in the LUA programming language to customize the behavior of the game. Before getting started on creating those scripts, you should first read the general guidelines[paladinsoath.fandom.com] about how to create and publish mods. If you have any issue, blockers or suggestions feel free to join the Discord server[discord.gg] where we you can ask your questions to the developer of the game or the community of mods developers.

Scenario Extensions

With v1.7.0, the game supports a new kind of mod called Scenario Extension. These extensions are declared like other mods (see guidelines[paladinsoath.fandom.com] about using mod.json and associated sample mod zip file[drive.google.com] for the format of the scenario extension mod.json). You can also look at the sample mods in the Steam workshop of the game (ex: the Shadow of Death mod).

Scenario Extensions mods are written using a LUA[www.lua.org] script (similar syntax as Javascript). When a player configures a new crusade/scenario, they can select one or more Scenario Extensions to attach to that scenario. The script for each selected extension will be loaded when the scenario starts (or is resumed after a save->load). Then throughout the lifecycle of the scenario, the game will execute callbacks declared by the script passing in some contextual information and the full gameState and associated APIs to mutate it. Any mutation performed by the script will then be reflected onto the UI and also persisted in the save file.
Game Scripting API
The API for the LUA scripts is described fully in the Paladin's Oath game Wiki[paladinsoath.fandom.com]. The Steam guide will only cover the basic concepts, please refer to the Wiki for the extended version with sample code too.

Context and Mod State

Most of the LUA functions that the game calls get a context object passed in. The context contains information related to the mod and scenario extension as well as access to some API to store and retrieve state pertaining to the execution of the script.

Managing State for the Script via ModState

It is highly recommended that you avoid relying on global variables to manage the state of your mod. The reason being that the game needs to support the ability for players to save and reload the game at a later time. When a game is reloaded, a new LUA runtime is created to run your script and thus the previous script global state is lost / will not be recovered. To help you with managing persistent state between various calls to the lua hooks, the game passes a ModState API to LUA via the context object. You can use ModState to read and write strings, booleans, and integers values into the state (indexed by a string key). These values will be persisted into the game save file and restored on next game load and passed to your script every time it is called.

You should use ModState if you need to store and retrieve information in-between calls to your script that you cannot find in the gameState itself. For example the Shadow of Death mod which spawns an enemy that follows the player around uses ModState to store information about the last known position of the player, whether the enemy has spawned and was killed.

Debugging the Scripts

The game offers rudimentary support for developers to debug their scripts. Ultimately the game won't tell you if your LUA script has syntax errors so you should double check your lua syntax yourself. But the game helps you in testing the behavior of your script a little bit.

First the game automatically pops up a new panel for script debugging at the Campfire and at the Exploration screen. The panel shows a drop down with all active dev mods with scripts. You select yours and you can click the buttons to reload the script and also trigger some lifecycle events. Note that If you are downloading mods from the internet (not Steam) the panel will always show up unless you disable the panel in the Game Options > Mods > Developer Mode.

Lifecycle Events
A scenario (or Crusade) has multiple events happening from the start of a scenario to the end of it. Each major event has a corresponding hook that the LUA script can implement to react to it. See Paladin's Oath Wiki[paladinsoath.fandom.com] for all the events that the script can hook into. Typically they are high-level events like: OnCrusadeStarts, OnCrusadeEnds, OnTurnStarts, OnTurnEnds, OnRoundStarts, OnRoundEnds, ...

Script must be a good citizen

The game loads an individual runtime for each scripts meaning there is no risk that the variables and method names used in one script conflicts with another script. But it's important to understand that scripts are expensive to run and if a game has multiple mods to run sequentially it might slow down the game if the scripts are not optimized. The Wiki[paladinsoath.fandom.com] provides some examples of optimizations and other aspect of script writing you need to pay attention to like expected order of operations, how to avoid breaking the game state, how to cache API calls, etc.

Game API

The Wiki[paladinsoath.fandom.com] provides the full scripting API which provides a direct access to the entire game state, game resources and common game values. This allows you to modify the game state in reaction to scenario events, for example giving a wound to a player every time they explore, or having monsters follow the player around, or completely changing the map and enemies at night.

Some of the Game entities you have access to:
  • Crusade Info - how the scenario is configured, number of rounds left, ...
  • Map - all revealed sections and hexes and their content and exposes various mutation APIs
  • Market - read and write followers offer, ambient mana pool, etc.
  • Player & Dummy Player State - modify player state, acquire cards, mana, followers, ...

Hopefully this inspires you to join the community of players already contributing to the game and you will come up with cool new game modes :)