• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
Index

Snow Crystal

Design Lead - Crusader Kings 3
Paradox Staff
63 Badges
Jan 22, 2018
1.377
5.823
  • Crusader Kings II
  • Hearts of Iron IV: Death or Dishonor
  • Hearts of Iron IV: Expansion Pass
  • Crusader Kings II: Holy Fury
  • Imperator: Rome
  • Imperator: Rome - Magna Graecia
  • Stellaris
  • Crusader Kings III: Royal Edition
  • 2Like
Reactions:
Intro
Intro

Hello there!

In this guide we are going to showcase how to make a simple event, with no follow-ups or anything. It will be expected that whoever reads this has already taken a look at our basic Scripting guide, so they know the differences between Scopes, Triggers, Effects, etc. In other words, we are not going to explain a lot of the basic concepts.

For this event we are going to make a small Hellenic Religion Flavor event where a city has been afflicted by a local plague. In this case I will add an entry at the bottom of the ‘Imperator\game\events\religion_flavor\rel_flavor_hellenic.txt’ file, to easily categorize the event where it makes sense.

To make a new event file, simply add a .txt file inside the events folder, save it with the encoding UTF-8 with BOM, and add a ‘namespace = <name_of_your_events>’ at the top. The namespace of rel_flavor_hellenic is… Well… rel_flavor_hellenic, so every event is written with that as its name (with our new event that you can see in the picture below, we have rel_flavor_hellenic.16 for example).

The number you assign to events is not important, besides making sure no two events have the same number.

So to start off, let us take a look at the basic syntax of an event file in our Scripting language.

upload_2019-11-15_10-16-44.png

Code:
# Asklepian Plague
rel_flavor.16 = {
    type = country_event # EVENT TYPE - Can be Country/Province/Character, decides ROOT Scope
    title = rel_flavor.16.t # LOCALIZATION KEY - Title of Event
    desc = rel_flavor.16.desc # LOCALIZATION KEY - Description of Event
    picture = aqueducts # EVENT PICTURE
    hidden = no # SPECIAL FIELD - Can hide the event from a player's view
    fire_only_once = yes # SPECIAL FIELD - Will limit the event to once per tag
    goto_location = capital_scope # SPECIAL FIELD - Will let the player jump to the province in question
 
    left_portrait = current_ruler # LEFT PORTRAIT - Shown at the left hand side of event
    right_portrait = current_ruler # RIGHT PORTRAIT - Shown at the right hand side of event

    weight_multiplier = { # MODIFIER - Will modify the chances for the event to fire

    }

    trigger = { # TRIGGER FIELD - Checks if the event will fire at all
 
    }

    immediate = { # EFFECT FIELD - Fires after trigger check, but before everything else

    }

    option = { # EFFECT FIELD - FIRST OPTION - Options the player can choose between when receiving the event
        name = rel_flavor.16.a
    }
    option = { # EFFECT FIELD - SECOND OPTION - Options the player can choose between when receiving the event
        name = rel_flavor.16.b
    }
    option = { # EFFECT FIELD - THIRD OPTION - Options the player can choose between when receiving the event
        name = rel_flavor.16.c
        trigger = { # TRIGGER FIELD - Checks if this specific option will be shown

        }
        exclusive = yes # SPECIAL FIELD - Will be the only option available, if it is available
        highlight = yes # SPECIAL FIELD - Will highlight the option
    }

    after = { # EFFECT FIELD - Happens after the player has clicked an option

    }
}
  • type - Selects which scope the event will be in (i.e. country, province, or character)
  • title - Defines a localization key for the event’s title
  • desc - Defines a localization key for the event’s description
  • picture - Selects which picture will be shown (see the text files ‘Imperator\game\common\event_pictures’ folder for all the event pictures you can use)
  • hidden - You can hide the event from a player’s view
  • fire_only_once - Will limit the event to firing once per tag
  • goto_location - Let the player be able to jump to a location when the event triggers
  • left_portrait - Displays the portrait of a character Scope on the left hand side of the event, max 3 can be shown at once (just add a second entry if you want a second left_portrait, and a third entry for a third portrait)
  • right_portrait - Shows the portrait of a character Scope on the right hand side of the event, max 3 can be shown at once (similarly to left_portrait, you can add several entries to get several characters shown)
  • weight_multiplier - Modify the chances for the event to fire, if it is a random event
  • trigger - Trigger Field - Sets the conditions in which the event can fire
  • immediate - Effect Field - Sets effects to be run immediately after the event is triggered, but before the event pops up (e.g. saving a Scope here will let you refer to it in the title, description, portraits, etc.)
  • option - Effect Field - Adds an option the player can choose, with effects running on selection
  • exclusive - Inside an Option - Will limit this to be the only option available in the event
  • highlight - Inside an Option - Highlight this option
  • after - Effect Field - Sets effects to be run after an option has been selected, i.e. the last things to happen in the event
 
  • 1
  • 1Like
