Event modding

From Europa Universalis 4 Wiki
Jump to: navigation, search

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
    • Alternatively, it can be marked as "triggered only", meaning it is only triggered when another script specifically triggers it.
  • 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 him 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 him.

Country or province event?[edit]

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.

The event id[edit]

This must be a unique non-negative integer, not replicated in any other event file of either your own making, another mod, or vanilla. A list of ids is available at Event ids.

On the importance of namespaces[edit]

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, so long as you specify the namespace at the top of each one.

The title and description[edit]

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:0 "Hello, world!"
my_mod_event_1_desc:0 "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:0 "Hello, world!"
my_mod_event_1_desc_1.1:0 "Let's go explore! This is France."
my_mod_event_1_desc_1.2:0 "Let's go explore! This is not France."

The picture[edit]

The picture you choose will be the one displayed in events. To find the names of event pictures, go to gfx\event_pictures. You need only put the short-form filename: you do not need the directory or the filetype. Example:

picture = BUDDHA_eventPicture

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 (folder: 'gfx\event_pictures') and the .gfx file (folder:'interface') that references that picture. For an example of a .gfx file, look up interface\eventpictures.gfx.

Fire only once?[edit]

You can specify that the event should fire once and only once by putting

fire_only_once = yes

Hidden?[edit]

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]

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
		}
	}
}

The trigger can also include personalities for the ruler, consort and heir. For example:

trigger = {
	ruler_has_personality = kind_hearted_personality
}

Mean time to happen[edit]

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 every 3 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.

Is triggered only[edit]

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]

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.3we 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]

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.

Options[edit]

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

Trigger[edit]

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]

A highlight can be added to an option in an event, such as:

option = {
	highlight = yes
	trigger = {
		ruler_has_personality = well_connected_personality
	}
}

If[edit]

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
	}
	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]

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+.

Event targets[edit]

The direct target of an event, which means the country/province for which the event is triggered - which is ROOT in the event -, can be saved as global event target by using the following effect in either an option or within the immediate effects section.

save_global_event_target_as = my_event_1_event_target

The name as which ROOT is saved can be chosen freely, but needs to be unique. Saving a country or province as a global 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:

option = {
  name = "my_mod_name.EVTOPT1"
  save_global_event_target_as = my_event_target
}

In the localisation of another event:

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:

option = {
   name = "my_mod_name.EVTOPT2"
   save_global_event_target_as = my_first_event_target
    
   event_target:my_first_event_target = { add_stability = 1 }
}


Debugging events[edit]

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> OPTIONAL] [<Option id> OPTIONAL] like so:

event 12345

If the event uses a namespace, use the namespace:

event my_mod_event_namespace.1
It is important to note that since the trigger conditions are not always met, strange results may occur. For example, the wrong province is used in this event even though there clearly is at least one province that produces wine.

You can also use the command testevent [<Event ID>] [<Character 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.

Modding
Documentation EffectsTriggersModifiersScopesVariablesLocalisationCustomizable localization
Scripting AdvisorsAgesBookmarksBuildingsCasus belliColonial regionsCountriesCultureDecisionsDefinesDiplomatic actionsDisastersEstatesEventsFactionsGovernmentGreat projectsHistoryIdea groupsInstitutionsMissionsModifiersNation designerPoliciesReligionRebel typesSubject typesTechnologyTrade companiesTrade goodsUnits
Map MapRandom New WorldTrade nodes
Graphics 3D ModelsInterfaceGraphical AssetsFontsParticlesShadersUnit models
Audio MusicSound
Other Console commandsChecksumJoroDox mod making toolMod structureTroubleshootingThe Validator
Guides Adding a province