Decisions and missions represent actions that the player can or must take, each one stored within a category. Decisions themselves are defined within /Hearts of Iron IV/common/decisions/*.txt files, while categories are defined within /Hearts of Iron IV/common/decisions/categories/*.txt. While it's typical to put the country's tag within the filename, it is actually irrelevant: files can take on any filename and there will be no difference in how they will be read.
Basic creation
Each decision must be stored within a category. Decision categories are defined within any /Hearts of Iron IV/common/decisions/categories/*.txt file. An incredibly basic decision category definition looks like the following:
my_decision_category = { }
This will create the my_decision_category
category, which can be used within decisions.
Afterwards, decisions can be created for that category in any /Hearts of Iron IV/common/decisions/*.txt file. Decisions are assigned to a category by putting them within that category's block, encompassed with the curly brackets, as in the following example:
my_decision_category = { my_decision_1 = { } my_decision_2 = { } }
This will create the my_decision_1
and my_decision_2
decisions, with the default icon and no effect, and assign them to the my_decision_category
category.
A decision's name according to the currently-turned on language can be defined in any localisation file, taking the decision's name as key, and the decision's name with _desc added in the end as the name for the localisation key for the description. As an example, the localisation for these decisions for the English language will look like the following within any /Hearts of Iron IV/localisation/english/*_l_english.yml file:
l_english: my_decision_category: "My decision category" my_decision_category_desc: "My decision category's description" my_decision_1: "My decision" my_decision_1_desc: "My decision's description" my_decision_2: "My decision without a description"
Arguments for decisions and categories
File:Ambox outdated info.png | 这部分内容可能已不适合当前版本,最后更新于1.11。 |
The following arguments can be used in either decisions or decision categories, usually with similar effect.
Triggers
Usually, it is desirable to restrict the decision so that it might not always be possible to take, such as restricting it to a certain country. In order to do that, there are several trigger blocks, serving different purposes. A decision will only be available or visible if the corresponding conditions are met in both the category and the decision.
allowed
is a trigger block that checks only at the game's start or when loading a save, primarily used to restrict a decision to a country (As tag = BHR
or original_tag = POL
) and/or a DLC (As has_dlc = "One Step Back"
). If a decision's or a category's allowed is unfulfilled, it will never appear unless it becomes true on the save being reloaded or decisions themselves being reloaded. If left out, assumes to be always allowed. This only checks once!
allowed = { original_tag = BHR }
visible
is a trigger block that continuously checks every frame if allowed was met, required to make the decision or the entire category be visible in the decision selection screen. In case for targeted decisions, both FROM and ROOT can be checked here, but using target_trigger is recommended when possible for optimisation purposes. It is preferable to put country or DLC checks into allowed instead. Does nothing for missions!
visible = { is_subject = no }
available
is a trigger block that continuously checks every frame if visible was met, required to be possible to actually take the decisions. If false, the decision (or, in case of categories, decisions within) will remain visible (unless set otherwise), but will be greyed out and be impossible to complete. This is applied on top of the political power cost. Applied differently for missions.
available = { has_war = yes }
Icon
The icon is the small picture displayed to the left of decision's or category's name. Icons use sprites, defined in any /Hearts of Iron IV/interface/*.gfx file, by default in decisions.gfx
. Within a decision or a category, it is set with icon = icon_name
.
Note that the game automatically inserts either GFX_decision_
or a GFX_decision_category_
, depending on whether it's in a decision or a category. As such, the example with icon_name will make it use the GFX_decision_icon_name
sprite for decisions and the GFX_decision_category_icon_name
for categories, or, other way around, to use GFX_decision_sprite_name
in a decision, it should have icon = sprite_name
.
However, icon = GFX_decision_icon_name
will also work, as the game will check the spriteType with the exact same name as well. Overall, it's to the developer's discretion whether to include GFX_decision_
/GFX_decision_category_
in the icon or not.
Priority
Priority is used to change the order in which decisions or categories are displayed from top to bottom, with a higher priority being closer to the top. By default, a decision has the priority of 1. Decision priority can be set in a short form for a static value or in a long form, similar to ai_will_do formatting.
In short form, the following code will set a decision or category to have the priority value of 10: priority = 10
In long form, the following code will have a priority value of 13 for POL and 3 for other countries:
priority = { base = 3 modifier = { add = 10 tag = POL } }
State highlighting
A decision or all decisions within a category can be set to highlight a state or several with an outline when hovering over it in the selection menu. This is the code required to do that:
highlight_states = { highlight_state_targets = { state = 123 state = 321 } highlight_color_while_active = 3 highlight_color_before_active = 2 }
highlight_state_targets
selects a specific state or several that will be highlighted. If the state is unknown, then highlight_states_trigger
can be used as a trigger block instead, evaluated for every state on the map.
highlight_color_before_active
is the colour that the state highlighting will have before selecting the decision, from 0 to 3. If not set, it will default to a white outline.
highlight_color_while_active
is the colour that the state highlighting will have after selecting the decision during the timer before it gets removed, from 0 to 3. If not set, it will default to a white outline.
Within regular decisions, only one state can be highlighted at a time. This restriction does not exist when used inside of decision categories.
Province Highlighting
In addition to highlighting states, it is also possible to highlight individual provinces since patch 'Stella Pollaris': 1.13.6. This is the code required to do that:
highlight_states = { highlight_state_targets = { state = 123 } highlight_provinces = { 123 213 321 232 } }
With highlight_provinces = { ... }
being the effect that stores the individual provinces to be highlighted.
Arguments for categories
File:Ambox outdated info.png | 这部分内容可能已不适合当前版本,最后更新于1.11。 |
These can only be used within categories and cannot be used in separate decisions.
Picture
A decision category can have a picture defined in addition to its regular icon. A picture will show up to the left of the category's description, shifting it to the left. Pictures use sprites, defined in any /Hearts of Iron IV/interface/*.gfx file, by default in decisions.gfx
. A sprite with the name of GFX_decision_category_picture
can be set as the category's picture with picture = GFX_decision_category_picture
. A category must have a description defined in localisation for the picture to appear.
Visibility when empty
By default, a decision category is invisible unless there's at least one visible decision within. This isn't always helpful, as the category may display information vital for the player in its description. To override that, you can add a line consisting of visible_when_empty = yes
within the decision category.
Map area
A decision category can be assigned a map area, which will show up in the top of the decision list similarly to a decision. Clicking on the button will move the camera to the specified state or states, while setting the zoom level to the set amount. This is recommended to do in decision categories containing decisions targeted towards states. A map area definition looks like the following:
on_map_area = { state = 123 name = my_localisation_key zoom = 850 target_root_trigger = { tag = ENG } }
state
sets a singular state that's used as the centre of the area where the camera will move. If the map area is to be dynamic, then formatting similar to targeted decisions can be used, with targets
, target_array
, and target_trigger
being available and mixable.
name
is the localisation key that will be used as the name of the pseudo-decision that moves the camera to the map area.
zoom
is the zoom level for the map area, set in the amount of pixels off the ground, meaning that a lower value results in it being zoomed in more. For comparison, by default, the player can change the camera zoom between 50[1] and 3000[2].
Additionally, each of the trigger blocks defined for decisions and categories (aside from available
) can go inside of on_map_area
, such as target_root_trigger
.
An example map_area with a dynamic target trigger:
on_map_area = { target_array = controlled_states name = occupied_states_map_area zoom = 150 target_trigger = { FROM = { NOT = { is_owned_by = ROOT } } } }
Scripted GUI
A decision category can be set to have a scripted graphical user interface container within the category, showing up below the description. The scripted GUI in question must have the decision_category context type for this to work. This is set with scripted_gui = my_scripted_gui
. See details on the dedicated page for scripted GUI.
Category examples
POL_my_category = { allowed = { tag = POL } priority = 10 picture = GFX_decision_category_picture icon = POL_category visible_when_empty = yes scripted_gui = POL_scripted_gui }
my_map_category = { visible = { has_completed_focus = my_focus } icon = my_map highlight_states = { highlight_states_trigger = { is_owned_by = ROOT is_capital = yes } } on_map_area = { state = 123 targets = { capital } zoom = 350 } }
Arguments for decisions
These can only be used within decisions and cannot be used in categories.
Effects on selection
complete_effect
is the block of effects that gets executed immediately when the decision is selected (Starting the timer if it has one).
complete_effect = { annex_country = { target = QAT } }
Decision reappearing
By default, a decision reappears on the very next day after being taken. In order to increase the cooldown in days, days_re_enable = 123
can be used to put in more days in the cooldown.
In order to make the decision disappear forever upon being completed, the fire_only_once = yes
line of code will ensure that, making the decision only be possible to fire once per country.
Decision cost
In order to assign a political power cost to a decision, the cost = <int>
argument is used. The cost can be assigned a variable. As an example of a decision which is assigned a cost of 50 political power:
find_resources = { develop_infrastructure = { cost = 50 available = { has_manpower > 500 } complete_effect = { random_owned_state = { add_building_construction = { type = infrastructure level = 2 instant_build = yes } } add_manpower = -500 } } }
Alternatively, a decision can also take a custom localisation string as the cost. This is done with the following:
custom_cost_trigger = { <triggers> } custom_cost_text = <localisation key>
If custom_cost_trigger is fulfilled, then <localisation key> will be used for localisation, otherwise, <localisation key>_blocked will be. <localisation key>_tooltip will be used when hovering over the cost. Using the example of the following:
custom_cost_trigger = { command_power > 14 } custom_cost_text = decision_cost_CP_15
The localisation file will have the following:
l_english: decision_cost_CP_15: "£command_power §Y15§!" decision_cost_CP_15_blocked: "£command_power §R15§!" decision_cost_CP_15_tooltip: "It costs £command_power §Y15§! to take the decision"
In order to show icons, text icons are used.
A custom cost will not actually cost anything, and what you set it to cost will have to be subtracted within the complete_effect
of the decision, preferably as a hidden effect.
As the custom cost can't be used in conjunction with the regular cost, if it includes political power, the AI will not be aware that it should save up an amount of it before taking the decision. This can be remidified with ai_hint_pp_cost = 100
: this attribute will make the AI think that the decision will use 100 political power regardless of whether it does or not, making sure it will save up that much before trying to use it. This must be a constant amount rather than being a variable.
Timer upon selection
In order to add a timer between the decision being selected and some of its effects applying, days_remove = 123
is used to define the amount of days. If set to -1
, the decision will never be removed by the timer running out, although additional trigger blocks can remove it.
As for defining the effects that would be executed when the timer ends, remove_effect = { ... }
is used as an effect block. Note that complete_effect = { ... }
is when the decision is selected starting the timer, rather than when the timer ends. In other words, this timer appears after the decision was completed and stays there until the decision is removed. Additionally, remove_trigger = { ... }
is used to instantly remove the decision once the triggers within are met for the country, also firing the remove_effect = { ... }
block.
Additionally, it is possible to make the decision apply modifiers during the timer's duration, with the modifier = { ... }
providing a modifier block. Similarly to ideas, targeted_modifier = { ... }
also exists as a way to apply targeted modifiers, in the same formatting with tag = BHR
setting the target, such as the following example:
targeted_modifier = { tag = ENG attack_bonus_against = 0.1 defense_bonus_against = -0.15 }
In order to make the timer cancel early without providing the effects, visible = { ... }
does not work by default.
Instead, cancel_trigger = { ... }
is used as a trigger block. Upon it being evaluated as true, the decision timer ends without remove_effect = { ... }
being executed. cancel_if_not_visible = yes
, false by default, serves as an easy way to add visible's triggers into the cancel_trigger = { ... }
block.
Upon the decision being cancelled, cancel_effect = { ... }
is an effect block that gets executed. This can be useful as a way to reverse the effects applied within the complete effect.
AI
- 主条目:AI modding、AI will do
The chance for AI to pick a decision is decided by the ai_will_do = { ... }
block within a decision, which is a MTTH block. By default, a decision will never be chosen by AI, and that block is required to make AI choose it.
As a MTTH block, the structure consists of factor = 10
or base = 10
to choose the initial value and modifier = { ... }
as trigger blocks assigning add
/factor
/base
in the order. For example, the following will make the decision be never chosen by AI, unless the country is at war with ITA, in which case it has 10 weight:
ai_will_do = { base = 0 modifier = { add = 10 has_war_with = ITA } }
Warning for war
If your decision leads to a nation declaring war on another nation, there are several arguments that can be used to inform the targeted nation that a war is coming, as well as alert the AI to begin moving troops onto the border:
war_with_on_remove = TAG
will make the game assume that the decision, within its remove_effect
will declare war on the specified country, making it prepare when the timer starts.
war_with_on_complete = TAG
will make the game assume that the decision, within its complete_effect
will declare war on the specified country, making it prepare when the decision becomes available.
These arguments do not work for targeted decisions; see Targeted Decisions: Warning for War.
Fixed random seed
Decisions, by default, use a fixed random seed. What this means is that such scopes as random_list or random_owned_controlled_state will pick the same thing each time that the decision is used, making a choice when the game starts. fixed_random_seed = no
will make sure that the random seed is dynamic, making it possible for a different outcome to happen.
Decision examples
QAT_category and BHR_category are assumed to already have been created within any /Hearts of Iron IV/common/decisions/categories/*.txt file.
QAT_category = { QAT_example = { allowed = { tag = QAT } icon = QAT_example #For GFX_decision_QAT_example fire_only_once = yes days_remove = 100 war_with_on_remove = BHR modifier = { training_time_factor = -0.3 } remove_effect = { create_wargoal = { target = BHR type = puppet_focus_wargoal } } cancel_trigger = { OMA = { is_subject_of = BHR } } cancel_effect = { BHR = { puppet = ROOT } } } }
BHR_category = { BHR_example = { allowed = { tag = BHR } visible = { has_war_with = QAT } available = { QAT = { surrender_progress > 0.5 } } icon = GFX_decision_BHR_example priority = 10 days_re_enable = 200 custom_cost_trigger = { has_command_power > 14 } custom_cost_text = decision_cost_CP_15 war_with_on_complete = OMA fixed_random_seed = no complete_effect = { hidden_effect = { add_command_power = -15 } annex_country = { target = QAT } random = { chance = 50 OMA = { load_oob = "OMA_prepared" } } declare_war_on = { target = OMA type = annex_everything } } } }
Missions
Missions are another type of decisions, activated when the triggers are true and requiring the player to do an action in order for the mission to have a positive outcome. These mostly use the same attributes as regular decisions, but there are some crucial differences. In particular:
days_mission_timeout = 123
is the amount of days that the mission will last for and is the attribute that turns a decision into a mission.timeout_effect = { ... }
are the effects that will be executed for the country if the timer runs out uninterrupted.available = { ... }
decides on triggers that make the mission possible to select, executingcomplete_effect
. Defaults to always being true, making it disappear instantly.selectable_mission = yes
, if set, turns the mission into one that where the player must select the button. If unset or set to false, then the complete effect will fire as soon asavailable
is true.activation = { ... }
decides on triggers that must be met for the decision to appear, assumingallowed
was true on the game's start. This is checked daily.visible = { ... }
does nothing and shouldn't be used in missions.- The
activate_mission = mission_name
effect can bypass bothallowed
andactivation
, and it's usually better-optimised to use it to make the decision appear instead of relying on it being done automatically.
- The
is_good = yes
changes the tooltips shown to the player on a non-selectable mission. By default or if set to false, the tooltip states that theavailable
will complete the mission, callingtimeout_effect
the effects if it's not completed. If set to true,complete_effect
will instead change to "Effects when failed". This is purely graphical and may be used to better communicate to the player whether they should seek to complete the prerequisites or to avoid them being true.war_with_on_timeout = TAG
will make the game assume that the mission, within itstimeout_effect = { ... }
will declare war on the specified country. This is used to make the AI prepare for a declaration of war and amass its troops on the border. This will also grant a notification to the target and all of its allies that a wargoal is being justified.
Other attributes, such as cancel_trigger
or cancel_effect
generally may be used inside of missions and should work how they do outside of them.
Mission example
my_mission = { activation = { has_civil_war = yes } available = { has_civil_war = no has_war = yes } cancel_trigger = { has_war = no } icon = mission_icon # For GFX_decision_mission_icon is_good = yes war_with_on_timeout = SOV days_mission_timeout = 100 selectable_mission = yes complete_effect = { add_ideas = my_idea } timeout_effect = { declare_war_on = { target = SOV type = annex_everything } } }
Targeted decisions
In addition to regular decisions that are taken by the country towards that same country, it is possible to make a decision be targeted towards a different country or group of countries. In that case, the decision will clone itself for each country that it gets targeted towards, putting the flag of the country in the bottom right of the decision's icon. The targeted country will be possible to reference in code using FROM, while ROOT is still the country that gets the decision. Despite what the names imply, FROM is the target of the decision rather than the country doing it.
fire_only_once
, in this case, will make the decision fire only once per each target country: a decision targeted towards BLR will not disappear if a decision of the same ID targered towards LIT gets completed.
Missions, as well as regular decisions, can be made targeted.
A decision becomes targeted if any way to check for a target is added within the decision:
Checking for target
There are several ways to limit the selection of targets. If any of these three is present in the decision, it will be marked as targeted.
The primary way to limit the selection to a select few countries is targets = { TAG TAG }
. In that case, if you want the game to check every country with that original tag (including civil war rebellions and other types of dynamic countries), then targets_dynamic = yes
line of code will ensure that the game will check more than the country that the country tag truly belongs to. Additionally, by default, it's impossible to target a non-existing country. The target_non_existing = yes
argument can be used to remove that restriction.
Additionally, it is possible to use arrays to limit a selection with target_array = array_name
, where the array must be assigned to the country. You can see a list of arrays automatically generated by the game here.
Together with any of the previous two ways or without them, target_trigger = { ... }
is a trigger block evaluated daily for both FROM and ROOT, if target_root_trigger
is evaluated as true.
For targeted decisions, target_root_trigger
is also possible to use, as a trigger block that continuously checks every day if allowed was met, required to make the decision or the entire category be visible in the decision selection screen. This checks only ROOT, being executed before target_trigger = { ... }
is. This exists for optimisation purposes, as it takes much less time to check the condition for one country daily than for every combination of countries.
Triggers overview
allowed = { ... }
checks the country that should get this decision and only checks upon the game's start or when reloading decisions such as by loading a savegame. If false, the decision is permamently disabled.target_root_trigger = { ... }
checks the country the country that should get this decision, every day. If false, the decision will not appear until the next daily check. Despite only checking one country, this still makes the decision targeted.target_trigger = { ... }
checks any countries (or states) that meettargets = { ... }
andtarget_array = array_name
, if they're present. In here, ROOT (default scope) is the country that gets the decision and FROM is the potential target of the decision. This is checked daily, making the decision not appear until the next day's check if false. Putting this automatically makes the decision targeted.visible = { ... }
andavailable = { ... }
are checked every tick. If the decision is targeted, then FROM is checked alongside ROOT, otherwise only ROOT is checked.
Warning for war
The regular arguments of war_with_on_
do not work if using FROM as a target. Instead, there are alternatives for targeted decisions specifically:
war_with_target_on_complete = yes
- Equivalent to war_with_on_complete = FROM
war_with_target_on_remove = yes
- Equivalent to war_with_on_remove = FROM
war_with_target_on_timeout = yes
- Equivalent to war_with_on_timeout = FROM
Additional note
Similarly to missions, the activate_targeted_decision = { target = TAG decision = my_decision }
effect exists. If possible, it is recommended to use this effect instead of letting it automatically activate, making it never allowed. For instance, if the targeted decision activates by being at war with a country, on_war_relation_added in on_actions can be used to activate it instead of using target_array = enemies
.
Targeted decision example
my_targeted_decision = { target_root_trigger = { has_completed_focus = my_focus } targets = { BHR QAT SAU OMA YEM IRQ SYR LEB ISR PAL } targets_dynamic = yes target_trigger = { FROM = { has_idea = my_idea } } icon = my_icon cost = 20 war_with_target_on_complete = yes complete_effect = { create_wargoal = { target = FROM type = annex_everything } } }
State targeted decisions
If the decision has state_target = yes
then, instead, it'll be targeted towards a state. Possible values are: yes, no, any, any_owned_state, any_controlled_state, continent_key (europe, africa, north_america...). This will only have an effect if no 'targets' are specified, else this should be set to 'any' (or 'yes') if targets are used. Unless omitted or set to "no", makes the decision a state targeted decision. Which states will be checked depends on value:
- any (or yes): will check every state in the game against the 'target_trigger'. To be avoided whenever possible as this is expensive performance wise.
- any_owned_state: will check every state owned by the country. This is equivalent (but quite faster) to adding 'owner = ROOT' in the target_trigger.
- any_controlled_state: will check every state controlled by the country. This is equivalent (but quite faster) to adding 'is_controlled_by = ROOT' in the target_trigger.
- continent_key (europe, africa, north_america...): will check every state in the continent. This is equivalent (but quite faster) to adding 'is_on_continent = xxx' in the target_trigger.
Targeting still works the same way, with it having FROM as a state scope instead. targets
becomes targets = { 123 321 }
or, in case of one state total, targets = { state = 123 }
can be used as well.
Decisions targeted towards states will have the icon appear over the states while the decision menu is open. To prevent confusion, a map area can be added to the decision category.
Additionally, The argument on_map_mode
will determine where the targeted decisions appear in.
on_map_mode = map_only
will make the targeted decisions only appear on the map.
on_map_mode = decision_view_only
will make the targeted decisions only appear in the decisions menu.
on_map_mode = map_and_decisions_view
will make the targeted decisions appear on both the map and the decisions menu.
Example
my_state_targeted_decision = { state_target = yes target_root_trigger = { has_completed_focus = my_focus } target_array = GER.core_states target_trigger = { FROM = { is_owned_by = ROOT } } on_map_mode = map_and_decisions_view icon = my_icon cost = 20 complete_effect = { FROM = { remove_core_of = GER } } }
文件 | 效果 • 条件 • 定义 • 修正 • 修正列表 • 作用域 • 本地化 • on action • 数据结构 (标记, 临时标记, 国家别名, 变量, 数组) |
脚本 | 成就修改 • AI修改 • AI focuses • 自治领修改 • 权力平衡修改 • 剧本/标签 (游戏规则)• 建筑修改 • 人物修改 • 修饰性TAG修改 • 国家创建 • 军队修改 • 决议制作 • 装备修改 • 事件修改 • Idea修改 • 意识形态修改 • 军工商修改 • 国策制作 • 资源修改 • Scripted GUI • 科技制作 • 单位修改 |
地图 | 地图 • 省份 • 补给区域 • 战略区域 |
图形图像 | 界面 • 图形资产 • 实体模型 • 后期特效 • 离子效果 • 字体 |
装饰性 | 肖像 • 命名列表 • 音乐 • 音效 |
其他 | 控制台指令 • 故障排除 • 模组结构 • 成就代码分析 • Mod相关 • Nudger修改 |