Effects

From Total War Modding

Whenever you pick a new skill for a character, or gain an item, or apply a banner to a unit, or build a building - you are getting and using effects.

Effects are one of the most common game objects in all of Total War, and they drive a vast majority of any sort of dynamic/changing values throughout the game, and many game play systems. For example - the income from buildings is done through effects; attrition immunity is applied through effects; stat changes for units (ie. +Melee Attack for all archers) are done through effects.

Learning how to create and alter effects is a fundamental part of being able to make meaningful edits to the game.

NOTE: Written with R2/3K/WH2 in mind, this information should be valid from Empire to the present though. Please share if there are any inconsistencies.

The Effect Ecosystem:

Before we get into how to set up effect, lets take a quick look at how they are integrated into the game – at first glance, it can be a little overwhelming so lets just start simple and work our way up!

A diagram showing the table relationship of effects


You define your effect in its own table.

You can then define what it effects through the MANY effect_bonus_values_ tables, and the ones you use depend on what you want to use the effect on.

Finally, you attach the effect to the “thing” in game that will apply it. There are two core ways of doing this.

  • Many systems in the game are built to apply effects through an effect bundle (literally a bundle of one or more effects that get applied in one go). It’s worth noting, this is the only method of applying effects via script.
  • There are a good number of systems that forgoe effect bundles and hook up directly to the effect, skipping the need of an effect bundle, for example building levels or ancillaries.

And that is largely it, in a nutshell!

Anatomy of an effect:

At the heart of all effects is the effects_table db file.

Sample of the effects table.png


This table defines a few important things:

  • Key: This is the unique key for this effect. Name it uniquely, and name it in a way so that you can tell what it does! You will be referring to this a lot in other tables.
  • Icon | icon_negative: defines the icon this effect will display when it’s having a positive effect and negative effect.
  • Description: This is the text that will be displayed (note that you’re going to need to define this in a.loc file in rPFM).
  • Is_posititve_value_good: This means that, if your value is a positive integer and this bool is set to true, the text will show up as green; if your value is negative and this bool is set to false, the text will show up as red.
  • Priority: 0 will result in the effect being hidden. Otherwise, the higher the number, the lower on a list the effect will be displayed in the UI.
  • Category:  which determines where an effect shows up.


Unfortunately, the above table only creates the foundation for an effect, it’ll show up in the UI but nothing happens. Sometimes, this is all you may want, here are plenty of dummy effects in the game already that add a UI element to the game for things done in script!

To make real change, we’re going to need to delve into the realm of effect_bonus_values, these allows us to hook up effects to bonus value ids, the games way to connect an effect to “stuff” in the game that the effect will impact.

Bonus Value Ids:

Bonus value ids are essentially the way an effect modifies a given “thing”. Below you can see all the ways you can modify unit abilities with an effect.

Example bonus value ids.png


You cannot create a new bonus value id. Sorry. Just the way it is.

With this in mind, don’t get too caught up with knowing all the Bonus Value Id’s. There are a lot of them and many of them will never show up in your modding activities, best to look at the ones tied to what you want to achieve and 99% of the time, you can just imitate what effects in the base game are already doing.

Effect Bonus Value Tables:

OK, so we’re here! This is where we connect your effect to the bonus value and define the id to modify it! I’m afraid this is highly contextual and really depends on what it is you want to achieve. So I’m going to give a couple of examples to help demonstrate and hopefully that will be enough to get you started.

Army Abilities:

Here you can see two effects one enables the usage of an army ability and another increases the charges of an army ability by one. This is defined in the effect_bonus_value_military_force_ability_junctions table.

effect_bonus_value_military_force_ability_junctions_tables

Units (sets):

Here you can see two effects that that give “barrier health”. One to the unit set that covers all skinks, the other to a unit set to all Saurus.

effect_bonus_value_ids_unit_sets_tables


Here you can see two effects that that give a redirect aura to the two same unit sets, but done in a different table.

effect_bonus_value_unit_set_unit_ability_junctions_tables

Buildings:

And here, we can see two effects that modify the building set for high elf defences. One modifies the building cost, the other the build time.

effect_bonus_value_building_set_junctions_tables

Pooled Resources:

Note: to learn more about pooled resources, there is a dedicated guide to them.

In this example, you can see how two effects are set up to affect the dark elf slave pooled resource, one effect modifies the base amount and another is a percentage multiplier.

effect_bonus_value_pooled_resource_factor_junctions_tables

ARCHIVE:

Below is the old guide. I didn't want to delete it.

Anatomy of an Effect

At the heart of all effects is the effects_table db file. This table defines a few important things - the key of the effect, to link it up to other data objects and the localised text. It will also define some UI details here, typical - such as icon, priority (which determines the order effects show up, or whether it is hidden from view with 0), and the category, which determines where an effect shows up on a Character Details panel for example. Also mind the boolean in here, positive_is_good. This means that, if your value is a positive integer and this bool is set to true, the text will show up as green; if your value is negative and this bool is set to false, the text will show up as red.

An effect defined in just this table has no, well, effect - it has to be linked to another game object called bonus_values. Bonus values are the game object that actually do a thing. Effects just enable those bonus values to be applied elsewhere. Bonus values can do a bunch, from increasing recruited lords' ranks, to adding charge bonus to a unit set, and far beyond, varying greatly based on the individual game. It's important to note here: no, you can't make new bonus_values. They are defined in the underlying game engine, and have code attached to them that actually make stuff happen. You can only use existing bonus_values, ever.

The bonus_values are defined in data in dummy tables called campaign_bonus_value_ids_BONUS VALUE TYPE. For instance, the basic bonus_values are found in the tables campaign_bonus_value_ids_basic. Do note that you won't find these tables in RPFM; they're dummy tables, meaning they're not actually used to build data in the game and can't be edited.

The links between an effect is defined in tables called effect_bonus_value_BONUS VALUE TYPE. These tables are typically either two or three columns - you link an effect key to the bonus_value dummy key, and a potential third piece of data needed for the effect. For instance, effect_bonus_value_ids_unit_sets has three columns - effect, bonus_value_id which defines WHAT'S being edited (upkeep, charge bonus, etc), and unit_set which defines which units get this effect.

However, not every effect needs a bonus value - it's fairly common to make a "dummy" effect, which is just UI and text, but doesn't actually have any bonus_values attached to it. This could be desired to make some clear UX about a functionality that is done through script or some other data object.

Applying an Effect

From here, the effect works and is a beautiful machination, but it doesn't do anything since it isn't applied anywhere. In order to take hold, it needs to be attached into an effect_bundle.

Effect bundles are another fairly common data object, and their name is pretty much their definition - they're a nice lil' package of effects. There are two types of effect_bundles - explicit, and implicit. Explicit effect bundles are defined in the table effect_bundles, and then those effect bundles can be applied through a variety of means. Implicit effect bundles are created when another effect-bundling table is used - for instance, building_effects_junction. This table defines a list of effects that attach to a building, which are then bundled up in the game, thus implicitly.

Looking first at explicit effect_bundles - you would first define the effect_bundle key in effect_bundles, which again is primarily UI information. However - there's an important bit of data in this table too, that we'll have to return to later. The bundle_target column is very important, as it plays a big role in a future bit that we'll cover soon. It's mostly common sense here - if the effect bundle is going to be applied to a character via an ancillary, use the character bundle_target. If it's applied to an army through a stance, use the force bundle_target. This is the game object that has the effect_bundle, and the effects will be applied from that object.

From there, the next jump for making an explicit effect_bundle is the table effect_bundles_to_effects_junctions. You'll never guess what it does!

First off the bat, we have the effect_bundle_key - self-explanatory. Same with effect_key and, I assume, value. If you're editing a numerical bonus_value - like, editing a stat - it'll just be whatever number you want to add to the stat. If you're applying some stranger effect - like attrition immunity - that doesn't use actually numbers, you'll either use 0 for "deactivate", or 1 for "activate".

The effect_scope is where it gets really important. Effect_scopes are defined in data, and new ones can be made - and, sometimes, are needed. Effect_scopes are composed of source and a target. The source of an effect_scope will have to be the bundle_target defined in the effect_bundle earlier - you're applying an effect from the bundle_target's effect_bundle to something else. For example, if you wanted to add charge bonus on a character through an ancillary, you would just use the character_to_character_own effect_scope - since the character has the effect_bundle and will receive the effect.

One more very important note - not every effect works with every effect target. You can't assign a charge_bonus to a faction, for instance. That just doesn't make sense. 90% of the time, you can find which game objects are valid targets in the bonus value definitions (campaign_bonus_value_ids_xxxxx), in the notes column. They'll say something like "used at character bonuses", which means it's only applicable to a character. On the 10% that aren't noted in that table, you can typically find examples in vanilla for what you want to do, and you can copy what they do.

Implicit effect_bundles are much the same - just without defining the effect_bundle on its own, and its bundle_target. This means the effect_scope column doesn't have a predefined effect source, so you will need to be slightly more aware of what you're using. Again, check vanilla examples as much as you can.

Aside from using the aforementioned data structures, you can script some effect bundles as well. You can use a Lua script to apply (or remove) an explicit effect_bundle from a bundle_target - though mind it won't work for implicit effect_bundles.

For Warhammer 2 - you can read up here. The same general commands should exist in all other games, with the biggest difference lying in Three Kingdoms.

Likewise, Warhammer 2 got a GREAT new ability to completely change explicit effect_bundles dynamically while the game is going on. Instead of defining a dozen different effect bundles with 12 different values for the same effect, you can make one effect_bundle, and change its effect value dynamically. Read up more on it here.