How to use Progression Framework

Overview
(specifically the  file inside it) defines the   class that you should instantiate for a specific character. For those not familiar with object oriented programming, an analogy is that the LiProgression class describes what Car objects are (that you can drive them, fill them with fuel of various types, that they have wheels, and other properties and how you can use them), and to instantiate them means describing a specific single car (this 2023 Ford Mustang that runs on petroleum). Instances are made for Morathi, Miao , and Katarin in the progression stages pack files (e.g.  ). These are defined globally (without the   keyword in its assignment statement) so then we can access them in other files.

Example Instantiation
See the progression stages above for more examples of how to instantiate a character's progression, but it boils down to finding some properties and using some conventions for defining them in the tables. Note that the following may become outdated and you should check the code in the packfiles for the latest version:

local kat_faction = "wh3_main_ksl_the_ice_court"; local kat_subtype = "wh3_main_ksl_katarin"; local LI_KAT_MAIN_EVENT = "ScriptEventKatarinCorruptEvent" local confed_factions = { "wh3_main_ksl_the_great_orthodoxy" }; local kat_art_set = "wh3_main_art_set_ksl_katarin"; local names_name_id = "150649774"; li_kat = LiProgression:new("katarin", kat_faction, kat_subtype, kat_art_set, LI_KAT_MAIN_EVENT, confed_factions, names_name_id);

cm:add_first_tick_callback(function li_kat:initialize end);

With the ordered arguments having meaning ---@param main_shortname string Short name for logging ---@param main_faction string faction key for main character to be corrupted ---@param main_subtype string subtype key for main character ---@param main_art_set string art set prefix for main character ---@param main_event string custom event name for the main corruption event (e.g. ScriptEvent CorruptEvent) ---@param confed_factions table[string] array of faction keys that could possibly confederate the main character ---@param names_name_id_prefix string prefix of names name ID (stage will be appended to become new ID for each stage's name)

Usage
You can then use methods of the created progression object to trigger progression, which will keep track of it across save games and do internal bookkeeping. Check the  file for all methods on the progression object, but some commonly useful ones include (with   and   as example progression instances):

Retrieving the Character
This will retrieve the character script interface regardless of what faction Miao's in (can get confederated into another faction). local miao = li_miao:get_char;

Registering a Stage
Define a stage by giving a callback for what happens when progression is triggered, and what to do when you enter this stage local name = "fishnet"; local this_stage = 2; li_miao:stage_register(name, this_stage, progression_callback, stage_enter_callback);

Triggering Progression
Call this inside of CA events, passing it the current context (that the CA event will give you), and whether the triggering agent is human or not.

Listener on "BattleCompleted" CA event that will call our method whenever a battle is completed core:add_listener(       "BattleCompleted_offer_amulet",        "BattleCompleted",        true,        initial_amulet_offer_after_battle_listener,        true    ); local function initial_amulet_offer_after_battle_listener(context) ...   local character = li_kat:get_char; local faction = character:faction; if faction:is_human then ...       li_kat:trigger_progression(context, true); else local rand = cm:random_number(100, 1); li_kat:log("AI rolled " .. tostring(rand) .. " against chance of being offered amulet " .. ai_trigger_chance) if rand <= ai_trigger_chance then li_kat:trigger_progression(context, false); end end end

Advancing Stage
This should be called inside of the progression_callback you pass to the stage_register method. It does the actual advancing of the stage to the next one. The progression callback should advance depending on the choice of some dilemma (or you can advance without any user choice), but the idea is that there may be many ways to trigger progression, but you get the same choice to progress in each case. For example, Miao can progress diplomatically, after combat with a Slaanesh faction, or through taking a Realm of Chaos gift (all cases where  is called).

local trait_name = "li_trait_corrupt_amulet"; local this_stage = 1; li_kat:advance_stage(trait_name, this_stage);

Logging
You'll want to log things that happen in your script to help debug li_kat:log("This is something that will show up in li_log.txt" .. "another part of the string"); li_kat:error("Use this where you check for things that shouldn't happen but did");

Getting and Setting Stage
You need to register the stage first to set it. You should generally not set the stage directly and use this more as a debugging tool. local stage = li_miao:get_stage; li_miao:set_stage(3);