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

Chrysaetos

Second Lieutenant
37 Badges
Jan 22, 2013
136
144
  • Cities in Motion 2
  • Europa Universalis IV: Pre-order
  • Cities in Motion
  • Europa Universalis IV: Res Publica
  • Magicka
  • Knights of Pen and Paper +1 Edition
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Art of War
  • Europa Universalis IV
  • Crusader Kings II: Sunset Invasion
  • Crusader Kings II: Sons of Abraham
  • Crusader Kings II: The Republic
  • Crusader Kings II: Rajas of India
  • Crusader Kings II: The Old Gods
  • Crusader Kings II: Legacy of Rome
  • Crusader Kings II
  • Crusader Kings II: Sword of Islam
  • Europa Universalis IV: Rights of Man
  • Europa Universalis IV: Mandate of Heaven
  • Europa Universalis IV: Third Rome
  • Europa Universalis IV: Cradle of Civilization
  • Europa Universalis IV: Rule Britannia
  • Europa Universalis IV: Dharma
  • Crusader Kings III
  • Europa Universalis IV: Golden Century
  • Prison Architect
  • Stellaris Sign-up
  • Stellaris: Galaxy Edition
  • Stellaris: Galaxy Edition
  • Stellaris
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Common Sense
  • Europa Universalis IV: El Dorado
  • War of the Roses
  • Victoria 2
Hi, I'm Chrys and I'm here to provide a guide on how to make a simple but branching colony event.

I advise you to get Notepad++ as well as @allocater 's Notepad++ Stellaris Syntax Highlighting File.

We're gonna go through the entire process on how to make a colony event and I'll comment the code the whole way. The event we're gonna follow is from my own mod Vanilla+ (shameless self-plug I hope you'll excuse). For the sake of brevity, I'm going to skip the part about making a mod and uploading it to the Steam Workshop because I'm sure you can find a guide that illustrates that already.

Good. Let's get started.

So first of all, we go over to

"\Documents\Paradox Interactive\Stellaris\mod\Your Mod"

and we're gonna create a new folder 'events'. In our new folder of

"\Documents\Paradox Interactive\Stellaris\mod\Your Mod\events"

we're gonna create a new file "xx_colony_events.txt", where xx can (and should) be replaced with a tag relating to your mod. This is done to preserve compatibility with similar mods. PS: Don't use 'vp_', it's mine.

Alright, we got our file in our mod directory, let's start writing our colony event.

Code:
namespace = vp_colony #What all your colony ids will start with

### Ancient Energy Recharging Technology <-- This is just a comment, it's here so we know what event we're supposed to be writing.