Reactions:
Triggers & Immediate
Triggers

We will start with setting up the event’s triggers. Triggers are mainly used for two things: setting the basic conditions under which an event can fire, and making sure the right actors we need for an event exist. E.g. if an event is about a corrupt general, you want to make sure it only fires for a country that has a general with some corruption or the corrupt trait.

upload_2019-11-15_10-18-46.png

Code:
trigger = { # TRIGGER FIELD - Checks if the event will fire at all
    religion = roman_pantheon # TRIGGER - Checks if the country has the Hellenic religion
    any_owned_province = { # TRIGGER SCRIPT LIST - Checks if we any owned province
        total_population > 20 # TRIGGER - With more than 20 pops
    }
}

So we will start off with a simple check that our country is the right religion, as this is a religion flavor event related to Asklepion (the Greek deity of medicine). Additionally we will see if we have any owned provinces with more than 20 pops (as an early test number), as plagues usually occur when a lot of people live in a confined area.

It is common when writing an event to return to the triggers later to add more conditions, as new ideas and potential issues are revealed through creating the event, so we will keep it like this for now and move on to the Immediate.

Immediate

upload_2019-11-15_10-19-5.png

Code:
trigger = { # TRIGGER FIELD - Checks if the event will fire at all
    religion = roman_pantheon # TRIGGER - Checks if the country has the Hellenic religion
    any_owned_province = { # TRIGGER SCRIPT LIST - Checks if we any owned province
        total_population > 20 # TRIGGER - With more than 20 pops
    }
}

immediate = { # EFFECT FIELD - Fires after trigger check, but before everything else
    random_owned_province = { # EFFECT - Find a random owned province
        limit = { # LIMIT - Set Trigger Field
            has_city_status = yes # TRIGGER - With city status
            total_population > 20 # TRIGGER - And more than 20 pops
        } # End of Trigger Field
        save_scope_as = plague_city_scope # EFFECT - Save Scope for later use
    }
}

We have now added an effect to the Immediate, finding the same owned province we checked existed in the trigger, and saving it as a scope so we can refer to it in the options (and probably also in the loc when we get to that part). We used the same triggers we used for the any_owned_province in the Trigger section, but we have added an additional ‘city status’ check in both of them.

It is very important to make sure the conditions of an event’s Trigger are exactly the same as those in the Immediate, otherwise you might not be able to find the target, and the event will probably not work as intended.

Now we have created an event which will only fire for a Hellenic religion country with a city province with at least 21 pops.
 
  • 1Like
Reactions:
Options
Options

We are going to set up three options for the player to choose between. Two normal options, and one that only appears if the country has an Asklepian Wiseman or a province with an Asklepion.

For the first option, the player will be able to ignore the city’s pleas for help, and leave them to suffer through the plague. We will want to reduce the ruler’s popularity for ignoring their people, add a negative province modifier, and kill some of the city’s pops.

We will make the province modifier first, so we can refer to it in the Script. To create the modifier, we will switch over to the file ‘game\common\modifiers\00_from_events_province.txt’. You could create it in any file in the modifiers folder, but we try to keep things somewhat organized.

With modifiers we want a descriptive name (so we don’t accidentally create several modifiers with the same name, e.g ‘disloyal_general_modifier’ might be a bad name, as it is something someone might use several times). With the modifier we want something that makes sense and is easy to understand.

upload_2019-11-15_10-21-1.png

Code:
rel_flavor_hellenic_asklepian_plague_modifier = { # MODIFIER NAME
    local_unrest = 3 # MODIFIER - Increases local unrest in the area
    local_population_growth = -0.1 # MODIFIER - Decreases local growth
}

