Skip to content

Instantly share code, notes, and snippets.

@Shazbot
Last active November 20, 2019 01:00
Show Gist options
  • Save Shazbot/a49b438bef8ae2bb246334198e1ef475 to your computer and use it in GitHub Desktop.
Save Shazbot/a49b438bef8ae2bb246334198e1ef475 to your computer and use it in GitHub Desktop.
Little introduction to using the Execute External Lua File mod in Total War Warhammer 2

So, we have our scripts in a pack, but it'd be nice if we could pull out functions, or tables with data, or listeners, and modify them on the fly using exec.lua. So to do that we need access to those things from external files, i.e they need to be globally accessible. Therefore, we need our mod to put those references into a globally accessible table. We initialize this global table like this:

MYMOD = MYMOD or {}

this is just shorthand for

if not MYMOD then
	MYMOD = {}
end

it means: if MYMOD exists, use that, if it doesn't create it as an empty table. Global tables are usually a bad, bad thing, use a prefix and give the table a unique name like PJ_EMP_TROOPS, we don't want to overwrite any other existing tables inadvertently.

Then, we put new functions inside that global table, instead of making them local:

MYMOD.give_gold = function()
	cm:treasury_mod(cm:get_local_faction(), 10000)
end

So let's say we have the MYMOD.give_gold function above inside a script that is inside a pack, and we want to test it or modify it.

It'd be nice if we could just say instead of that function always call another one in its stead. Well, if the function gets called via a global reference, and we have access to that reference, that's possible. Just make MYMOD.give_gold a new function:

MYMOD.give_gold = function()
	cm:treasury_mod(cm:get_local_faction(), 15000)
end

We can do this from inside exec.lua and MYMOD.give_gold will get globally overwritten. Now MYMOD.give_gold() gives 15000 gold.

To recreate event listeners use remove_listener before every add_listener, for example:

core:remove_listener("test_listener")
core:add_listener(
	"test_listener",
	"CharacterSelected",
	function(context)
		return true
	end,
	function(context)
		local cqi = context:character():cqi()
    out(cqi)
	end,
	true
)

I can freely modify the listener, and when I press F9 it will be updated ingame.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment