Decisions

Code: christmas_presents = { more_guns = { } }

Code: christmas_presents = { }

Code: complete_effect = { add_equipment_to_stockpile = { type = infantry_equipment_1 amount = 1337 } }

Code: available = { has_country_flag = santa_podcat }

Code: cost = 42

Code: christmas_presents:0 "Christmas Presents" christmas_presents_desc:0 "To fight off the cold and the dark we need to gather christmas present." invite_santa:0 "Invite Santa" invite_santa_desc:0 "In the darkest of times there is only one place to turn. Ask Santa Podcat for gifts."

Code: days_remove = 5 #Stays for 5 days before being removed days_re_enable = 5 #Will show up in the interface and can be selected again after 5 days fire_only_once = yes #Will not re enable after being removed

Code: days_remove = 5 remove_effect = { add_political_power = 50 }

Code: modifier = { political_power_gain = 1 }

Code: christmas_presents = { invite_santa = { allowed = { tag = SWE } available = { date > 1936.11.30 date < 1936.12.25 } visible = { NOT = { has_country_flag = sadness_and_darkness } } fire_only_once = yes cost = 42 complete_effect = { custom_effect_tooltip = invite_santa_tt set_country_flag = santa_podcat } } more_guns = { allowed = { tag = SWE } available = { has_country_flag = santa_podcat } visible = { NOT = { has_country_flag = sadness_and_darkness } } modifier = { political_power_gain = 1 } days_re_enable = 5 days_remove = 5 remove_effect = { add_political_power = 50 } complete_effect = { add_equipment_to_stockpile = { type = infantry_equipment_1 amount = 1337 } } } }

Code: ruin_christmas = { allowed = { tag = FIN } target_trigger = { FROM = { OR = { tag = SWE tag = DEN tag = NOR } } } available = { FROM = { has_country_flag = santa_podcat } } complete_effect = { declare_war_on = { target = FROM type = ruin_christmas } FROM = { set_country_flag = sadness_and_darkness } } }

Code: ruin_christmas:0 "Ruin Christmas for [From.GetNameDef]"

Code: activate_targeted_decision = { target = TAG decision = decision_to_activate }

Code: activate_targeted_decision = { target = FROM decision = decision_to_activate }

Missions

Code: more_cake = { allowed = { tag = SWE } available = { controls_state = 64 #THIS IS THE ACTUAL OBJECTIVE } activation = { has_stability < 0.3 #This starts the mission } Is_good = no days_mission_timeout = 3 fire_only_once = yes timeout_effect = { DEN = { annex_country = { target = ROOT } } } complete_effect = { add_political_power = 1337 } }

Code: war_with_on_remove = TAG war_with_on_complete = TAG war_with_on_timeout = TAG war_with_target_on_remove = yes war_with_target_on_complete = yes war_with_target_on_timeout = yes

Code: custom_cost_trigger = { has_army_experience > 10 } custom_cost_text = army_xp_more_than_10

Code: army_xp_more_than_10:0 "§H10§!£army_experience" army_xp_more_than_10_blocked:0 "§R10§!£army_experience" army_xp_more_than_10_tooltip:0 "It costs 10£army_experience to select this."

Code: highlight_states = { state = 64 }

Code: christmas_presents = { priority = { base = 0 modifier = { add = 10 has_country_flag = christmas_time } } }

New script features

Code: set_variable = { a = 20 } set_variable = { b = ROOT.political_power } multiply_variable = { var = b value = 2 } check_variable = { a > b }

Code: set_variable, add_to_variable, subtract_from_variable, multiply_variable, divide_variable, clamp_variable, has_variable, check_variable (compare = less_than, less_than_or_equals, greater_than, greater_than_or_equals, equals, not_equals)

Code: set_variable = { b = FROM.FROM.FROM.political_power }

Code: Some_loc_key:0 "Value of a: [?Root.a]"

Code: set_variable = { var = eng_opinion_on_turkey value = ENG.opinion@TUR }

Code: 64 = { set_variable = { a = 1 } } set_variable = { global.b = 1 }

Code: add_political_power = 141.infrastructure_level

Code: set_temp_variable = { a = 141.infrastructure_level } multiply_variable = { var = a value = 20 } add_political_power = a

Scripted Localisation

Code: defined_text = { name = GetIsThisDiaryLong text = { trigger = { always = yes } localization_key = YES_YES_YES } text = { localization_key = NO } }

Spoiler YES_YES_YES:0 “Maybe a little.”

Namelists

Code: GER_Inf_01 = { name = "Infantry Divisions" for_countries = { GER } can_use = { always = yes } division_types = { "infantry" } # Number reservation system will tie to another group. link_numbering_with = { GER_dog_divisions } fallback_name = "%d. Infanterie-Division" # Names with numbers (only one number per entry). # It's okay to have gaps in numbering. ordered = { 1 = { "%d. Infanterie-Division" } 2 = { "%d. Infanterie-Division" } 3 = { "%d. Infanterie-Division" } 4 = { "%d. Infanterie-Division" }

Code: name = "SS Divisions" can_use = { has_government = fascism }

Stability and War Support

Locking Division Templates

Code: delete_unit_template_and_units = { division_template = "Snowmen" }.

Unit Leader Scope

Code: random_army_leader = { limit = { average_stats < 2 is_field_marshal = no } set_unit_leader_flag = some_flag add_trait = useless_trait }

Focus Tree

Code: offset = { x = -6 y = 0 trigger = { tag = PRC } }

Targeted Modifiers

Code: targeted_modifier = { tag = SWE attack_bonus_against = 0.1 defense_bonus_against = 0.05 }

State Events

Code: state_event = { id = some_event.1 trigger_for = controller }

Off-Map Buildings

Code: add_offsite_building = { type = arms_factory level = 2 }

Code: add_offsite_building = { type = arms_factory level = -2 }

Hi everyone, its that time again. The one normal people spend on finding Christmas presents, drinking eggnog and/or glühwein and game devs scramble to finish stuff in time for the new yearWe figured this would be an excellent time to try to break the record on longest dev diary! Also, I'm not passing up a chance to paint a horrible Christmas picture!We are now going on a Christmas break (well on Friday) and will be back in January with diaries and working on Waking the Tiger. However I arranged a cool special diary for next week for you so there would be something @Jamor (the project lead for Stellaris), who is also a huge WW2 buff, is going to write a big piece on division names in the German armed forces. He has been helping us out and filling out our new naming system for Germany, so expect it to be massive and chock-full of historical details!Handing over to Havebeard now for tons of details on modding. If you know nothing about modding... this is gonna get technical! The simple translation to the below is that modding teams will now be able to do really cool stuff when 1.5 Cornflakes drops!This diary will be about the new script features for modders so I am gonna warn you again - If you are not a modder, we are now about to dive into the juicy/scary technical stuff!Still with us? Great!We come bearing gifts for the modding community and those who enjoy their work.One of the new shiny tools Content Designers on HOI4 have received is the Decision system. We have already covered what it is in a previous diary, but I figured there might be a modder or 2 who would like to use it, so here is a somewhat detailed rundown of how to use this new feature.The simplest decision you can script is this:This is put in a .txt file in this folder: common\decisionsAll decisions need to be wrapped in a category, in the above the category ischristmas_presents need to be defined like this:In a .txt file in this folder: common\decisions\categoriesThis will produce the following:This requires nothing and does nothing, which is a pretty big disappointment when someone expects guns. Not the most exciting thing so far, but we have to start somewhere.Adding an effect when the decision is selected is done like this:You can add an allowed trigger to either decision or category.Any country matching this trigger on startup will have the decision in its pool of possible decisions for the duration of the game. If you script allowed on a category, all decisions wrapped in this category will check the trigger. This is similar to how political advisor are scripted, where they are limited by country tag.Blocking a decision based on a dynamic trigger is done very similarly to focus, by scripting an available trigger.We will add another decision calledwhere we set that flag. In this decision we script the cost to take the decision. This is the cost in political power.Once you’ve made a couple hundred decisions the interface gets a little cluttered and a lot of them probably might be blocked by ideology, war or other things that means it won’t be relevant for the player. Entertrigger. When this is true the decision is shown in the interface.available and visible can also be scripted on the category, so if you have some complex trigger you want to apply to a bunch of decisions, you just have to add it in one place. This does not help with readability though, so use with care (or just use a scripted trigger).Both categories and decisions can have name and description.You can also use the generated localisation like [Root.GetNameDef], [Root.GetLeader] and so forth.Our decision now looks like this:This is the basics of decisions, but there are a few more things you can do with them.Some decisions you want to keep in the interface for a little while after selecting them. Some you will want to re-enable after a period of time and some you only want to happen once.We also added an effect that is run when a decision is removed, by scripting:This removes the decision after 5 days and add 50 political power to the country.Scripting a modifier on a decision will apply it to the country for a long as the decision is active (in the interface)Here is the script and a little example of how all of this might look:Let’s say you want to make a decision that involves two countries, but you want it to work with more than just one single specific country. Scripting one for each country in the world and all the potential other countries they can affect gets messy quick.Enter, targeted decisions. Still a little messy, but in a much better way.Once per day the system looks for countries that match the target_trigger and if a match is found a new decision with that particular country as target is added.Triggers and effects for targeted decisions can access the other country using FROM. (We are using FROM because of reasons. Trust us, they are good reasons. No, we can’t tell you.)In the example above Finland has the opportunity to ruin christmas and declare war on Sweden, Denmark or Norway. Way to go Finland…Notice the little flag denoting the target country and FROM being used in place of the target country. This makes it a powerful way of generating interactions between countries. FROM can be used inandThe target can also be used in localisation like this.Since target_trigger is checked for every country it can have quite a heavy effect on performance. If you simply want to add a targeted decision against a specific country from a focus you can do it by using an effect.You can also use one targeted decision to active a new one against the same country.In this case you do not need to script the allowed or target_trigger, but can just let the decision sit in the database until you need it.Scripted in the same place and almost the same way as decision. These require you to either fulfill or avoid certain conditions in a given time frame.Here the Swedes have reached low stability, causing the mission to activate (activation trigger becomes true). The available trigger is used for the objective and if it is met, the complete_effect will be run. (There are good reasons why available is the objective. Very good reasons. The best reasons.)Is_good = yes/no only defines the tooltips and color of the progress bar. It is always the timeout_effect that is run when days_mission_timeout goes below 0.Note that modifiers do not work with missions, but we are probably going to add that in the future.I would not recommend straight up war from a decision, but here are a couple of ways to tell the AI to watch out when certain decisions are in play.is scripted same way as for any national focus. It will weigh decisions against each other and pick the highest scoring one. Ifis not scripted for a decision it will not be selected by the AI.For some decisions you might not want the cost to be political power. We have added a custom cost trigger that lets you define your own cost. Here is a simple one as an example.When you script a custom_cost_trigger the normal cost is ignored, and instead this trigger is checked.The localisation key we point to in custom_cost_text is what is used to generate the text in the interface and on the tooltip. In our example when we fulfill the cost trigger army_xp_more_than_10 is shown, but when we don’t have enough XP, army_xp_more_than_10_blocked is shown. Army_xp_more_than_10_tooltip is optional and will replace the usual text on the bottom of the tooltip if the key is added.EDIT:The custom cost trigger is mainly there for presentation. It is only a trigger that checks if you are allowed to take the decision. It does not in itself modify anything. In the case above you will have to deduct the army xp in the effect (and then probably hide it to not have double tooltip).The same thing can be achieved with putting the trigger in available and then reducing whatever you cost is in the effect, but this looks nicer.For cost over time (political power drain fx) this is a way of showing the player that cost instead of it looking like a freebie at first glance and this is not something you can as easily communicate in the trigger.Highlight a random state that matches the trigger when hovering over the decision. Right clicking moves the map to the state.Example:Categories can have priority scripted to order them in the interface. This number is scriptable, so you can change priority based on a trigger.picture = picture_nameCorresponds to GFX_decision_cat_picture_nameicon = icon_nameCorresponds to GFX_decision_icon_nameActivated in the same way as normal targeted decisions, but if days_mission_timeout is scripted, they will be a targeted mission instead.Turns out there are quite a few things you can do with this system and it takes a while to explain in writing. I think I covered most parts, but don’t hesitate to ask in the comments or on the modding forum once you get your hands on the script.For those of us on the team who use the scripting language it is always a great pleasure when scripting features from other projects get ported to Hearts of Iron. @shultays has been a true champion of script during development and has blessed us with variables. Make sure to name your firstborns after him.This sets variable a to 20, b to the ROOT country’s political power, multiplies it and then checks if a is greater than b.Variables can be named dynamically in the same way as flags using @. That has already been covered earlier, so I won’t spend more time on it.Checking PP like that is of course nothing fancy, but you get the idea and with the following available you start being able to do a lot more interesting things with variables.You can also “chain scopes” when getting and setting variables. It would probably be better to save it as an event target instead, but you may find yourself in situations where that is not possible.There are also temporary variables, which only exist inside the current trigger or effect. They work like normal variables, but are set with. The advantage of these is that they can be set and used in triggers to do some calculation relevant for it.Variables can also be used in localisation using ?.This will print: Value of a: 20 (since we set our variable a to 20 further up)You can also get party support of a specific ideology as a variable like this:Variables like party_popularity and political_power are special variables that exist from the start and are read only. They are meant to get data from the game. There are a bunch of them and more will probably be implemented as we go.Country: political_power, command_power, manpower, max_available_manpower, max_manpower, opinion, stability, modifier, party_popularity.State: resistance, arms_factory_level, industrial_complex_level, infrastructure_levelOpinion is another special one where you can goVariables are stored on the scope you are currently in unless you use global.The first example below set the variable a to 1 and stores it on state 64.The second example sets variable b to 1 and saves it as a global variable.If you name your own variables political_power or other reserved variable names, all manners of crazy events can happen, ranging from the universe imploding, fire raining from the sky to Sweden defeating Italy in football and the dead rising from their graves to feast upon the living.So don’t do it.At some point you may find that you have been scripting for a couple of hours and absolutely nothing works (this has absolutely never happened to anyone at paradox, so this is merely hypothetical). Using list_vars in the console will print variables for the country or state you have currently selected. You can also give the state or country as an argument in case you don’t want to select it.In the console:list_vars ENG (prints variables set on ENG)list_vars 37 (prints vars on Sjælland)Variables can be used in place of numbers in a lot of places.This would add political power equal the Infrastructure level in Svealand, so not a whole lot...This would add political power equal 20 time the Infrastructure level in Svealand, so still not a whole lot…Most simple effects and triggers that just take a number will work with variables, but the ones where you pass multiple arguments are not guaranteed to work.“So”, you may say, “this is kind of like flags. Should we just throw away all flags now? Is that what you want from us, Paradox? A flagless society?”No. Flags are faster to check performance wise, so keep using them if all you need to do is mark something. @shultays also added list_flags to the console, so even flags are easier to work with now.This dev diary has gotten way too long and run way way over time, but I promise variables will be covered in more detail on the modding forum next year (when you ask me how it works...).Quite well documented in the file and available on other projects, so for a lot of people this will not be news.Allows you to create your own dynamic keys to be called in localization.-> this is it, we're defining the text-> a discrete entry that can be picked to display in loc.-> determines if a text entry will be picked or not.(The triggers need to be valid for the scope the key is called in (eg Root or From.From)-> points to the localization key that'll be used if trigger passesIn localisation: [Root.GetIsThisDiaryLong] will be replaced with YES_YES_YES.Sidenote: Focuses can take scripted localisation as a name if you set them to dynamic = yesThis is how you script namelists.Pretty self explanatory.means that divisions from this naming template will share numbering with this one.is a way to limit when the namelist is active.Example:When the scripted names run out the fallback_name starts getting used.Since national unity is no longer a thing, modders can already now start replacing set_national_unity and add_national_unity with the new set_stability and add_stability and war_support. Things like national_unity_factor work the same way, just replace national_unity with stability or war_support as appropriate. Triggers work as you’d expect (has_stability and has_war_support). Setting and trigger off of stability/war_support is on a scale of 0-1 (so set_stability = 0.5 and has_war_support > 0.3)You can script templates as is_locked = yes. This disables modifications and training of that template. You can delete these special templates later withWe also added a unit leader scope, which lets you run effects on random or all unit leaders (Generals, Field Marshals, Admirals) based on a trigger.Here is how you get them:Use trigger_docs to find effects you can use on them.Example:If you define a focus by writing shared_focus instead of focus you can add the focus to another tree using. The focus and all its children (and their children etc.) will be added to the country.To avoid shared focus overlapping with normally scripted ones you can script dynamic positioning.is a new effect that will change the current country’s focus tree to whatever tree is specified.National spirits can have targeted modifiers, meaning the modifier applies only in relation to a specified other country.Example giving a country attack and defense bonus against Sweden :Defining an event as a state_event and triggering it using the effect with the same name lets you fire an event specific to that state. The receiver is defined in trigger_for.As part of the Chinese focus tree, we added support for off-map factories. This supports any kind of building that does not need to be on the map to work (civilian and military factories, shipyards, synthetic refineries, nuclear reactors)The buildings act like any on-map building with the exception that they, obviously, can’t be bombed or conquered. To remove off-map buildings, you add negative ones:Removing off-map buildings that aren’t there leads to a hard reset of the entire universe so we’d all appreciate it if you didn’t do that.Hopefully this will get you started using the new systems and be hungry for modding again. Remember that trigger_docs in the console is your friend and ask on the modding forum when you don’t find your answer there.Good luck out there! Script good and crash well!