This is the modifier we will make for the event. It increases the local unrest in the area, as people are not happy about being stuck with a plague with no help from the local government, and decreases local pop growth, as the population won’t be expanding while the city is ravaged by plague.

For small things that need localization, like modifiers, opinion modifiers, etc., I like writing them before I move on to the next task, as I usually forget otherwise. We’ll also do it here to make things simple.

For modifier localization, we will open the file ‘Imperator\game\localization\english\modifiers_l_english.yml’, scroll all the way to the bottom, and add a new entry for our modifier.

upload_2019-11-15_10-21-17.png

Code:
rel_flavor_hellenic_asklepian_plague_modifier:0 "Asklepian Plague"
desc_rel_flavor_hellenic_asklepian_plague_modifier:0 "This territory is currently suffering from a devastating plague."

For the title of the localization string, we simply take the modifier’s name and paste it on a new line. For the description that shows up when you hover over the modifier, we write ‘desc_<modifier_name>’.

The colon and number (in this case 0) at the end of localization strings are what we call version numbers at Paradox. Whenever we update a localization string, we update the version number so our translators will know a string has changed and may need to be retranslated. You will always need a colon for the localization text to work, but you can choose to not add a version number if you so wish.

upload_2019-11-15_10-21-34.png

Code:
option = { # EFFECT FIELD - FIRST OPTION - Options the player can choose between when receiving the event
    name = rel_flavor_hellenic.16.a # LOCALIZATION KEY - Option A text
    current_ruler = { # EVENT TARGET - Find current ruler of your country
        add_popularity = subtract_popularity_medium # EFFECT - Reduce popularity of ruler
    }
    scope:plague_city_scope = { # SAVED SCOPE - Find affected city
        add_province_modifier = { # EFFECT - Add a province modifier to the saved scope
            name = rel_flavor_hellenic_asklepian_plague_modifier # SPECIAL FIELD - Find the modifier to add
            duration = 3650 # SPECIAL FIELD - Duration of the modifier, counted in days (so 10 years for this one)
        }
        while = { # WHILE Loop
            count = 3 # Special Field - Will run 3 times
            limit = { # TRIGGER FIELD - The While loop will end if the following requirements are not true
                total_population > 1 # TRIGGER - Population higher than 1
            } # END OF TRIGGER FIELD
            random_pops_in_province = { # EFFECT - Find a random pops in the saved province scope
                kill_pop = yes # EFFECT - Kill the pop we have found
            }
        }
    }
}

So, for the first option we want to let the player simply ignore the pleas of the struggling city. We’ll start with the effects on the ruler by finding the right Scope and then reducing their popularity.

We use a reference for popularity (‘subtract_popularity_medium’) instead of an actual number here, but could just as well have used ‘-10’. We use these references so we can quickly rebalance a lot of events at the same time, if necessary.

Moving on, we want some pops in the province to die and to add the province modifier. We start by using the saved scope we set earlier in Immediate to find the city in question, and add the province modifier. We specify which modifier we want to add by name, and add a duration to ensure the effect is not infinite.

We’ll make it 10 years long. Though plagues are unlikely to last ten years, this simulates the effects of the plague as well as the plague itself, and from a gameplay perspective we need our modifiers to be somewhat impactful, otherwise they are fairly pointless.

No we’ll kill some of the pops in the province. This is not meant to be a large overarching catastrophe like a volcanic eruption or an earthquake, but rather a small local issue that affects one city.

We already know that the city in question has at least 21 pops, as we checked for that earlier on (thought it is important to keep in mind that players have 2 months to make an event choice in multiplayer, so something else CAN happen to the city before the player picks an option).

We’ll use a simple ‘while’ loop with the script list effect ‘random_pops_in_province’ to find a random pop in the city, then kill that pop and repeat 3 times. We’ll also add a limit to make sure there is always more than 1 pop in the province, so if something else has happened, the city population won’t lose its entire population.

upload_2019-11-15_10-22-4.png


Keep in mind that when it comes to the tooltip of a ‘while’ loop it will only show the effect of the first loop when it comes to ‘random’ script list effects, just to give the player an example. E.g. the first pop might be a Peloponnesian Citizen, and an Athenian Freemen the second, but it would never clarify that they differed.

Moving on to the next option, we will give the player a choice of sending in whatever wisemen, soldiers and local healers they can muster to deal with the issue. It will cost them a little bit of gold, but be a popular move for your ruler.

upload_2019-11-15_10-22-19.png

Code:
option = { # EFFECT FIELD - SECOND OPTION - Options the player can choose between when receiving the event
    name = rel_flavor_hellenic.16.b # LOCALIZATION KEY - Option B text
    current_ruler = { # EVENT TARGET - Find current ruler of your country
        add_popularity = popularity_small # EFFECT - Increase popularity of your ruler
    }
    add_treasury = { # EFFECT - Add or remove gold from your treasury
        subtract = scope:plague_city_scope.total_population # INLINE MATH - Subtract gold equal to the population of the city
        multiply = 1.5 # INLINE MATH - Multiply that number by 1.5
        max = -20 # INLINE MATH - Inverted because it is a negative number, you must pay a minimum of 20 gold
        min = -100 # INLINE MATH - Inverted because it is a negative number, you never need to pay more than a max of 100 gold
    }
}

First, we’ll do the same thing as we did in the previous option, which is to find the ruler Scope and adjust their popularity.

For the second part, we get to take a look at some inline Script math, as ‘add_treasury’ is one of the effects which can use it. We start by setting up a value as a basis at the top with:
Code:
subtract = scope:plague_city_scope.total_population
In other words a negative number equal to the population of the affected city.

Then we take that number, and multiply it by 1.5, as the base pop number might be a tad low as a payment. ‘Max’ and ‘Min’ are limits set to the end number, limiting how high or low a number can go. As our number is a negative one, in this case the max and min will be somewhat inverted, as max will be the minimum number and min will be the maximum number.

For more info on math in our Script, you can take a look at the file ‘Imperator\game\common\script_values\_script_values.info’.

upload_2019-11-15_10-23-36.png


As Sparta have 50 pops in the city, we are multiplying by 1.5 multiplier, and the sum isn’t less than 20 or higher than 100, we get 75 as the cost for this option. A tad expensive for some popularity, but considering the nature of the event that seems fine.

Moving on to the third option, we will let the player solve this more easily if they have access to an Asklepian Wiseman or an Asklepion, opening a special option for them. Special options are usually highlighted to show the player that these are unique in some way, and include a tooltip explaining exactly why the player is given the option.

upload_2019-11-15_10-23-54.png

Code:
option = { # EFFECT FIELD - THIRD OPTION - Options the player can choose between when receiving the event
    name = rel_flavor_hellenic.16.c # LOCALIZATION KEY - Option C text
    trigger = { # TRIGGER FIELD - Checks if the option will show up or not
        OR = { # BOOLEAN OPERATOR - Either of the following statements must be true
            any_owned_province = { # TRIGGER SCRIPT LIST - Check if you have any owned province with
                has_province_modifier = asklepion # TRIGGER - The province modifier Asklepion
            }
            current_ruler = { # EVENT TARGET - Find current ruler
                has_character_modifier = character_improvement_asclepian_wiseman # TRIGGER - And check if they have the character modifier Asklepian Wiseman
            }
        }
    } # END OF TRIGGER FIELD
    highlight = yes # Special Field - Highlights option
    custom_tooltip = rel_flavor_hellenic.16.c.tt # LOCALIZATION KEY - Adds special loc when hovering the option
    current_ruler = { # EVENT TARGET - Find current ruler
        add_popularity = popularity_small # EFFECT - Add popularity to the character
    }
    if = { # If Clause
        limit = { # LIMIT - Trigger Field
            current_ruler = { # EVENT TARGET - Check if current ruler
                has_character_modifier = character_improvement_asclepian_wiseman # TRIGGER - Have the Asklepian Wiseman modifier
            }
        } # END OF TRIGGER FIELD
        current_ruler = { # EVENT TARGET - Find current ruler
            remove_character_modifier = character_improvement_asclepian_wiseman # EFFECT - Remove Asklepian Wiseman modifier
        }
    }
    else = { # Else Clause
        add_country_modifier = { # EFFECT - Add country modifier
            name = rel_flavor_hellenic_asklepian_blessing_modifier # SPECIAL FIELD - Find the modifier to add
            duration = 3650 # SPECIAL FIELD - Set duration
        }
    }
}