planet_event = { #Identifies this as a planet-based event and not for example, a country-based one.
    id = vp_colony.10 #This is the event's id, when we want an event to call it up, this is the id we should refer
    title = "vp_colony.10.name" #This is for localisation, it's the title on top of the event and we'll write the flavour text later when we get to localisation.
    desc = "vp_colony.10.desc" #Also for localisation, this is the flavour text below the title
    picture = GFX_evt_alien_ruins #A cute picture so your event is prettier, you can use the ones Paradox made, they're in \SteamApps\common\Stellaris\gfx\event_pictures
    show_sound = event_alien_signal_02 #A sound to let your players know stuff went down, they're located in \SteamApps\common\Stellaris\sound\event
    location = ROOT #Defines the planet as our ROOT, this is helpful for when you want to bring up the planet's name in localisation

    trigger = {
        has_owner = yes #Will only spawn on owned planets
        original_owner = yes #Will not spawn on conquered planets
        is_homeworld = no #Will not spawn on the homeworld
        owner = { is_ai = no } #Can only spawn for players
        has_ground_combat = no #Planet is not engaged in an invasion
        num_pops > 0 #Planet needs to have at least 1 pop
        is_capital = no #Planet is not your capital
        OR = { #Will only spawn in Gaia, Desert, Arid, Tundra or Arctic Worlds.
            is_planet_class = pc_gaia
            is_planet_class = pc_desert
            is_planet_class = pc_arid
            is_planet_class = pc_tundra
            is_planet_class = pc_arctic
        }
        NOT = {
            has_global_flag = vp_ancient_recharger #assigns a tag that'll tops the event from spawning more than once per game
            has_planet_flag = colony_event #limits a planet to a single colony event
        }
    }


    mean_time_to_happen = {
        months = 24 #Average amount of time this event takes to trigger given that the trigger conditions are met
    }

    immediate = { #The set of commands here will trigger immediately when the event does
        set_global_flag = vp_ancient_recharger #adds a tag globally, together with the trigger, it'll stop the event from spawning more than once per game
        set_planet_flag = vp_ancient_recharger #adds a tag to the planet, so we call up the specific planet we want with a random={ } function if we want
        set_planet_flag = colony_event #Paradox (and I) use this tag to limit a planet to a single colony event, you could omit this is you like.
        random_tile = { #This function will select a random tile on the planet
            limit = { #This will limit the tiles that the random_tile function can select
                has_blocker = no #It won't select any tiles that have tile_blockers
                has_grown_pop = no #It won't select any tiles that have grown pops
                has_building = no #It won't select any tiles that have buildings
                has_building_construction = no "It won't select any tiles you're already building on
            }
            set_blocker = "vp_tb_ancient_recharger" #Once it finds a tile that meets the limit conditions, it'll spawn a "vp_tb_ancient_recharger" tile blocker, that we'll define in a bit.
        }
        random_tile = { #This and the next random_tile functions do the same as the above one so that we spawn 3 total tile blockers.
            limit = {
                has_blocker = no
                has_grown_pop = no
                has_building = no
                has_building_construction = no
            }
            set_blocker = "vp_tb_ancient_recharger"
        }
        random_tile = {
            limit = {
                has_blocker = no
                has_grown_pop = no
                has_building = no
                has_building_construction = no
            }
            set_blocker = "vp_tb_ancient_recharger"
        }
        add_modifier = {
            modifier = "vp_mod_ancient_recharger" #This adds a planetery modifier to the planet
            days = -1 #This is the duration, with -1 being a permanent event (until removed by another event anyway)
        }
    }

    option = { # This is what your players get to click. In this case, since we only have a single option function, the player will only get one choice, if you were to write several option functions, the player would have more choices, with the outcomes you write in.
        name = vp_colony.10.a #This defines the text in the option, we'll write it in localisation later
        begin_event_chain = { #This links the two special projects we're gonna provide in a chain
            event_chain = "vp_ancient_recharger_chain" #this defines the chain we're using
            target = ROOT #this is defining what planet this stuff is supposed to go on
        }
        enable_special_project = { #This and the next function enable special projects.
            name = "VP_ANCIENT_RECHARGER_1_PROJECT" #The key for the special project, it's just an id
            location = this #It's supposed to go on this planet
            owner = root #Whoever got the event is supposed to get the special project
        }
        enable_special_project = {
            name = "VP_ANCIENT_RECHARGER_2_PROJECT"
            location = this
            owner = root
        }
    }
}

So that's our starter event! That wasn't so hard uh? Well, now we have to go build the things it's calling on.

Let's start with the tile blocker. We're gonna create a new file 'xx_tile_blockers.txt' and put it in "\Documents\Paradox Interactive\Stellaris\mod\Your Mod\common\tile_blockers\" .

Code:
#Ancient Capacitor

vp_tb_ancient_recharger = { #this is the tile blocker id we called on in our event, we're defining it now
    picture = tb_city_ruins #the picture we're using for it, you can find them at \SteamApps\common\Stellaris\gfx\interface\icons\tile_blockers
    cost = { # It's empty because we're defining it as something the player can't remove
    }

    spawn_chance = { #This defines the spawning change of the tile blocker
        modifier = {
            add = 0 #In our case, we're defining it as null. We're only spawning these via event.
        }
    }
}

Cool, let's look at the event chain now. For this one, we'll create a new file 'xx_event_chains.txt' and put it in "\Documents\Paradox Interactive\Stellaris\mod\Your Mod\common\event_chains\".

Code:
vp_ancient_recharger_chain = { #the chain id we called up in our event
    icon = "gfx/interface/icons/situation_log/situation_log_main_quest.dds" #the icon we're using for the chain when it shows up in the special events log
    picture = GFX_evt_alien_ruins #the picture that'll show up on the event
}

So we got our event chain, let's look at the special projects we want associated with it. Again, new file 'xx_special_projects.txt' over at "\Documents\Paradox Interactive\Stellaris\mod\Your Mod\common\special_projects\"

Code:
#Ancient Capacitor

special_project = {
    key = "VP_ANCIENT_RECHARGER_1_PROJECT" #This special project's id
    event_chain = "vp_ancient_recharger_chain" #The event chain it's tied to, which we defined above
    cost = 500 #Its cost, just like the uplifting special projects in vanilla. You could also use "days_to_research = XX" if you wanted to
    tech_department = physics_technology #the technology department it's related to and the one it'll tie up while it's being researched, the other ones being society and engineering

    event_scope = planet_event #It's a planet-based event

    on_success = { #What'll happen if it's completed
        planet_event = { id = vp_colony.11 } #It'll trigger the event vp_colony.11 which we'll get to
        owner = { end_event_chain = "vp_ancient_recharger_chain" } #This end the event chain
    }

    on_fail = { #What'll happen if you fail the special project. In this case, it's not actually possible to fail, you could make it so by adding a "time_limit = XXX" function.
    }
}
#this project is exactly the same as the previous one, it just ties up a different department and it triggers a different event (for branching!)
special_project = {
    key = "VP_ANCIENT_RECHARGER_2_PROJECT"
    event_chain = "vp_ancient_recharger_chain"
    cost = 500
    tech_department = engineering_technology

    same_option_group_as = { VP_ANCIENT_RECHARGER_1_PROJECT } #These need to be added in subsequent special events that are tied up in the same event chain

    event_scope = planet_event

    on_success = {
        planet_event = { id = vp_colony.12 }
        owner = { end_event_chain = "vp_ancient_recharger_chain"
        }
    }
    on_fail = {
    }
}

So now let's look at the Planetary Modifier we added. It's probably starting to get old but we're gonna create a new file 'xx_planet_modifiers' and put it in "\Documents\Paradox Interactive\Stellaris\mod\Your Mod\common\planet_modifiers\".

Code:
vp_pm_mod_ancient_recharger = { #this part is unintuitive because we didn't add this modifier, we added a static one, however this will make it so that the planetary modifier takes the static modifier's benefits and descriptions
    spawn_chance = {
    #leaving this empty so that it is solely spawned by Event
    }

    modifier = "vp_mod_ancient_recharger" #This is the static modifier it'll call up
}

So we need to sort out this static modifier thing. Same old tale: new file 'xx_static_modifiers.txt' over in "\Documents\Paradox Interactive\Stellaris\mod\Your Mod\common\static_modifiers\"

Code:
vp_mod_ancient_recharger = { #this is the id we called up with our event and that'll be called up by the planetary modifier

    icon = "gfx/interface/icons/planet_modifiers/pm_strong_magnetic_field.dds" #this gives it a pretty icon
    icon_frame = 3 # 1 gives a green frame, 2 gives a yellow frame and 3 gives a red frame. We picked red because these tile blockers are undesirable! (for now)
}

So now, we're gonna give all of these things actual names and descriptions. We're going over to localisation.

Same old spiel, we create a new file 'xx_localisation_l_english.yml' and be careful that in this case it does need to end in '_l_english.yml' for English localisation (or _l_spanish.yml for the Spanish one and so on).

We'll add our new file to "\Documents\Paradox Interactive\Stellaris\mod\Your Mod\localisation\".

Here's the example from my mod:

Code:
l_english: # NOTE: IT IS VERY IMPORTANT TO START EVERY LINE WITH A SPACE, OTHERWISE THEY WON'T BE LUMPED IN WITH THE l_english: FUNCTION.

# [Root.GetName] pulls up the Planet's Name, other useful functions are [From.GetRulerTitle] to get your Empire Leader's title or [From.GetRulerName] for his name. In the case of planet events, Root is generally the Planet and From is usually the owner.

##############################
# Vanilla Plus Colony Events #
##############################

#Ancient Recharging Technology
vp_colony.10.name:0 "Ancient Technology found on [Root.GetName]." #This is the title, we set up before, [Root.GetName] calls up the planet's name. :0"<Text>" Is how you define the text that'll show up.
vp_colony.10.desc:0 "As our colonists on [Root.GetName] were surveying the planet for possible settlement expansion sites, they came across what we believe is an ancient wireless capacitor. It seems to recharge most electrical devices within several kilometers of itself." #This is the description of the first event, the meat of the text.
vp_colony.10.a:0 "We'll get the Scientists on it." #This is what will show up as an option for the player to click

#################################
# Vanilla Plus Special Projects #
#################################

#Ancient Recharging Technology
VP_ANCIENT_RECHARGER_1_PROJECT:0 "Utilize the Ancient Capacitors" #Special Projects always use their key in localisation
VP_ANCIENT_RECHARGER_1_PROJECT_DESC:0 "Our scientists believe it is possible to make use of the Capacitors to boost our production on [Root.GetName]." #Their descriptions always use their KEY with an added _DESC.
VP_ANCIENT_RECHARGER_2_PROJECT:0 "Remove the Ancient Capacitors"
VP_ANCIENT_RECHARGER_2_PROJECT_DESC:0 "Our scientists believe that removing the capacitors won't be difficult. Albeit they do think it'll be time consuming."

###############################
# Vanilla Plus Tile-Blockers  #
###############################
#Ancient Recharging Technology
vp_tb_ancient_recharger:0 "Ancient Capacitor"
vp_tb_ancient_recharger_desc:0 "An Ancient Capacitor is lodged in the ground here. Building on top of it is just impossible and living in too close proximity might be dangerous to our population."

#################################
# Vanilla Plus Planet Modifiers #
#################################

#Ancient Capacitor
vp_mod_ancient_recharger:0 "Ancient Capacitor Technology"
vp_mod_ancient_recharger_desc:0 "Ancient Capacitors are embedded into the planet's soil, they're only an annoyance for now."

#################################
#   Vanilla Plus Event Chains   #
#################################
vp_ancient_recharger_chain_title:0"Ancient Capacitors on [Root.GetName]"
vp_ancient_recharger_chain_desc:0"We've uncovered some ancient complexes on [Root.GetName] that hinder our settlement's expansion. Our scientists have come up with some methods to approach the problem."

In the next post, I'll show the other related events from my mod to serve as a guide but I'll solely comment on things I haven't commented on previously.

Note that I omitted localisation text from further events and kept only the parts that were shown in this example already.
 
Last edited:
  • 4
  • 2Like
Reactions:
In this event we'll replace all the tile blockers we added with new ones.

Code:
# Special Project Completed 1
planet_event = {
    id = vp_colony.11
    title = "PROJECT_COMPLETE" #You don't always have to write your own localisation, you can just use the ones Paradox already wrote.
    desc = "vp_colony.11.desc"
    picture = GFX_evt_alien_ruins
    location = ROOT

    is_triggered_only = yes #This means that the event will only show up if another event or special project calls it up. In this case, Special Project 1 did.

    option = {
        name = EXCELLENT
        hidden_effect = {
            set_planet_flag = vp_studied_capacitors #Important for Event 13
            every_tile = {
                limit = { has_blocker = "vp_tb_ancient_recharger" }
                remove_blocker = yes
                set_blocker = "vp_tb_ancient_recharger_2"
            }
        }
    }
}

And the code for these new blockers:

Code:
vp_tb_ancient_recharger_2 = {
    picture = tb_city_ruins
    cost = { # Can't be removed
    }

    spawn_chance = {
        modifier = {
            add = 0
        }
    }

    adjacency_bonus = { #These specific tile blockers add +2 Physics and Engineering Research to labs that are adjacent to them.
        resource_engineering_research_add = 2
        resource_physics_research_add = 2
    }
}

You'll obviously need to write the localisation for all of this stuff, I'm omitting it for the sake of brevity.

So, we have another Event, this one comes out from Special Project 2.

Code:
#Special Project 2 Complete

planet_event = {
    id = vp_colony.12
    title = "PROJECT_COMPLETE"
    desc = "vp_colony.12.desc"
    picture = GFX_evt_alien_ruins
    location = ROOT

    is_triggered_only = yes

    option = {
        name = EXCELLENT
        set_planet_flag = vp_destroyed_capacitors #Important for Event 13
        remove_modifier = "vp_mod_ancient_recharger" #This removes the planetary modifier from the planet
        hidden_effect = { #This function will omit what your option does from the player so it doesn't show up on the tooltip
            every_tile = {
                limit = { has_blocker = "vp_tb_ancient_recharger" }
                remove_blocker = yes
            }
        }
    }
}

However, this event chain seems too nice. Some tile blockers? You can even ignore the special projects because they don't have a time limit? We need some consequences for the people sleeping on this event surely? That's where Event 13 comes in.

Code:
#Unresearched Capacitor causes Problems!

planet_event = {
    id = vp_colony.13
    title = "vp_colony.13.name"
    desc = "vp_colony.13.desc"
    picture = GFX_evt_alien_ruins
    show_sound = event_air_raid_siren
    location = ROOT

    auto_opens = yes #Seems self-explanatory

    trigger = { #Defining the circumstances for when this event can fire
        NOT = { #If the following is true, then don't fire
            OR = { #Verify if either of the following conditions is true
                has_planet_flag = vp_destroyed_capacitors #See? Events 11 and 12 defined these two flags so that they'd stop Event 13 from showing up and being an asshole.
                has_planet_flag = vp_studied_capacitors
            }
        }
        has_planet_flag = vp_ancient_recharger #It does have to show up on the correct planet
        has_owner = yes
        original_owner = yes
        is_homeworld = no
        has_ground_combat = no #Means it won't show up in a planet that's under attack by Armies
        num_pops > 6 #This defines the minimum amount of population that's needed on the planet for the event to fire
    }

    mean_time_to_happen = {
        months = 60
    }

    immediate = {
        random_pop = { kill_pop = yes } #I mean... it seems self explanatory. It'll pick a random pop and kill it
        random_pop = { kill_pop = yes }
    }

    option = {
        name = colony.13.a #This option is empty because it's not supposed to do anything. It's supposed to make you feel bad for letting your pops die.
    }
}

However, I do think that down the line, your colony events should give you a little something Empire wide, so we're getting Events 14 and 15 involved.

Code:
planet_event = {
    id = vp_colony.14
    title = "vp_colony.14.name"
    desc = "vp_colony.14.desc"
    picture = GFX_evt_alien_ruins
    location = ROOT
 
    trigger = {
        NOT = {
            has_planet_flag = vp_destroyed_capacitors #We don't want people who destroyed the capacitors to get the benefit of studying them
        }
        has_planet_flag = vp_studied_capacitors #Requires you to have studied the capacitors
        has_planet_flag = vp_ancient_recharger
        has_owner = yes
        original_owner = yes
        is_homeworld = no
        has_ground_combat = no
        owner = {
            has_technology = tech_shield_rechargers_1 #This makes it so that the event can only fire, if he has researched the Shield Capacitor component for his ships.
        }
    }
 
    mean_time_to_happen = {
        months = 144
    }
 
    option = {
        name = vp_colony.14.a
        owner = { add_modifier = { modifier = vp_capacitors_shieldboost } } #This adds an Empire-wide bonus, which I'll show next.
    }
}

And

Code:
planet_event = {
    id = vp_colony.15
    title = "vp_colony.15.name"
    desc = "vp_colony.15.desc"
    picture = GFX_evt_alien_ruins
    location = ROOT
 
    trigger = {
        NOT = {
            has_planet_flag = vp_studied_capacitors #People who don't destroy Capacitors don't deserve this event
        }
        has_planet_flag = vp_destroyed_capacitors #Requires you to have destroyed the Capacitors
        has_planet_flag = vp_ancient_recharger
        has_owner = yes
        original_owner = yes
        is_homeworld = no
        has_ground_combat = no
        owner = {
            has_technology = tech_power_plant_3 #Again, a tech requirement
        }
    }
 
    mean_time_to_happen = {
        months = 144
    }
 
    option = {
        name = vp_colony.15.a
        owner = { add_modifier = { modifier = vp_capacitors_energyboost } }
    }
}

And the bonuses these two events provide:

Code:
vp_capacitors_shieldboost = {
    ship_shield_hp_mult = +0.10 # This will increase the Shield HP on all of your ships by 10%
}

vp_capacitors_energyboost = {
    tile_resource_energy_mult = 0.05 #This will increase all the energy you generate from tiles by 5%.
}

And that's it! Excluding writing the very extensive localisation, this is how you create a colony event chain!

Oh and as an aside for those of you who want to get creative with branching:

Code:
option = {
        name = vp_colony.10.d
        trigger = { #Only shows up for Militarist Empires
            owner = {
                OR = {
                    has_ethic = "ethic_militarist"
                    has_ethic = "ethic_fanatic_militarist"
                }
            }
        }
        add_modifier = {
            modifier = "vp_mod_militarist_capacitor"
            days = -1
        }
    }
 
Last edited:
  • 3
Reactions:
This is great! Thanks for writing this.

Say, if you have time, could you describe how ROOT works a bit more? The scope thing is still a bit Byzantine to me.

I feel the same way. In general what I've found is that for planetary events ROOT will define as the planet it triggered on, if it's a country event it'll define as the country who triggered the event. I've gone by feel for now mostly.
 
  • 1
Reactions: