Balance of power modding:修订间差异

本页面所适用的版本可能已经过时,最后更新于1.13
(20230313-创建-更新为当前时间最新版本)
 
无编辑摘要
 
(未显示同一用户的2个中间版本)
第1行: 第1行:
{{Version|1.12}}
{{Version|1.13}}
In Vanilla, '''Balance of powers''' are used to represent a conflict between two sides through a progress bar divided into distinct sections. The main functionality of Balance of power, also referred to as Bop or powerbalance in code, is located in <code>/Hearts of Iron IV/common/bop/*.txt</code>.
{{需要翻译|译者=霜泽图书馆}}
A '''balance of power''' (also internally referred to as bop or power balance) is typically used to represent a conflict between two sides, using a progress bar divided into distinct sections and decisions to push it towards some side for benefits. These are defined in {{path|common/bop/*.txt}} files.
__TOC__
Each balance of power consists of 2 or more sides. While a balance of power can contain more than 2 sides, at any time the player may only see 2 which are chosen in the effect to initialise the balance of power.<br/>
To track the current balance, a single value is used, which can range from -1 to 1 with up to 3 decimal points. The <math>[-1; 0)</math> range is used for the left side, <math>[0; 1]</math> is used for the right side. A side having power only has a cosmetic impact, changing the icon and the text used in scripted localisation. A side isn't inherently set as being left or right, instead it is assigned which side is on which half when the power balance is initialised.


=== Basics ===
Depending on the value, the country is placed in some range representing the exact degree of power on a certain side. This is usually used to grant certain [[modifiers]] or to execute an [[effect]] upon entering it. Most ranges are placed inside of sides, making it only possible to enter when that side is active. A range may also not be assigned to any side and be always visible, usually used for a single "balanced" range in the middle.<br/>
A range being assigned to a side only means that it'll be visible when the range is active, and a side may have ranges on both halves of the balance at the same time. Entering a range defined on a certain side does not necessitate that the balance is tipped in favour of that side. For example, if a side is set as a left side and yet it includes a range of <math>[0.1, 0.3)</math>, then if the value is at 0.2, then the balance will be tipped towards the right side visually, but it will still be inside of that range.


A Balance of power consists of two sides, which sit on opposite sides of a progress bar. By changing a [[Data_Structures#Variables|variables]] in the Bop, a cursor is moved towards one of the two sides. The value ''1'' describes the maximum value in the Bop to the right side. The left side includes all values up to ''-1'', ''0'' being the equilibrium. A modder can include a [[Decision_modding#Arguments_for_decisions_and_categories|decision category]] in the Bop that supports the same functions as a regular [[Decision_modding#Arguments_for_decisions_and_categories|decision category]]. The progressbar, which can be seen at the top of the Bop menu, can be divided into different sections, so-called ranges. Ranges can trigger different continuous or one-time [[Effect|effects]] when they are activated.
'''A balance of power is tracked globally.''' If 2 countries are assigned the same BoP, then the value of the balance will always be exactly the same between both countries. If both of these countries have modifiers pushing the BoP to some side daily or weekly, the effects of these modifiers will stack.
== Code structure ==
Balances of power are created in any {{path|common/bop/*.txt}} file. A BoP is defined as a root-level block, where the name of the block determines the unique ID of the BoP. In case of duplicates, the error.log entry <code>Template ID duplicate: bop_name</code> is generated and the game will prioritise the one that was [[Modding#Code structure|created later]], determined using the filename and order in files.<br/>
There are no strictly mandatory arguments, however it is preferred to have at least 2 sides as the UI is built on the assumption that there is always a left and a right side active. In particular, these arguments exist:


=== Structure ===
* <code>intial_value = -0.1</code> is the default value of the BoP. If unset, defaults to 0.
==== Balance of power ====
* <code>left_side = side_id</code> is the default left side of the BoP.
* <code>right_side = side_id</code> is the default right side of the BoP.
The default values are used when the BoP is first initialised with [[#set_power_balance|set_power_balance]] (unless overwritten by its arguments) or when that same effect includes <code>set_default = yes</code> to reset it.
* <code>decision_category = TAG_example_category</code> will move that [[decision]] category to the balance of power view. In particular, this ensures that it's impossible to access the decision category in any way other than by the balance of power. Any trigger blocks in the decision category, such as <code>allowed = { ... }</code>, are still checked for the country with the BoP, however.
In addition, <code>side = { ... }</code> and <code>range = { ... }</code> are possible with more detail.
=== Side ===
Each side is defined using a <code>side = { ... }</code> block in the balance of power. In particular, these arguments exist:
* <code>id = side_id</code> is the identifier used for the side. There should not be overlap in the same BoP, however overlap may exist between different BoPs. In case of overlap in the same BoP, only the first-created side will be used with a <code>Side ID duplicate: side_id</code> entry in error.log.
* <code>icon = GFX_idea_unknown</code> is the spriteType used as the image to represent the side. If undefined or if the spriteType doesn't exist, the icon will not be created with no default to replace it.
{| class="wikitable mw-collapsible"
!General sprite overview
|-
|For loading GFX, the game uses the sprite system. Sprites are code definitions that attach a name to an image file, as well as optionally adding additional information, such as animation, the amount of frames, the way that the image will be loaded, and so on. This means '''placing an image into the gfx folder isn't enough for it to work''', a sprite has to use that image file as well.
Sprites are defined in any /Hearts of Iron IV/interface/*.gfx file (this is separate from gfx/interface/), opened with a text editor. To create a new .gfx file, a text file can be created and renamed to change the extension (on Windows, the Windows Explorer needs to show the extensions, which it doesn't by default). In particular, sprites are defined within a <code>spriteTypes = { ... }</code> block, as to separate from fonts and map arrows also defined in that folder, while the simplest sprite with the least mandatory properties is a <code>spriteType = { ... }</code>. The simplest sprite definition looks like the following:
spriteTypes = {
   spriteType = {
     name = GFX_first_sprite             # In some cases, beginning with GFX_ is mandatory for it to work.
     texturefile = gfx/interface/folder/filename.dds # The folder and filename don't matter, as long as they are correct
   }                          # Only the forward slash '/' (can be doubled as '//') can be used to separate folders.
   spriteType = {                    # The image doesn't have to be .dds, as .tga and .png are acceptable.
     name = GFX_second_sprite
     texturefile = gfx/interface/folder2/filename2.dds
     noOfFrames = 2 # Splits the image into 2 halves, which may be switched between dynamically in GUI
   }
}
In this case, this creates a sprite with the name of <code>GFX_first_sprite</code> and attaches the /Hearts of Iron IV/gfx/interface/folder/filename.dds image to it, and a second sprite similarly. The second sprite will be split into 2 frames: this is decided by having the left half of the image as the first frame and the right half as the second frame (more frames would further split the image horizontally). This doesn't make the sprite animated, just turns on the option to switch between the two halves as needed. <code>GFX_second_sprite:1</code> serves as a reference to the first frame, and GUI can be set up to change the shown frame depending on context, such as with radio stations.


A Balance of power is defined using <code>TAG_example_balance = { ... }</code> syntax. The name of the Bop is used to identify it in code.
In order to add animation, a frameAnimatedSpriteType is used.


The following arguments are mandatory:
'''It's never mandatory to copy a base game file to change a sprite'''. If there are duplicate definitions of a sprite with the same name in different files, the game will prioritise the one that would be evaluated later, based on the filename, and the older sprite will be ignored in entirety. This can be ensured by beginning the replacement file's name with a symbol late in the ASCII character table. Typically the lowercase letter 'z' is used for this purpose. For example, to change the amount of frames in <code>GFX_idea_traits_strip</code> to 10, it is possible to define a sprite with that name with 10 frames in the mod's modname/interface/zz_replace.gfx file instead of copying over the base game file.


<code>intial_value = ...</code> Is for the starting value of the Bop. The value has to be between ''-1'' and ''1''.
Since most .gfx files define integral parts of the user interface, copying them over can lead to the mod's loaded files missing sprites upon a major game update, which would appear in-game as the default image, which is the error dog by default. As to ease the burden of needing to check the interface files, it's best to never copy over .gfx files, unless more additions would be actively harmful to the mod, such as with interface/subuniticons.gfx
 
|}
The sides of the Bop are defined as <code>right_side = ...</code> and <code>left_side = ...</code>. The names need to be unique as they are used to identify the sides in code.
* <code>range = { ... }</code> is a range set to exist if and only if that side is active.
 
=== Range ===
<code>decision_category = TAG_example_category</code> makes the decision_category appear in the Bop menu.
A range is defined as a <code>range = { ... }</code> block which may exist either directly in the BoP or inside of a <code>side = { ... }</code>. This is used to determine when the range will be visible to the player: a range directly in a BoP is always visible, while a range in a side will only be visible if that side is visible. There are 3 mandatory attributes:
 
* <code>id = range_id</code> is used to assign an ID to the specified range. There shouldn't be duplicates across the entire BoP (even in different sides), but there may be between different BoPs. A duplicate will be marked with a <code>Range ID duplicate: range_id</code> entry in error.log. In this case, the game will still display each range with the same ID that is not in a disabled side. However, this can cause issues with strict non-equal comparison when using [[#is_power_balance_in_range|is_power_balance_in_range]]: in particular, the game will only recognise the range that's placed furthest to the left. For example, if there are duplicate <code>range_id</code> on intervals of <math>[-0.3, -0.1)</math> and <math>[0.1, 0.3)</math>, then a strict equilibrium will be recognised as being to the right of <code>range_id</code>, but not to the left of it.
==== Side ====
* <code>min = -0.1</code> is the minimum value in the range's interval. If the value is exactly at this point, this range will be applied.
 
* <code>max = 0.1</code> is the maximum value in the range's interval. If the value is exactly at this point, this range will be applied if and only if max is set to 1. Otherwise, the exact point is excluded from the interval.
Each Bop needs two sides, which are defined with <code>side = { ... }</code>. Each side requires a unique <code>id = ...</code> and <code>icon = GFX_TAG_example_bop_icon</code>. A side can then be divided into any number of ranges. However, the ranges must not overlap.
 
==== Range ====
 
Any range requires a unique <code>id = ...</code> as well as a <code>min</code> and <code>max value</code>. The values are used to determine which range is active at any given moment.
 
The effects of a range are scripted in the <code>modifier = { ... }</code> block. (Modifiers) Furthermore, effects can also be specified that are executed when the specific range is activated or deactivated. This can be achieved through the usage of <code>on_activate = { ... }</code> and <code>on_deactivate = { ... }</code>.


There are also blocks that decide which impact exactly a range has on the country when the value is inside that. In particular:
* <code>modifier = { ... }</code> decides on the [[modifiers]] applying to the country when the value is in that range.
* <code>rule = { ... }</code> decides on the [[Effect#set_rule|game rules]] applying to the country when the value is in that range.
* <code>on_activate = { ... }</code> executes [[effects]] the instant that the value enters this range.
* <code>on_deactivate = { ... }</code> executes [[effects]] the instant that the value exits this range.


=== Example ===
=== Example ===
<pre>
<pre>TAG_example_balance = {
TAG_example_balance = {
     initial_value = 0.25
     initial_value = 0.25
     left_side = default_left_side
     left_side = default_left_side
第43行: 第73行:
         modifier = {
         modifier = {
             war_support_weekly = 0.5
             war_support_weekly = 0.5
        }
        rule = {
            can_create_faction = yes
         }
         }
     }
     }
第55行: 第88行:
             modifier = {
             modifier = {
                 war_support_weekly = 0.1
                 war_support_weekly = 0.1
            }
            on_activate = {
                random_owned_controlled_state = {
           limit = {
             NOT = { is_core_of = PREV }
           }
           add_core_of = PREV
           set_state_flag = cored_by_bop
         }
            }
            on_deactivate = {
                random_owned_controlled_state = {
           limit = {
             has_state_flag = cored_by_bop
           }
           remove_core_of = PREV
           clr_state_flag = cored_by_bop
         }
             }
             }
         }
         }
     }
     }
     side = {
     side = {
         id = default_right_side
         id = default_right_side
第71行: 第121行:
         }
         }
     }
     }
}
}</pre>
</pre>
 
== Implementation ==
{{Anchor|set_power_balance}}
As a balance of power isn't inherently assigned to any country, it must be manually initialised. This is done using the <code>set_power_balance</code> [[effect]]. For example, this is the most bare-bones way to initialise the BoP, which will set it to the default:
<pre>set_power_balance = {
   id = TAG_example_balance
}</pre>
The effect can also be used to change details about the currently-active balance of power, such as changing the sides or the value:
<pre>set_power_balance = {
   id = TAG_example_balance
   left_side = default_left_side
   right_side = default_right_side
   set_value = 0.1
}</pre>
If necessary to reset it completely to the default, <code>set_default = yes</code> will do so.
<pre>set_power_balance = {
   id = TAG_example_balance
   set_default = yes
}</pre>


=== Modifying a Balance of Power ===
As an effect, it can be used in any effect block. If it should be initialised at the game's start, this is usually done in [[Country creation#Country history|country history]], alternatively it can be initialised when needed, such as in a focus reward or an event option.


There are two main ways of adding to or subtracting from a Balance of power. One can either add a flat value through an effect or apply a modifier for continuous Bop change.
== Balance of power modifiers ==
{{See also|Modifiers|Static modifiers|section=yes}}
Balance of power modifiers are [[static modifiers]] that are applied directly to a balance of power, from which they are cloned to each country that has the BoP assigned. As static modifiers, they're defined in any {{path|common/modifiers/*.txt}} file. They typically include within of themselves only the [[Modifiers#power_balance_daily|power_balance_daily]] and/or [[Modifiers#power_balance_weekly|power_balance_weekly]] modifiers in order to gradually tip the balance towards one side. These modifiers will be shown in the tooltip when hovering over the current value.


==== Effect ====
An example of a BoP modifier is as such:
<pre>my_bop_modifier = {
   power_balance_weekly = -0.01 # Changes by 1% each week to the left
}</pre>
Balance of power modifiers are added via [[#add_power_balance_modifier|the add_power_balance_modifier effect]] as such:
<pre>add_power_balance_modifier = {
   id = my_bop   # The ID of the balance of power
   modifier = my_bop_modifier # The modifier to add
}</pre>[[#remove_power_balance_modifier|The remove_power_balance_modifier effect]], with the same syntax, or [[#remove_all_power_balance_modifiers|remove_all_power_balance_modifiers]] can be used to remove these from the country.


The effect <code>add_power_balance_value = { ... }</code> requires the name of the power balance, for example <code>TAG_example_balance</code> and a value between ''-1'' and ''1''.
Since these are duplicated to each country that has the BoP, the weekly or daily effect for each modifier will increase for each country that is assigned the BoP. For example, if the BoP is assigned to 3 countries, <code>power_balance_daily = 0.01</code> in a BoP modifier will, in practice, make the balance get pushed by 3% to the right in total daily.
<pre>
add_power_balance_value = {
   id = TAG_example_balance
   value = -0.25
}
</pre>
==== Bop Modifier ====


A Bop modifier is defined within common/modifiers/*.txt with the following syntax:
== Effects ==
<pre>
{{Hatnote|Parts of this section are transcluded from {{Section link|Effect|Balance of power}}.}}
TAG_example_balance_modifier = {
Other than <code>set_power_balance</code>, these effects exist which can be used to modify a balance of power:
   power_balance_daily = 0.05
{{#section-h:Effect|Balance of power}}
}
</pre>
Another valid argument would be power_balance_weekly = -0.005.


Bop modifiers can be applied or removed with the effect <code>add_power_balance_modifier = { ... }</code> and <code>remove_power_balance_modifier = { ... }</code>.
== Triggers ==
{{Hatnote|Parts of this section are transcluded from {{Section link|Triggers|Balance of power}}.}}
These triggers exist for checking the state of a balance of power. Some of these can only be used in country scope.{{#section-h:Triggers|Balance of power}}


{{Modding navbox}}
{{Modding navbox}}
[[Category:Modding]]
[[Category:Modding]]

2024年8月10日 (六) 01:55的最新版本

A balance of power (also internally referred to as bop or power balance) is typically used to represent a conflict between two sides, using a progress bar divided into distinct sections and decisions to push it towards some side for benefits. These are defined in /Hearts of Iron IV/common/bop/*.txt files.

Each balance of power consists of 2 or more sides. While a balance of power can contain more than 2 sides, at any time the player may only see 2 which are chosen in the effect to initialise the balance of power.
To track the current balance, a single value is used, which can range from -1 to 1 with up to 3 decimal points. The [math]\displaystyle{ [-1; 0) }[/math] range is used for the left side, [math]\displaystyle{ [0; 1] }[/math] is used for the right side. A side having power only has a cosmetic impact, changing the icon and the text used in scripted localisation. A side isn't inherently set as being left or right, instead it is assigned which side is on which half when the power balance is initialised.

Depending on the value, the country is placed in some range representing the exact degree of power on a certain side. This is usually used to grant certain modifiers or to execute an effect upon entering it. Most ranges are placed inside of sides, making it only possible to enter when that side is active. A range may also not be assigned to any side and be always visible, usually used for a single "balanced" range in the middle.
A range being assigned to a side only means that it'll be visible when the range is active, and a side may have ranges on both halves of the balance at the same time. Entering a range defined on a certain side does not necessitate that the balance is tipped in favour of that side. For example, if a side is set as a left side and yet it includes a range of [math]\displaystyle{ [0.1, 0.3) }[/math], then if the value is at 0.2, then the balance will be tipped towards the right side visually, but it will still be inside of that range.

A balance of power is tracked globally. If 2 countries are assigned the same BoP, then the value of the balance will always be exactly the same between both countries. If both of these countries have modifiers pushing the BoP to some side daily or weekly, the effects of these modifiers will stack.

Code structure

Balances of power are created in any /Hearts of Iron IV/common/bop/*.txt file. A BoP is defined as a root-level block, where the name of the block determines the unique ID of the BoP. In case of duplicates, the error.log entry Template ID duplicate: bop_name is generated and the game will prioritise the one that was created later, determined using the filename and order in files.
There are no strictly mandatory arguments, however it is preferred to have at least 2 sides as the UI is built on the assumption that there is always a left and a right side active. In particular, these arguments exist:

  • intial_value = -0.1 is the default value of the BoP. If unset, defaults to 0.
  • left_side = side_id is the default left side of the BoP.
  • right_side = side_id is the default right side of the BoP.

The default values are used when the BoP is first initialised with set_power_balance (unless overwritten by its arguments) or when that same effect includes set_default = yes to reset it.

  • decision_category = TAG_example_category will move that decision category to the balance of power view. In particular, this ensures that it's impossible to access the decision category in any way other than by the balance of power. Any trigger blocks in the decision category, such as allowed = { ... }, are still checked for the country with the BoP, however.

In addition, side = { ... } and range = { ... } are possible with more detail.

Side

Each side is defined using a side = { ... } block in the balance of power. In particular, these arguments exist:

  • id = side_id is the identifier used for the side. There should not be overlap in the same BoP, however overlap may exist between different BoPs. In case of overlap in the same BoP, only the first-created side will be used with a Side ID duplicate: side_id entry in error.log.
  • icon = GFX_idea_unknown is the spriteType used as the image to represent the side. If undefined or if the spriteType doesn't exist, the icon will not be created with no default to replace it.
General sprite overview
For loading GFX, the game uses the sprite system. Sprites are code definitions that attach a name to an image file, as well as optionally adding additional information, such as animation, the amount of frames, the way that the image will be loaded, and so on. This means placing an image into the gfx folder isn't enough for it to work, a sprite has to use that image file as well.

Sprites are defined in any /Hearts of Iron IV/interface/*.gfx file (this is separate from gfx/interface/), opened with a text editor. To create a new .gfx file, a text file can be created and renamed to change the extension (on Windows, the Windows Explorer needs to show the extensions, which it doesn't by default). In particular, sprites are defined within a spriteTypes = { ... } block, as to separate from fonts and map arrows also defined in that folder, while the simplest sprite with the least mandatory properties is a spriteType = { ... }. The simplest sprite definition looks like the following:

spriteTypes = {
    spriteType = {
        name = GFX_first_sprite                         # In some cases, beginning with GFX_ is mandatory for it to work.
        texturefile = gfx/interface/folder/filename.dds # The folder and filename don't matter, as long as they are correct
    }                                                   # Only the forward slash '/' (can be doubled as '//') can be used to separate folders.
    spriteType = {                                      # The image doesn't have to be .dds, as .tga and .png are acceptable.
        name = GFX_second_sprite
        texturefile = gfx/interface/folder2/filename2.dds
        noOfFrames = 2 # Splits the image into 2 halves, which may be switched between dynamically in GUI
    }
}

In this case, this creates a sprite with the name of GFX_first_sprite and attaches the /Hearts of Iron IV/gfx/interface/folder/filename.dds image to it, and a second sprite similarly. The second sprite will be split into 2 frames: this is decided by having the left half of the image as the first frame and the right half as the second frame (more frames would further split the image horizontally). This doesn't make the sprite animated, just turns on the option to switch between the two halves as needed. GFX_second_sprite:1 serves as a reference to the first frame, and GUI can be set up to change the shown frame depending on context, such as with radio stations.

In order to add animation, a frameAnimatedSpriteType is used.

It's never mandatory to copy a base game file to change a sprite. If there are duplicate definitions of a sprite with the same name in different files, the game will prioritise the one that would be evaluated later, based on the filename, and the older sprite will be ignored in entirety. This can be ensured by beginning the replacement file's name with a symbol late in the ASCII character table. Typically the lowercase letter 'z' is used for this purpose. For example, to change the amount of frames in GFX_idea_traits_strip to 10, it is possible to define a sprite with that name with 10 frames in the mod's modname/interface/zz_replace.gfx file instead of copying over the base game file.

Since most .gfx files define integral parts of the user interface, copying them over can lead to the mod's loaded files missing sprites upon a major game update, which would appear in-game as the default image, which is the error dog by default. As to ease the burden of needing to check the interface files, it's best to never copy over .gfx files, unless more additions would be actively harmful to the mod, such as with interface/subuniticons.gfx

  • range = { ... } is a range set to exist if and only if that side is active.

Range

A range is defined as a range = { ... } block which may exist either directly in the BoP or inside of a side = { ... }. This is used to determine when the range will be visible to the player: a range directly in a BoP is always visible, while a range in a side will only be visible if that side is visible. There are 3 mandatory attributes:

  • id = range_id is used to assign an ID to the specified range. There shouldn't be duplicates across the entire BoP (even in different sides), but there may be between different BoPs. A duplicate will be marked with a Range ID duplicate: range_id entry in error.log. In this case, the game will still display each range with the same ID that is not in a disabled side. However, this can cause issues with strict non-equal comparison when using is_power_balance_in_range: in particular, the game will only recognise the range that's placed furthest to the left. For example, if there are duplicate range_id on intervals of [math]\displaystyle{ [-0.3, -0.1) }[/math] and [math]\displaystyle{ [0.1, 0.3) }[/math], then a strict equilibrium will be recognised as being to the right of range_id, but not to the left of it.
  • min = -0.1 is the minimum value in the range's interval. If the value is exactly at this point, this range will be applied.
  • max = 0.1 is the maximum value in the range's interval. If the value is exactly at this point, this range will be applied if and only if max is set to 1. Otherwise, the exact point is excluded from the interval.

There are also blocks that decide which impact exactly a range has on the country when the value is inside that. In particular:

  • modifier = { ... } decides on the modifiers applying to the country when the value is in that range.
  • rule = { ... } decides on the game rules applying to the country when the value is in that range.
  • on_activate = { ... } executes effects the instant that the value enters this range.
  • on_deactivate = { ... } executes effects the instant that the value exits this range.

Example

TAG_example_balance = {
    initial_value = 0.25
    left_side = default_left_side
    right_side = default_right_side
    decision_category = TAG_example_category
    range = {
        id = mid_range
        min = -0.1
        max = 0.1
        modifier = {
            war_support_weekly = 0.5
        }
        rule = {
            can_create_faction = yes
        }
    }

    side = {
        id = default_left_side
        icon = GFX_idea_generic_agrarian_society
        range = {
            id = left_side_range
            min = -1
            max = -0.1
            modifier = {
                war_support_weekly = 0.1
            }
            on_activate = {
                random_owned_controlled_state = {
                    limit = {
                        NOT = { is_core_of = PREV }
                    }
                    add_core_of = PREV
                    set_state_flag = cored_by_bop
                }
            }
            on_deactivate = {
                random_owned_controlled_state = {
                    limit = {
                        has_state_flag = cored_by_bop
                    }
                    remove_core_of = PREV
                    clr_state_flag = cored_by_bop
                }
            }
        }
    }
    side = {
        id = default_right_side
        icon = GFX_idea_generic_degauss_ship_hulls
        range = {
            id = right_side_range
            min = 0.1
            max = 1
            modifier = {
                war_support_weekly = 0.9
            }
        }
    }
}

Implementation

As a balance of power isn't inherently assigned to any country, it must be manually initialised. This is done using the set_power_balance effect. For example, this is the most bare-bones way to initialise the BoP, which will set it to the default:

set_power_balance = {
    id = TAG_example_balance
}

The effect can also be used to change details about the currently-active balance of power, such as changing the sides or the value:

set_power_balance = {
    id = TAG_example_balance
    left_side = default_left_side
    right_side = default_right_side
    set_value = 0.1
}

If necessary to reset it completely to the default, set_default = yes will do so.

set_power_balance = {
    id = TAG_example_balance
    set_default = yes
}

As an effect, it can be used in any effect block. If it should be initialised at the game's start, this is usually done in country history, alternatively it can be initialised when needed, such as in a focus reward or an event option.

Balance of power modifiers

参见:Modifiers

Balance of power modifiers are static modifiers that are applied directly to a balance of power, from which they are cloned to each country that has the BoP assigned. As static modifiers, they're defined in any /Hearts of Iron IV/common/modifiers/*.txt file. They typically include within of themselves only the power_balance_daily and/or power_balance_weekly modifiers in order to gradually tip the balance towards one side. These modifiers will be shown in the tooltip when hovering over the current value.

An example of a BoP modifier is as such:

my_bop_modifier = {
    power_balance_weekly = -0.01 # Changes by 1% each week to the left
}

Balance of power modifiers are added via the add_power_balance_modifier effect as such:

add_power_balance_modifier = {
    id = my_bop    # The ID of the balance of power
    modifier = my_bop_modifier # The modifier to add
}

The remove_power_balance_modifier effect, with the same syntax, or remove_all_power_balance_modifiers can be used to remove these from the country.

Since these are duplicated to each country that has the BoP, the weekly or daily effect for each modifier will increase for each country that is assigned the BoP. For example, if the BoP is assigned to 3 countries, power_balance_daily = 0.01 in a BoP modifier will, in practice, make the balance get pushed by 3% to the right in total daily.

Effects

Parts of this section are transcluded from Effect § Balance of power.

Other than set_power_balance, these effects exist which can be used to modify a balance of power:


Balance of power-related country-scoped effects:
Name Parameters Examples Description Notes Version Added
remove_power_balance id = <BoP ID>
Balance of power to modify.
remove_power_balance = {
    id = my_bop
}
Removes the balance of power in entirety. 1.12
add_power_balance_value id = <BoP ID>
Balance of power to modify.

value = <decimal>
The value to add.
tooltip_side = <BoP side ID>
The side to show in the tooltip. Optional.

add_power_balance_value = {
    id = my_bop
    value = -0.1
    tooltip_side = my_bop_side
}
Pushes the balance of power towards one side. 1.12
add_power_balance_modifier id = <BoP ID>
Balance of power to modify.

modifier = <static modifier>
The static modifier to apply.

add_power_balance_modifier = {
    id = my_bop
    modifier = my_static_modifier
}
Applies a balance of power modifier. 1.12
remove_power_balance_modifier id = <BoP ID>
Balance of power to modify.

modifier = <static modifier>
The static modifier to apply.

remove_power_balance_modifier = {
    id = my_bop
    modifier = my_static_modifier
}
Cancels a balance of power modifier. 1.12
remove_all_power_balance_modifiers id = <BoP ID>
Balance of power to modify.
remove_all_power_balance_modifiers = {
    id = my_bop
}
Cancels all balance of power modifiers. 1.12
set_power_balance_gfx id = <BoP ID>
Balance of power to modify.

side = <BoP side ID>
The side whose GFX to change.
gfx = <sprite>
The sprite to change the GFX to.

set_power_balance_gfx = {
    id = my_bop
    side = my_bop_side
    gfx = GFX_my_bop_side_new
}
Changes the appearance of one of the sides within the balance of power. Sprites are defined within /Hearts of Iron IV/interface/*.gfx files. 1.12


Triggers

Parts of this section are transcluded from Triggers § Balance of power.

These triggers exist for checking the state of a balance of power. Some of these can only be used in country scope.

Balance of power-related country-scoped triggers:
Name Parameters Examples Description Notes Version Added
has_power_balance id = <bop ID>
The balance to check for.
has_power_balance = {
    id = TAG_my_bop
}
Checks if the current scope has the specified balance of power active. 1.12
has_any_power_balance <bool>
Boolean.
has_any_power_balance = yes
Checks if the current scope has any balance of power active. 1.12
power_balance_value id = <bop ID>
The balance to check in.

value = <float>
The value to check for.

power_balance_value = {
    id = TAG_my_bop
    value > 0.7
}
Checks if the current scope has the specified value within the balance of power. Either =, >, or < operators are allowed. 1.12
power_balance_daily_change id = <bop ID>
The balance to check in.

value = <float>
The value to check for.

power_balance_daily_change = {
    id = TAG_my_bop
    value < -0.01
}
Checks if the current scope's balance of power changes each day by the specified value. Either =, >, or < operators are allowed. 1.12
power_balance_weekly_change id = <bop ID>
The balance to check in.

value = <float>
The value to check for.

power_balance_weekly_change = {
    id = TAG_my_bop
    value < -0.01
}
Checks if the current scope's balance of power changes each week by the specified value. Either =, >, or < operators are allowed. 1.12
is_power_balance_in_range id = <bop ID>
The balance to check in.

range = <range ID>
The range to check for.

is_power_balance_in_range = {
    id = TAG_my_bop
    range > TAG_my_bop_right_range
}
Checks if the current scope's balance of power value lies within the specified range. Ranges are defined within the balance of power. Can use either =, >, and < operators. In case of > or <, the comparison is 'strict', i.e. excluding the range itself. 1.12
is_power_balance_side_active id = <bop ID>
The balance to check in.

side = <side ID>
The side to check.

is_power_balance_side_active = {
    id = TAG_my_bop
    side = TAG_my_bop_right_range
}
Checks if the specified balance of power has a side active. Sides are defined within the balance of power. "Active" means that the side is among those that are currently visible instead of relying on the current value. 1.12
has_power_balance_modifier id = <bop ID>
The balance to check in.

modifier = <modifier ID>
The static modifier.

has_power_balance_modifier = {
    id = TAG_my_bop
    modifier = TAG_my_bop_modifier
}
Checks if the current scope's balance of power value activates a modifier. BoP modifiers are defined within /Hearts of Iron IV/common/modifiers/*.txt files, while they're activated in the balance of power definition. 1.12