So this one is a tad longer than all the others, but not a lot more complicated. At the start we have a trigger that checks if the player will be able to see the option or not, by checking if their ruler has the Asklepian Wiseman modifier or any owned province has the Asklepion modifier.

Then we have a special field ‘highlight’ check, that simply decides if the option will be coloured or not, then a ‘custom_tooltip’ that tells the player why the option exists. Custom tooltips are fairly simple, you simply set a loc key, and then you add a string to a loc document with whatever text you want (similar to the loc we gave the modifier earlier in the guide).

upload_2019-11-15_10-24-36.png

Code:
rel_flavor_hellenic.16.c.tt:0 "This option is available because we have to access to an #Y Asklepion#! or an #Y Asklepian Wiseman#!."

As before, we have the loc key followed by a colon and optional version number, then the text that is to be shown to the player contained in quotation marks (these must be present for the text to appear).

The only thing that might be a tad confusing is the #Y and #!, which set a different colour on text contained within them. There must be a space after the first part (#Y in this case) and the actual text for it to work properly. There are also a number of different colors, e.g. #R for red, #G for green, #B for black, etc.

Moving on to the option, we have another popularity effect, something you’re no doubt an old hand at by now. We also have an if-else clause, which in this case checks if your ruler has the Asklepian Wiseman modifier, and removes it if they do.

If you don’t have the modifier, you will be given the country modifier Asklepian Blessing instead, which temporarily reduces your omen power by 10%, to try to show that you have used up some of the country’s priestly resources. We have already shown how to add a modifier, so we will not repeat that explanation.

upload_2019-11-15_10-24-59.png


Our ruler doesn’t have the Asklepian Wiseman modifier, but we do hold Epidauros (one of the provinces with an Asklepion) so we the ‘else’ part of the effect to fires in this case.

With all three options complete, we will move on to the meat of the localization.
 
Localization
Localization

upload_2019-11-15_10-26-20.png


Here is our event, fired with the console. We can see the highlighted option at the bottom, and all the options are working as they should, but the loc keys needs to be filled in.

upload_2019-11-15_10-26-37.png

Code:
rel_flavor_hellenic.16.t:0 "The Plague in [plague_city_scope.GetName]"
rel_flavor_hellenic.16.desc:0 "We have received news from [plague_city_scope.GetName] that the city has been ravaged by a disease; a significant proportion of the inhabitants have fallen ill. They have asked our leaders in general, but also entreated [ROOT.GetCountry.GetRulerTitle] [ROOT.GetCountry.GetRuler.GetName] in particular, to send them some form of aid. Our advisors, jealously taken aback by the direct appeals to [ROOT.GetCountry.GetRuler.GetPraenomen], have started mutterings, implying that [plague_city_scope.GetName] must have somehow offended the gods and deserve divine punishment."
rel_flavor_hellenic.16.a:0 "They must have brought this suffering upon themselves."
rel_flavor_hellenic.16.b:0 "We will call upon whoever we can to put an end to this plague."
rel_flavor_hellenic.16.c:0 "A messenger will be sent to the healers of [ROOT.GetCountry.Custom('get_medicine_god')]."
rel_flavor_hellenic.16.c.tt:0 "This option is available because we have to access to an #Y Asklepion#! or an #Y Asklepian Wiseman#!."

Here we can see all of the localization we are going to use in the text. As you’ll notice, we use a lot of loc promotes in the text, e.g [ROOT.GetCountry.GetRuler.GetName]. Similarly to how Scopes work, we sort of move between Scopes when we want to find the correct localization we want to refer to while working in these promotes. In this case we want to refer to the ruler of the country, so we find the ROOT Scope (country in this case), then the ruler of said country, and then ask for the name.

For saved Scopes, we simply use the saved Scope name (in this case ‘plague_city_scope’), and then you can effectively reference it for its name, or use it to find another Scope that you want the information of.

As for Custom, we are not going to go into it in this guide as it is its own rabbit hole, but it is related to custom localization one can make, and in this case we use it to get a specific name for Asklepios, e.g. it will fetch different names if you are Roman or Greek.

upload_2019-11-15_10-26-59.png
 
Final Touches
Final Touches

Now that we have made most of the event, we can look back at things like triggers and make the final touches, as it is easier to know what makes sense now than when we started out.

It probably isn’t logical if the city affected by the plague has an Asklepion, already has the province modifier you receive from the first event option, or that your country already has the country modifier from the third event option.

Similarly, an event affecting only one city should probably only happen for smaller nations, as it is fairly uninteresting when you grow large, but too punishing if you are a city-state. With all of these things in mind, we can add more conditions to our trigger.

upload_2019-11-15_10-29-8.png

Code:
trigger = { # TRIGGER FIELD - Checks if the event will fire at all
    NOT = { has_variable = "rel_flavor_hellenic_16_cooldown" } # VARIABLE - Cooldown check
    religion = roman_pantheon # TRIGGER - Checks if the country has the Hellenic religion
    NOT = { has_country_modifier = rel_flavor_hellenic_asklepian_blessing_modifier } # TRIGGER - Check for country modifier
    num_of_cities > 3 # TRIGGER - Check that you have more than 3 territories
    num_of_cities < 50 # TRIGGER - Check that you have less than 50 territories
    any_owned_province = { # TRIGGER SCRIPT LIST - Checks if we any owned province
        is_capital = no # TRIGGER - That isn't a capital
        NOR = { # BOOLEAN OPERATOR - Nor have
            has_province_modifier = asklepion # TRIGGER - the Asklepion province modifier
            has_province_modifier = rel_flavor_hellenic_asklepian_plague_modifier # TRIGGER - The Asklepian Plague modifier
        }
        has_city_status = yes # TRIGGER - That has city status (i.e city/metropolis)
        total_population > 20 # TRIGGER - With more than 20 pops
    }
}

immediate = { # EFFECT FIELD - Fires after trigger check, but before everything else
    set_variable = { # VARIABLE - Set up a variable that will work as a cooldown
        name = "rel_flavor_hellenic_16_cooldown" # Special Field - Variable name
        days = 3650 # Special Field - Variable duration (10 years)
    }
    random_owned_province = { # EFFECT - Find a random owned province
        limit = { # LIMIT - Set Trigger Field
            is_capital = no # TRIGGER - That isn't a capital
            NOR = { # BOOLEAN OPERATOR - Nor have
                has_province_modifier = asklepion # TRIGGER - the Asklepion province modifier
                has_province_modifier = rel_flavor_hellenic_asklepian_plague_modifier # TRIGGER - The Asklepian Plague modifier
            }
            has_city_status = yes # TRIGGER - With city status
            total_population > 20 # TRIGGER - And more than 20 pops
        } # End of Trigger Field
        save_scope_as = plague_city_scope # EFFECT - Save Scope for later use
    }
}

Now we have added all of these changes in the Trigger section, as well as updating our Immediate with the same conditions. In addition we have added a cooldown, so the event can NEVER happen more often than once every 10 years at most. We do so by adding a simple variable that lasts for 10 years in Immediate, and make a check that our country doesn’t have the variable in Trigger.

To make some more small changes, we’ll add a “goto_location” between picture and left_portrait at the top, so people can jump directly to the province in question if they so wish.

upload_2019-11-15_10-29-25.png

Code:
picture = religious_rite # EVENT PICTURE

goto_location = scope:plague_city_scope # SPECIAL FIELD - Find important province

left_portrait = current_ruler # LEFT PORTRAIT - Ruler shown at the left hand side in event

Next we will change our event picture, to something less aqueduct-like and something more religious. To find a fitting image, we simply open the file ‘Imperator\game\common\event_pictures\00_event_pictures.txt’ and take a quick look through the pictures available to us. I chose ‘religious_rite’, as it shows a fairly generic religious ceremony that you figure they might go through if they think a deity might have punished them.

And finally, we will rebalance option A slightly, reducing the popularity hit from 10 to 5, as it is a fairly punishing option right now. We’ll also change the 20 pops trigger to a 15 pops trigger, as 20 might have been a tad high.

upload_2019-11-15_10-29-42.png

upload_2019-11-15_10-29-47.png

Code:
# Asklepian Plague
rel_flavor_hellenic.16 = {
    type = country_event # EVENT TYPE - Can be Country/Province/Character, decides ROOT Scope
    title = rel_flavor_hellenic.16.t # LOCALIZATION KEY - Title of event
    desc = rel_flavor_hellenic.16.desc # LOCALIZATION KEY - Description of event
    picture = religious_rite # EVENT PICTURE

    goto_location = scope:plague_city_scope # SPECIAL FIELD - Find important province
   
    left_portrait = current_ruler # LEFT PORTRAIT - Ruler shown at the left hand side in event

    trigger = { # TRIGGER FIELD - Checks if the event will fire at all
        NOT = { has_variable = "rel_flavor_hellenic_16_cooldown" } # VARIABLE - Cooldown check
        religion = roman_pantheon # TRIGGER - Checks if the country has the Hellenic religion
        NOT = { has_country_modifier = rel_flavor_hellenic_asklepian_blessing_modifier } # TRIGGER - Check for country modifier
        num_of_cities > 3 # TRIGGER - Check that you have more than 3 territories
        num_of_cities < 50 # TRIGGER - Check that you have less than 50 territories
        any_owned_province = { # TRIGGER SCRIPT LIST - Checks if we any owned province
            is_capital = no # TRIGGER - That isn't a capital
            NOR = { # BOOLEAN OPERATOR - Nor have
                has_province_modifier = asklepion # TRIGGER - the Asklepion province modifier
                has_province_modifier = rel_flavor_hellenic_asklepian_plague_modifier # TRIGGER - The Asklepian Plague modifier
            }
            has_city_status = yes # TRIGGER - That has city status (i.e city/metropolis)
            total_population > 15 # TRIGGER - With more than 15 pops
        }
    }

    immediate = { # EFFECT FIELD - Fires after trigger check, but before everything else
        set_variable = { # VARIABLE - Set up a variable that will work as a cooldown
            name = "rel_flavor_hellenic_16_cooldown" # Special Field - Variable name
            days = 3650 # Special Field - Variable duration (10 years)
        }
        random_owned_province = { # EFFECT - Find a random owned province
            limit = { # LIMIT - Set Trigger Field
                is_capital = no # TRIGGER - That isn't a capital
                NOR = { # BOOLEAN OPERATOR - Nor have
                    has_province_modifier = asklepion # TRIGGER - the Asklepion province modifier
                    has_province_modifier = rel_flavor_hellenic_asklepian_plague_modifier # TRIGGER - The Asklepian Plague modifier
                }
                has_city_status = yes # TRIGGER - With city status
                total_population > 15 # TRIGGER - And more than 15 pops
            } # End of Trigger Field
            save_scope_as = plague_city_scope # EFFECT - Save Scope for later use
        }
    }

    option = { # EFFECT FIELD - FIRST OPTION - Options the player can choose between when receiving the event
        name = rel_flavor_hellenic.16.a # LOCALIZATION KEY - Option A text
        current_ruler = { # EVENT TARGET - Find current ruler of your country
            add_popularity = subtract_popularity_small # EFFECT - Reduce popularity of ruler
        }
        scope:plague_city_scope = { # SAVED SCOPE - Find affected city
            add_province_modifier = { # EFFECT - Add a province modifier to the saved scope
                name = rel_flavor_hellenic_asklepian_plague_modifier # SPECIAL FIELD - Find the modifier to add
                duration = 3650 # SPECIAL FIELD - Duration of the modifier, counted in days (so 10 years for this one)
            }
            while = { # WHILE Loop
                count = 3 # Special Field - Will run 3 times
                limit = { # TRIGGER FIELD - The While loop will end if the following requirements are not true
                    total_population > 1 # TRIGGER - Population higher than 1
                } # END OF TRIGGER FIELD
                random_pops_in_province = { # EFFECT - Find a random pops in the saved province scope
                    kill_pop = yes # EFFECT - Kill the pop we have found
                }
            }
        }
    }
    option = { # EFFECT FIELD - SECOND OPTION - Options the player can choose between when receiving the event
        name = rel_flavor_hellenic.16.b # LOCALIZATION KEY - Option B text
        current_ruler = { # EVENT TARGET - Find current ruler of your country
            add_popularity = popularity_small # EFFECT - Increase popularity of your ruler
        }
        add_treasury = { # EFFECT - Add or remove gold from your treasury
            subtract = scope:plague_city_scope.total_population # INLINE MATH - Subtract gold equal to the population of the city
            multiply = 1.5 # INLINE MATH - Multiply that number by 1.5
            max = -20 # INLINE MATH - Inverted because it is a negative number, you must pay a minimum of 20 gold
            min = -100 # INLINE MATH - Inverted because it is a negative number, you never need to pay more than a max of 100 gold
        }
    }

    option = { # EFFECT FIELD - THIRD OPTION - Options the player can choose between when receiving the event
        name = rel_flavor_hellenic.16.c # LOCALIZATION KEY - Option C text
        trigger = { # TRIGGER FIELD - Checks if the option will show up or not
            OR = { # BOOLEAN OPERATOR - Either of the following statements must be true
                any_owned_province = { # TRIGGER SCRIPT LIST - Check if you have any owned province with
                    has_province_modifier = asklepion # TRIGGER - The province modifier Asklepion
                }
                current_ruler = { # EVENT TARGET - Find current ruler
                    has_character_modifier = character_improvement_asclepian_wiseman # TRIGGER - And check if they have the character modifier Asklepian Wiseman
                }
            }
        } # END OF TRIGGER FIELD
        highlight = yes # Special Field - Highlights option
        custom_tooltip = rel_flavor_hellenic.16.c.tt # LOCALIZATION KEY - Adds special loc when hovering the option
        current_ruler = { # EVENT TARGET - Find current ruler
            add_popularity = popularity_small # EFFECT - Add popularity to the character
        }
        if = { # If Clause
            limit = { # LIMIT - Trigger Field
                current_ruler = { # EVENT TARGET - Check if current ruler
                    has_character_modifier = character_improvement_asclepian_wiseman # TRIGGER - Have the Asklepian Wiseman modifier
                }
            } # END OF TRIGGER FIELD
            current_ruler = { # EVENT TARGET - Find current ruler
                remove_character_modifier = character_improvement_asclepian_wiseman # EFFECT - Remove Asklepian Wiseman modifier
            }
        }
        else = { # Else Clause
            add_country_modifier = { # EFFECT - Add country modifier
                name = rel_flavor_hellenic_asklepian_blessing_modifier # SPECIAL FIELD - Find the modifier to add
                duration = 3650 # SPECIAL FIELD - Set duration
            }
        }
    }
}

