Campaign Index

Welcome to the homepage for campaign scripting in Total War. Here you can find resources and guidance for the creation of scripts that will run in campaigns.

Quick Links:

campaign_manager

episodic_scripting

model_hierarchy (internal documentation) and Model Hierarchy (direct link to external documentation)

old episodic scripting interface - now obselete

If any of the links above are dead then launch a campaign in the game. The old-style episodic scripting interface and model hierarchy documentation are generated by code when a campaign is run.

Relevant in Campaign Loaded in Campaign
Relevant in Battle Loaded in Battle
Relevant in Frontend Loaded in Frontend
Back to top

Script File Locations

The first script that is run when a particular campaign loads can be customised in the relevant record in the campaigns table, in the script_path field. By convention this is data\script\campaign\%campaign_name%\scripting.lua.

From Warhammer onwards, all campaign scripts can be found in data\script\campaign\ (as well as data\script\_lib\, for library scripts related to campaign). This data\script\campaign\ folder contains a number of subfolders, all of which may contain script files. Script files in those folders should contain functionality related to their location in the folder structure:

Folder PathComment
script\campaign\Scripts potentially related to all campaigns in this project.
script\campaign\%campaign_name%\Scripts related to a particular campaign.
script\campaign\%campaign_name%\factions\%faction_name%\Scripts related to a particular faction in a particular campaign.

For more information see the page about campaign_script_structure.

Back to top

Episodic Scripting Interface

The campaign model provides an interface of functions that can be used to query and modify the campaign state, known for historic reasons as the episodic scripting interface. This is the main interface through which scripts can modify the state of the game in campaign. Documentation for it can be found here: episodic_scripting

These functions are provided through a game_interface object. The object is stored internally by the campaign_manager, which also provides a pass-through interface to it. This means that functions on the episodic scripting interface may be called on the campaign manager e.g. cm:enable_ui(false). Scripters are encouraged to call functions on the episodic scripting interface in this way, rather than trying to get an interface to the underlying game_interface object, as in many cases the campaign_manager overrides the underlying call and adds additional functionality.

Back to top

Model Hierarchy

Read more about the Model Hierarchy in the dedicated page here: model_hierarchy

Quick link to the external model hierarchy documentation: Model Hierarchy

The campaign model also provides a model hierarchy that may be navigated around and queried by script. The model hierarchy represents the main way that scripts can read the state of the game in campaign.

The model hierarchy is mostly used when a campaign event is triggered - see documentation on scripted_events. From the context provided by event, the script may navigate amongst objects querying their state. For example, the FactionTurnStart event provides a context object from which the faction that is starting its turn may be derived. The interface of this faction object may be further queried to get a list of region objects that the faction owns, military_force objects that the faction controls, a character object representing the faction leader, and so on. These objects in turn may be asked for further related objects (e.g. get the settlement of the region of the faction leader character of the faction starting its turn) allowing scripts to perform tests of any feasible complexity on the current state of the game.

For the most part, this model hierarchy is read-only - (nearly) all function calls that modify objects are found on the episodic_scripting interface.

loaded in campaign

Back to top

Campaign Script Libraries

The campaign script libraries are built on top of the episodic_scripting and model_hierarchy interfaces provided by the campaign model, and offer extensive additional support and extended functionality for campaign scripting. The main script object through which campaign calls are made is the campaign_manager.

Other script objects exist in addition to the campaign manager, documentation for which can be found in the Script Interfaces list in the navigation bar on the right-hand side of this page. The main script objects related to campaign are listed below:

ObjectDescription
coreCentral object that provides functionality shared across both campaign and battle, such as ui querying and event listeners.
campaign_managerCentral interface object for campaign scripts. The main campaign episodic_scripting interface is accessed through this object.
campaign_ui_managerCentral campaign object providing functionality specifically related to the user interface.
mission_managerWrapper object provided functionality related to the declaring and management of missions.
campaign_cutsceneObject interface for creating scripted cutscenes in campaign.
interventionA mechanism for stopping progress in the game to allow one bit of script to play through to completion, such as some advice or a scripted tour.

Other script library interfaces are listed under the Script Interfaces section of the bar on the right of this page.

Back to top

Events

Read more about events in the dedicated page here: scripted_events

Campaign scripts rely on the script event system to receive notifications about events happening in the game. While running, the game triggers script events when particular changes in the state of the model (or the UI) take place. Scripts may register functions as listeners for script events in order to be notified of these changes. Should a lua function be registered as a listener for an event then that function will be called when the event is triggered by the game. Furthermore, the game provides a userdata context object to the function being called which can then be queried to determine more information about the change taking place. Script events are triggered in all game environments, but they are used most extensively by campaign scripts.

Examples of campaign events include when a faction starts a turn (FactionTurnStart) or when a character is created (CharacterCreated). In the former case the context would contain information about the faction involved, in the latter the context would contain information about the character. For a list of events in the game and more information about context interrogation see the external model hierarchy documentation: Model Hierarchy

The recommended method for scripts to listen for an event is by using the core:add_listener function. See an example of this below.

Example - PendingBankruptcy listener:

Listen for a PendingBankruptcy event for a particular faction
core:add_listener(
    "faction_turn_start_listener",                                    -- name for listener
    "PendingBankruptcy",                                            -- event to listen for
    function(context)                                                -- test to perform prior to triggering callback
        return context:faction():name() == "wh_main_emp_empire"
    end,
    function()                                                        -- callback to trigger
        empire_pending_bankruptcy()
    end,
    false                                                            -- continue listening after trigger
);
Back to top

Script Output

See the section on Output for more information about how to print debug output.

Back to top

Time Intervals

Script functions can be registered to be called in the future using the campaign_manager:callback command. Other commands are available with which to register functions to be called later - see the Timer Callbacks section.

Example:

-- call function one second from now
cm:callback(function() example_function() end, 1);
Back to top

Campaign Co-ordinates

The campaign contains two co-ordinate systems that are overlaid on top of one another: logical and display. Logical co-ordinates define the position of a hex in the logical data, and are used to position logical game objects that can only occupy a hex, such as a military force or a settlement. Display co-ordinates define the position of objects that don't exist in the logical game data, such as visual props or the camera.

The logical and display positions of the cursor may be shown in campaign by selecting controllers -> Campaign Debug and then UIs -> Cursor position from the debug dropdown menus. The hexmap map may also be drawn over the campaign map by selecting UIs -> Pathfinding Debug and also Warscape -> Debug Line Renderer. This hexmap and the co-ordinates of each hex should conform to the source hexmap in the Twitch tool.

The game can be instructed to output the display co-ordinates of the camera by entering the command camera_position on the console. The co-ordinates then printed to the command tab.

Example:

camera_position
Camera target: 201.634811, 520.228577; distance: 18.334259, bearing: 0.0, height: 9.76396 (201.634811 520.228577 18.334259 0.0 9.76396)
Last updated 12/08/2022 11:56:57