Event modding
An event must contain the following:
- A unique id
- A title
- A description text
- A picture
- A trigger: things that must be true for the event to fire
- A "mean time to happen", that is, how often the event should fire given that the trigger conditions are met, and modifiers thereto
- It can be marked as "triggered only", meaning it is only triggered when another script specifically triggers it. This makes mean_time_to_happen useless, unless the event is triggered in an on_action's random events list.
- One or more options for the player or AI to pick, with associated effects.
Optionally you may include an effect that happens immediately upon the event firing rather than waiting for the player to choose an option (for example, to stop them from moving troops to a province before choosing the option that causes a revolt there). This may be visible to the player or hidden from them.
Country or province event?[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
An event can either be about a province or about a country. You specify this as follows:
country_event = { }
or
province_event = { }
This only specifies the root scope of the event - country events can have province scale effects and vice versa.
A notification that the event has happened can be displayed to everyone by using the major = yes argument. Major event can also have major_trigger block, only displaying the notification to countries validating the trigger.
major_trigger = { prestige = 50 }
This would only display the notification to countries that have more than 50 prestige.
country_event = { id = test.1 title = test.1.t desc = test.1.d picture = TRADEGOODS_eventPicture major = yes major_trigger = { prestige = 50 } option = { name = test.1.a add_prestige = 50 } }
The event id[edit | edit source]
This must be a unique non-negative integer, not replicated in any other event file of either your own making, another mod, or vanilla.
On the importance of namespaces[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
To prevent compatibility problems with potential future mods or Paradox updates, and to ensure readability and ease of maintenance, it is prudent to use namespaces. At the beginning of an event file, define what namespace to use like so:
namespace = my_mod_event_namespace
Then when defining your event ID, use your namespace, followed by a dot, followed by a number unique within that namespace:
country_event = { id = my_mod_event_namespace.1 #everything else goes after ... }
This allows you to keep your event IDs manageable and avoids the need to remember long event ID numbers when debugging, along with the risk of Paradox or another modder adding an event with the same ID. You can use the same namespace across multiple files, as long as it is declared somewhere in any events file. Namespaces can have IDs of 0 to 9999, same for not having any namespace.
The title and description[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
These refer to the localisation entries for the title and description text. Example:
title = "my_mod_event_1_title" desc = "my_mod_event_1_desc"
Then in the localisation file:
my_mod_event_1_title: "Hello, world!" my_mod_event_1_desc: "Let's go explore!"
Descriptions can have triggers to be only displayed in specific situations. But make sure that always one description is visible. Example:
title = "my_mod_event_1_title" desc = { trigger = { tag = FRA } desc = "my_mod_event_1_desc_1.1" } desc = { trigger = { NOT = { tag = FRA } } desc = "my_mod_event_1_desc_1.2" }
Then in the localisation file:
my_mod_event_1_title: "Hello, world!" my_mod_event_1_desc_1.1: "Let's go explore! This is France." my_mod_event_1_desc_1.2: "Let's go explore! This is not France."
The picture[edit | edit source]
- See also: List of event pictures
The picture you choose will be the one displayed in events. The names of event pictures can be found in the list of event pictures and in the name =
lines of Europa Universalis IV/interface/eventpictures.gfx
and interface/eventpictures_*.gfx
files in the zip files of the DLCs which contain them. Just using the filename does not work unless there is a .gfx file with the file name in the name =
line.
Some event pictures have multiple entries in the .gfx files with different names in which case any of the names can be used. If the same name exists multiple times in the base game and DLCs with different pictures, the picture from the last .gfx file(when sorted by the ASCII representation of their filenames) will be used. For example b_eventpictures.gfx would override a_eventpictures.gfx, but Z_eventpictures.gfx would override neither of them, because uppercase letters are sorted before lowercase letters.
Some names are prefixed with a culture, culture group, religion or graphical culture. Events which use the name without the prefix, will get different pictures depending on the country which gets the event. For example:
picture = ANGRY_MOB_eventPicture
will use the following pictures:
Pictures can have triggers as well to be shown in specific situations. Make sure always one picture is visible. Example:
picture = { trigger = { is_part_of_hre = yes } picture = HRE_eventPicture } picture = { trigger = { is_part_of_hre = no } picture = GOOD_WITH_MONARCH_eventPicture }
NOTE: If you want to add a custom picture, you will need to add both the picture (usually in 'gfx\event_pictures') and a .gfx file (in 'interface') that references that picture. For an example of a .gfx file, look up interface\eventpictures.gfx.
Fire only once?[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
You can specify that the event should fire once and only once by putting
fire_only_once = yes
To clarify, this setting means that after this event fires, regardless of for whom it fires, it will no longer fire again for any country - even if they would otherwise meet the requirements to fire this event, or have had the event called directly in code.
Hidden?[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
You can specify that the event should only be triggered in the background and not popping up for the player. You can do this by putting
hidden = yes
Make sure to have at least one option (should include an ai_chance as well), otherwise it won't work.
The trigger[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
The trigger is the set of conditions which must all be true for the event to be eligible to fire. The root of the trigger = { } clause is considered to be an AND operator, so something like this is redundant:
trigger = { AND = { #stuff #more stuff #... #even more stuff } }
You can alternate between scopes in the trigger to an arbitrary depth. In this province event, the scope is originally a province, but then it is switched to the owner, and then any other country, in order to test whether certain conditions are met: the province must produce slaves, the owner cannot have taken the "Abolish Slavery" decision, and there must exist another country with which the province's owner has improved relations, and has not Abolished Slavery either.
trigger = { trade_goods = slaves NOT = { owner = { has_country_modifier = the_abolish_slavery_act } } any_country = { has_opinion_modifier = { who = ROOT modifier = improved_relation } NOT = { has_country_modifier = the_abolish_slavery_act } } }
Mean time to happen[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
This specifies how frequently the event should fire, given that the trigger conditions are met. A MTTH of 3 months means that on average, the event should fire about every 6-7 months (though of course, it may fire the next day, or never at all, such is the nature of probability). The "base" MTTH can be defined in terms of days or months. Additionally, you can make it more or less likely to fire according to certain conditions. For example:
mean_time_to_happen = { months = 400 modifier = { factor = 0.8 NOT = { stability = 0 } } }
The base MTTH is multiplied by the 0.8 factor to give 320 months, if the country does not have at least 0 stability. Many modifiers can be defined and if several of them are true, their effects stack.
Province events can have is_mtth_scaled_to_size = 1
, this will cause MTTH to be scaled up as the number of provinces their owner has increases. With two provinces, MTTH is doubled. With four provinces, MTTH is quadrupled.
This means that the province event is just as likely to happen for a large country as for a small one, preventing the event spam that province events tend to cause in huge countries.
For 'is_triggered_only = yes' events that are triggered in the 'random_events = {}' section of an on_action, you can set a mean_time_to_happen of 'days = 1' and then add modifiers to this value. The modifiers will be applied to the random chance given to that event in 'random_events = {}'. This means that unlike regular mean time to happen, a modifier of 0.8 will actually make the event less likely to happen, as the random chance is reduced.
Is triggered only[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
Many events lack an MTTH and instead use the condition is_triggered_only = yes
. With this condition in use, the event will only occur if it is triggered from another source, usually another event (that generally has an MTTH) or the on_actions (such as the event pulses defined in /Europa Universalis IV/common/on_actions/00_on_actions.txt). An interesting and useful note to make is that an event that contains this condition also can contain triggers. How does this work? An example is the event "The End of Hundred Years War" which is triggered from 00_on_actions.txt
:
on_peace_recipient = { events = { flavor_eng.9104 # End of Hundred Years' War flavor_fra.9104 # End of Hundred Years' War } }
Both events can be found in the events folder, here is the flavor_eng.9104 event:
# The End of the Hundred Years' War country_event = { id = flavor_eng.9104 title = "flavor_eng.EVTNAME9104" desc = "flavor_eng.EVTDESC9104" picture = DIPLOMACY_eventPicture is_triggered_only = yes trigger = { NOT = { has_country_flag = ENG_had_event_9104 } NOT = { is_year = 1500 } OR = { AND = { tag = ENG NOT = { exists = GBR } } tag = GBR } primary_culture = English NOT = { french_region = { owned_by = ROOT } } FRA = { exists = yes NOT = { war_with = ENG } NOT = { war_with = GBR } } } }
When a country accepts a peace agreement, on_peace_recipient
sends that country the events flavor_eng.9104
and flavor_fra.9104
. Therefore, the events contain the condition is_triggered_only = yes
. However, for the event flavor_eng.9104
to actually occur, a certain number of other conditions are required: the country can't have the country flag ENG_had_event_9104
, the year must be after 1500, the country's tag must either GBR or ENG, et cetera. If these conditions aren't met, the event doesn't trigger even though it was sent from on_peace_recipient
.
Using is_triggered_only together with triggers[edit | edit source]
There are several benefits with using is_triggered_only
together with triggers that aren't found in the vanilla code:
option = { name = "flavor_hsa.EVTOPTA3" hidden_effect = { country_event = { id = awesome_event.2 days = 300 } country_event = { id = awesome_event.3 days = 350 } } }
In the option above (in what we can call awesome_event.1
) two events will occur: awesome_event.2
which will occur after exactly 300 days and awesome_event.3
in exactly 350 days. In awesome_event.2
we enter the following code:
is_triggered_only = yes trigger = { prestige = 25 } immediate = { set_country_flag = had_awesome_event.2 }
What this means is that awesome_event.2
will occur if the country's prestige is higher than 25. And if it is, one of the first effects is that it will add the country flag had_awesome_event.2
to the country that had the event. In awesome_event.3
we enter the following:
is_triggered_only = yes trigger = { NOT = { has_country_flag = had_awesome_event.2 } }
This means that awesome_event.3
will only occur if the country doesn't have the country_flag had_awesome_event.2
. In summary, the first event (awesome_event.1
) sends two events (awesome_event.2
and awesome_event.3
). If the country's prestige is higher than 25, awesome_event.2
will occur after 300 days - note that it can be below 25 up until 299th day and still occur. If awesome_event.2
does occur then awesome_event.3
won't because awesome_event.2
added a country_flag that prevented that event from occurring. However, if the country doesn't have 25 prestige or higher on the 300th day nothing will happen - but on the 350th day awesome_event.3
will occur because the country doesn't have the country flag had_awesome_event.2
.
An alternative to this is to set an event 3 flag when event 1 fires, clear the event 3 flag if event 2 fires, and clear the flag in event 3 so that event 3 does not fire repeatedly when event 2 is not triggered. The advantage to doing it this way is that the game engine does not have to maintain the flag for the duration of the game.
Immediate effects[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
You may optionally want something to happen immediately on the event firing, rather than waiting for the player's action. This can be useful to prevent gaming the system as mentioned above, or to make something happen regardless of which option is picked. By default, the effects are listed underneath the description text of the event. You can make this hidden if you want.
Example of an hidden immediate effect:
immediate = { hidden_effect = { every_owned_province = { limit = { is_overseas = yes culture_group = iberian region = chile_region } add_core = CHL } release = CHL CHL = { set_country_flag = recent_independence_chl } } }
This gives Chile a core on every overseas province with the Iberian culture group in the Chile region, then releases Chile and gives them a flag indicating they have been recently released.
While events cannot be opened when they are already open (e.g. by triggering itself with no delay), they will still execute their immediate effects. Also, immediate effects will indeed happen immediately when an event is triggered, this can be in the middle of the execution of other code if that other code calls the event without delay.
After effects[edit | edit source]
You may optionally want something to happen after an event option has been chosen, without needing to add it to every option. This can be useful to clean up variables and flags used inside the event. By default, the effects are listed underneath the description text of the event. You can make this hidden if you want.
after = { set_variable = { which = my_event_test value = 0 } clr_country_flag = option_1_disable }
Options[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
You must give the player or AI at least one option to pick to exit the event. The effects of the option are listed when the player mouses over it, with the exception of setting country flags. Each option needs to point to its localisation for the text. An example option would be as follows:
option = { name = "CHILE_WAR" #this is the pointer to the localisation set_country_flag = chilean_nationalism #setting and removing country flags aren't shown on mouseover CHL = { declare_war_with_cb = { who = ROOT casus_belli = cb_independence_war } } clr_country_flag = colonial_annexation_chl }
The elements of an option are:
- name
- trigger (optional)
- if (optional)
- ai_chance (optional)
- effects
- highlight (optional)
Trigger[edit | edit source]
Triggers determine whether an option is available. Care must be taken to ensure that at least one option is always available. This is an example of options where only one (but always one) option is available:
option = { name = "EVTOPTA799" trigger = { prestige = 90 } add_dip_power = 20 } option = { name = "EVTOPTB799" trigger = { NOT = { prestige = 90 } } add_prestige = 20 }
In the above example option A will only be available if prestige is 90 plus and option B will only be available if prestige is less than 90.
Highlight[edit | edit source]
A highlight can be added to an option in an event, such as:
option = { highlight = yes trigger = { ruler_has_personality = well_connected_personality } }
Goto[edit | edit source]
![]() |
Please help improve this article or section by expanding it with: what parameters can be used for highlighting provinces. |
If you want any one of the event options to highlight and refocus the camera to any province, use goto:
option = { goto = 183 # Paris }
If a province has been saved as an event target, you can use the event target string instead.
If[edit | edit source]
An option can have multiple effects that depend on what conditions are true. Conditions are added in the limit brackets and the effect after:
option = { name = awesome_event.22.a if = { limit = { has_heir = yes } add_prestige = 10 } if = { limit = { has_heir = no } add_prestige = -10 } add_treasury = 10 }
In the example above, selection the option will grant 10 prestige if the country has an heir. If the country doesn't have an heir, the event will instead make the country lose 10 prestige. In either case, selecting the option will always add 10 gold to the treasury.
AI chance[edit | edit source]
![]() |
Please help improve this article or section by expanding it with: what is the default ai chance, when not all options have it specified. |
ai_chance determines the chance that the AI will chose an option. The ai_chance figures are factors so, for example, if the first option has an ai_chance figure of 3 and the second option has an ai_chance figure of 1 then the AI is three times more likely to chose the first option than the second. By convention the factors are specified out of 100 so three to one would be 75 and 25. Here is an example:
option = { name = "EVTOPTA1073" # Increase centralization efforts. ai_chance = { factor = 75 } add_treasury = -500 } option = { name = "EVTOPTB1073" # Leave as it is. ai_chance = { factor = 25 } add_stability = -2 }
ai_chance statements can accept modifiers like this:
ai_chance = { factor = 40 modifier = { factor = 0 NOT = { prestige = 50 } } modifier = { factor = 0 NOT = { dip_power = 100 } } }
In the above example the AI will only chose this option if prestige is 50+ and diplomatic power is 100+.
There seems to be a slight bug in the ai_chance evaluation calculations - sometimes the first event option is picked regardless of chance, even if the chance is set to 0. If you want the first option to never happen under certain circumstances, add a trigger that disables it for AI countries.
Event targets[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
Any object that the current scope refers to can be saved as an event target by using the following effect within that scope in either an option or the immediate effects section.
save_event_target_as = my_event_1_event_target
Example:
option = { name = "my_mod_name.EVTOPT1" save_event_target_as = my_event_target }
This will save country or province getting the event (ROOT scope) as my_event_target.
Example:
option = { name = "my_mod_name.EVTOPT2" random_ally = { save_event_target_as = roots_ally } }
This will save a random ally of the country getting the event as roots_ally.
The name of the saved event target can be chosen freely, but needs to be unique. Saving a country or province as an event target makes it possible to get its name in the localisation of other events and to directly add effects to it. To get the name of event targets in other localisation you have to use [event_target_name.GetName]. Example:
my_mod_event.event_title: "[my_event_target.GetName] explored the world!"
To add effects or use event targets in triggers, you need to add event_target: in front of the actual event target's name. Example:
immediate = { save_event_target_as = my_first_event_target } option = { name = "my_mod_name.EVTOPT2" event_target:my_first_event_target = { add_stability = 1 } }
Event targets are saved within the event chain - that is to say, events that are directly triggered using the country_event
and province_event
effects will share the same event targets. Once an event chain ends, event targets are removed.
To keep an event target saved between event chains, use save_global_event_target_as
. Global event targets need to be unique globally, and will only be removed when they are overwritten by saving as it again, or by doing clear_global_event_target
.
Event targets can be used in effects to easily find highest/lowest values, by going through a scope and updating the event target whenever a higher value is found:
every_country = { limit = { diplomatic_reputation = event_target:highest_diprep } save_event_target_as = highest_diprep } event_target:highest_diprep = { #further effects }
Debugging events[edit | edit source]
![]() |
Please help with verifying or updating this section. It was last verified for version 1.30. |
You can manually fire events in the console even if the trigger conditions are not met. The console will output which (if any) of the conditions are met, which is useful when debugging. Simply type event [event id] [<Target Country Tag/Province ID> OPTIONAL] [<Option id> OPTIONAL]
like so:
event 12345
If the event uses a namespace, use the namespace:
event my_mod_event_namespace.1
You can also use the command testevent [<Event ID>] [<Target Country Tag/Province ID> OPTIONAL]
to show the event triggers and whether they are fulfilled.
It is often useful to comment out certain parts of a troublesome event when trying to figure out what the problem is. This allows you to narrow down the range of possible causes. To avoid the problem shown on the right, you might want to set the MttH to 1 day so that it fires immediately.
Documentation | Effects • Triggers • Modifiers • Scopes • Variables • Localisation • Customizable localization • Run files |
Scripting | Scripted function • Advisors • Ages • Bookmarks • Buildings • Casus belli • Colonial regions • Countries • Culture • Decisions • Defines • Diplomatic actions • Disasters • Empire of China • Estates • Events • Factions • Government • Great projects • History • Holy Roman Empire • Idea groups • Institutions • Mercenaries • Missions • Modifiers • Nation designer • On Actions • Parliament • Peace treaties • Policies • Rebel types • Religion • Subject types • Technology • Trade companies • Trade goods • Units |
Map | Map • Nation designer • Random New World • Trade nodes |
Graphics | 3D Models • Interface • Graphical Assets • Fonts • Particles • Shaders • Unit models |
Audio | Music • Sound |
Other | Console commands • Checksum • JoroDox mod making tool • Mod structure • Troubleshooting • The Validator • Run files |
Guides | Adding a province • Save-game editing • Scripting Tutorial |