So this is what our final Script looks like, with all the effects, triggers etc implemented, leading to a fully functional event. All that remains now is to make sure it can actually be fired, which means we need to add it to an on_action file.

We will open the file ‘Imperator\game\common\on_action\00_custom_on_actions.txt’ and go down to ‘main_event_pulse_country’, which is the pulse where we generally fire flavor events.

The on_action is split into triggers, events and random_events, and it fires yearly. This means that it will check every year if you are viable to receive an event, then it will try to fire every event in the ‘events’ category, and one single event from the ‘random_events’ category (based on the weighting of the events, which is the number in front of them).

As our event ended up being a tad punishing, and not something you want to see too often, we will add it to the ‘random_events’ category with a low chance of firing.

upload_2019-11-15_10-30-7.png

Code:
20 = rel_flavor_hellenic.1 # Rel Flavor Hellenic
25 = rel_flavor_hellenic.3
50 = rel_flavor_hellenic.6
50 = rel_flavor_hellenic.7
40 = rel_flavor_hellenic.8
20 = rel_flavor_hellenic.9
50 = rel_flavor_hellenic.10
10 = rel_flavor_hellenic.11
50 = rel_flavor_hellenic.14
100 = rel_flavor_hellenic.15
20 = rel_flavor_hellenic.16
100 = rel_flavor_canaanite.1 # Rel Flavor Canaanite

And with the event added to an on_actions file, that should be the last thing we needed to do.

With this, we have added an entirely new event to the game, and it wasn’t too time consuming or difficult. Events are fairly simple (though time consuming) to add, unless you want to do something very complex, where it might be more difficult to keep track of everything and getting everything down right.
 
Is there any intention to develop this so that you do not have to modify the files in on_actions?
 
  • 1
Reactions: