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

HOI4 Dev Diary - Modding and Traits

Hi everyone! Todays dev diary will be a 3 meal course. First we are going to be talking about the new admiral traits in Man the Guns, then we will be showing off some new modding toys, and finally there will be an extra dessert in the form of more modding stuff posted here in the modding forum. Hope it’s to your tastes :)

Admiral Traits
With Man the Guns following Waking the Tiger and focusing on the naval aspects of the game we knew we wanted to give Admirals more progression and traits as well as new skills. Going over all the traits is going to be spoiling a bunch of upcoming stuff as well, so you will need to be patient with the details on some of that ;)

We have expanded the single skill level of Admirals in a similar way to how we did Generals in WTT, so there are now 4 traits to better reflect their skills and personality: Attack, Defense, Manoeuvring and Coordination. Attack and Defense are pretty straight forward. Maneuvering is the more tactical skill that will matter for fleet positioning and movement while Coordination is the more organizational skill and affects missions and other things outside combat more. We’ll be covering these in more detail once we start breaking down fleets, task forces and combat.

Admirals will now get access to more earnable traits as well as personality traits. Some personality traits carry over from Generals, like Career Officer as well as new ones like Battleship Adherent. There are also assignable traits you can unlock and tailor your admirals. Finally there are terrain traits which are earnable and help in different naval terrain (see future diary for details). As admirals level up they gain 3 points across their skills for each level, more likely in their strong points. Every second level they also unlock the slots needed for assigned traits similar to how it works for generals. The assignable traits and admiral screen will be in Man the Guns while the base stuff like personality traits and earnable traits will be in the free patch. So just like with Waking the Tiger’s general traits.
commanders.jpg


Here is the whole trait tree:
traits.jpg


As you can see most traits will have dependencies on having earned traits first.

There are stuff like Ironside if you want to focus on powerful capital ships, Air Controller for carrier abilities as well as things like Blockade Runner, Concealment Expert and Silent Hunter for raiders. There are also paths for improving the use of lighter ships under Flyswatter and Fleet Protector. This matters because light ships are going to get a whole lot more necessary for your fleets and naval operations.


Modding!
Hello everyone! @shultays here. I am a programmer in HoI4 team and I have exciting updates for all our modders and for the players that enjoy their mods! In this dev diary I will introduce a couple new scripting features that will be especially appealing for our modders. It is a bit early for such tech dev diary but we wanted some feedback on those features, and also have enough time to iterate on such feedback.

I will give short descriptions and small examples here, more in-depth stuff can be found in my other post that I made in modding forums.

Arrays

The people with programming experience are already familiar with the concept of arrays. For those who are not, arrays are basically containers of data. In HoI4, they are containers of variables (and things that can be stored as variables, such as states and countries).

Array support is an extension on the existing variable system. You can store arrays anywhere you can store variables (countries, states, unit leaders or globally). You can access individual array elements using existing effects & triggers that changes or compares variables (the syntax for accessing an element is array_name^index) or you can use them in the effects/triggers that accepts variables. And there are many additional effects and triggers to interact with arrays, like effects that can add/remove elements or triggers that can check for every or any elements.

Let's give an example:

Code:
#create an example array with 3 countries, named "array_example"
add_to_array = { array_example = GER }
add_to_array = { array_example = ITA }
add_to_array = { array_example = TUR }

# calculate total pp of these 3 countries
set_temp_variable = { sum_pp = 0 }
for_each_scope_loop = {
    array = array_example
    add_to_temp_variable = { sum_pp = political_power }
}

if = {
    # do they have more than 100 pp?
    limit = { check_variable = { sum_pp > 100 } }
 
    # remove 33 pp
    for_each_scope_loop = {
        array = array_example
 
        add_political_power = -33
    }
 
    #pp spent, now do business
}

Here I assumed Germany, Italy and Turkey made some kind of pact and I want to run an effect if they have more than 100 pp in total. This effects builds an array of 3 countries using add_to_array effect, calculates the sum of their pp by iterating on this array using for_each_scope_loop effect and removes 33pp from each if the sum is > 0 again using for_each_scope_loop.

This is just one example to usage of arrays. There are many more ways to interact with arrays, which can be found in my other post.

In addition to arrays that you can create or change, the game will also support "game variable arrays". Similar to "game variables", in various scopes you will be able to access such constant arrays which are built using in game data. For example accessing "enemies" array in country scope will let you access enemies of a country. If you loop through enemies, you will loop every for every enemy of that country. Current list of game variables and arrays can be found in my other post, please check it if you are interested and feel free to post your suggestions.

Meta-Effects and Meta-Triggers

This is something we borrowed from EU4, but the implementation and the usage is different. Meta-effects and meta-triggers will let modders to use non-dynamic effects/triggers (the ones that do not accept modifiers and can only use static tokens or constant values) as if they were accepting variables. It is hard to explain and so let's give an example! Consider following code

Code:
add_equipment_to_stockpile = {
    type = infantry_equipment_2
    amount = eq_amount
}

In this effect, amount is dynamic and can be set using a variable (here it is being set to eq_amount variable). However this effect does not let scripters to use a variable as equipment type. You can not store infantry_equipment_2 in a variable and use it here.

But with meta-effects anything is possible! Meta-effects will let scripters to use variables & scripted localization within their effect to build effects as if they were texts and run them. Now let's make previous effect accept equipment type and equipment level as variables stored in eq_type and eq_level.

Code:
set_temp_variable = { eq_type = 1 }
set_temp_variable = { eq_amount = 10 }
set_temp_variable = { eq_level = 2 }

meta_effect = {
    text = {
        add_equipment_to_stockpile = {
            type = [EQ_TYPE]_[EQ_LEVEL]
            amount = eq_amount
        }
    }
    EQ_LEVEL = "[?eq_level|.0]"
    EQ_TYPE = "[This.GetEquipmentName]"
}

# scripted localization
defined_text = {
    name = GetEquipmentName
    text = {
        trigger = {
            check_variable = { eq_type = 0 }
        }
        localization_key = "infantry_equipment"
    }
    text = {
        trigger = {
            check_variable = { eq_type = 1 }
        }
        localization_key = "artillery_equipment"
    }
    # give all equipment an index here
}

Here we created a meta_effect that takes two arguments. These arguments will be used replacing the parameters ([EQ_TYPE] and [EQ_LEVEL]) inside the meta effect. EQ_LEVEL will be replaced by [?eq_level|.0] which is the integer value of eq_level (in this case 2.000 becomes 2). EQ_TYPE is a bit more complicated, it is being replaced by a scripted localization. This scripted localization will check eq_type variable and depending on its value it will return the key token for the equipment. If it is 0, it will return infantry_equipment. If two, it will return artillery_equipment.

So the final result is [EQ_TYPE] is being replaced by "artillery_equipment" and [EQ_LEVEL] is being replaced by "2" and in the end our effect will be built as:

Code:
add_equipment_to_stockpile = {
    type = artillery_equipment_2
    amount = eq_amount
}

which will give you 10 artillery_equipment_2! Now you might think that this is extremely convoluted way of giving 10 artillery_equipment_2. But it will be possible to use and replace meta_effects in the scripted_effects or scripted_triggers, so this convoluted parts will be only written once.

Dynamic Modifiers

Currently our modifiers can only contain static values and you can't use variables in them. With dynamic modifiers, it will be possible add such modifiers to country and states. To keep things simple, we limited adding and removing dynamic modifiers only through effects, although some QoL improvements may be added in future.

Their declaration is similar to static modifiers, except that they will accept variables as modifier values.

Code:
dynamic_modifier_example = {
    political_power_factor = pp_factor_variable
}

And after declaring a dynamic modifier like that, you can run following effect to add this modifier to current scope.

Code:
set_variable = { pp_factor_variable = 0.15 }
add_dynamic_modifier = { modifier = dynamic_modifier_example }

This example will add "dynamic_modifier_example" dynamic modifier to the country of the scope. This modifier will give country pp gain factor equal to "pp_factor_variable" stored that in country. In this example we stored, 0.15 so the country will get 15% more pp gain. When you change the value of pp_factor_variable later through another effect, the bonus the country gets will also be updated.

Additionally you can define a scope while adding dynamic modifiers. In that case the modifier will fetch the variables from the scope that you specified. This will also let scripters to add multiple instances of same dynamic modifier that is targeting different countries (or states) so you can use them as if they were relationship modifier.

While adding modifiers, you can specify a duration as well, which makes them automatically removed after certain number of days. And it is possible to define a trigger, which will also remove the modifier when the trigger is false.

It will be possible to give dynamic modifiers icons. In that case they will show up in GUI. For example dynamic modifiers that are added country will show up if they were "national spirits" if an icon is defined.

dynamic mods.png


In this example Turkey has two dynamic modifiers in it. And we defined an icon here so it shows up in national spirits list. Both of these dynamic modifiers are same but one is targeted at Italy and the other one is target at France and value of "Fuel Capacity" is being read from those scopes (and root is Turkey, you can use targeted variables if you want). Also the effect that added those modifiers defined a duration, and these modifiers will be removed in two days because of that.

More Scripted-GUI features

Modders are being extremely creative with this feature and I am delighted to see all those new cool mods that is being developed or in the workshop. Other than fixing some unfortunate bugs and insights in the live version, we are also adding "dynamic lists" support for scripted GUIs.

Dynamic lists will let modders to create their own lists and fill those lists using an array they specify. In an older dev diary, I showed this sneak peek:

output.gif


This one is actually implemented using arrays. Each cell here is dynamically created using an array of 64 elements and value of each element represents the cell state. Each cell element is being built using the scope and the value of the the array element.

Another, more down to earth, example:

output.gif


Bottom list is populated using allies of the country (using “allies” game array in country scope). For Germany, this array has two elements, Italy and Turkey and thus it creates two entries in the bottom list. While building the elements of the bottom list, it changes scope to each entry in the element (if the element is not scopable, there are ways to access the value & index of the element, which are also being shown in the example)

Top list is built using an array that is stored in country scope and initially it is empty. Pressing “Add Item” button at top calls an effect that adds random country to that array, which also updates the list itself.

The medium flags that are being shown as a grid is also another dynamic list. This example is given to show that the lists inside lists also possible.

And that is all from me for now. If you are interested more on those topics, check the in-depth topic on modder's forum and please give feedback.
 
Last edited:
  • 1Like
Reactions:
Admiral traits look nice and varied, although I wonder how the individual skill points (Attack, Defense, Manoeuvring and Coordination) will effect ship/fleet performance.
The broad strokes are as outlined in the DD. Maneuvering is more useful within combat while Coordination most useful outside. more details will need to wait for when we cover combat changes

Also, will there be a lot more Naval officers? It looks like if you want to get the most out of the Naval Commander traits, you want as many battlegroups with as many Naval Commanders as possible.

Will they earn XP at similar rate or mechanic as land generals and field marshalls?
Xp gain is similar. some traits require certain stuff to be gained. Spotter is gained when spotting things for example. We'll see about commanders. Our plans atm are for more generics for all and <unannounced>
 
Oooohh... very nice. New information in regards to the navy rework is always great.

I've been wondering though, will there be any way to tell my carrier fighters not to attack ships during naval combat? While probably a really niche feature, I'd rather let my BBs, BCs, and CAs hammer the enemy fleet to bits. There's just something underwhelming about aircraft kills on ships in my opinion.
 
Oooohh... very nice. New information in regards to the navy rework is always great.

I've been wondering though, will there be any way to tell my carrier fighters not to attack ships during naval combat? While probably a really niche feature, I'd rather let my BBs, BCs, and CAs hammer the enemy fleet to bits. There's just something underwhelming about aircraft kills on ships in my opinion.
I applaud your fighting spirit but I think the best solution is to just put your carriers in port until you really need them? :)
 
ust put your carriers in port until you really need them? :)

Hmm.

I think I'll buy stock in "Port Strikes, LTD".

With capital ships sitting in dock, the value of blind air strikes versus the ports will increase (primarily thinking of port strikes against England and Italy).

A whole new game dynamic opens up with "just put your carriers in port until you really need them"

:)
 
Blockade Runner
Something tells me the Bismark is finnaly sailing to the Atlantic.
Not to mention making a German invasion of Norway possible hopefully?

Modding!
Hello everyone! @shultays here. I am a programmer in HoI4 team and I have exciting updates for all our modders and for the players that enjoy their mods! In this dev diary I will introduce a couple new scripting features that will be especially appealing for our modders. It is a bit early for such tech dev diary but we wanted some feedback on those features, and also have enough time to iterate on such feedback.

I will give short descriptions and small examples here, more in-depth stuff can be found in my other post that I made in modding forums.

Arrays

The people with programming experience are already familiar with the concept of arrays. For those who are not, arrays are basically containers of data. In HoI4, they are containers of variables (and things that can be stored as variables, such as states and countries).

Array support is an extension on the existing variable system. You can store arrays anywhere you can store variables (countries, states, unit leaders or globally). You can access individual array elements using existing effects & triggers that changes or compares variables (the syntax for accessing an element is array_name^index) or you can use them in the effects/triggers that accepts variables. And there are many additional effects and triggers to interact with arrays, like effects that can add/remove elements or triggers that can check for every or any elements.

Let's give an example:

Code:
#create an example array with 3 countries, named "array_example"
add_to_array = { array_example = GER }
add_to_array = { array_example = ITA }
add_to_array = { array_example = TUR }

# calculate total pp of these 3 countries
set_temp_variable = { sum_pp = 0 }
for_each_scope_loop = {
    array = array_example
    add_to_temp_variable = { sum_pp = political_power }
}

if = {
    # do they have more than 100 pp?
    limit = { check_variable = { sum_pp > 100 } }
 
    # remove 33 pp
    for_each_scope_loop = {
        array = array_example
 
        add_political_power = -33
    }
 
    #pp spent, now do business
}

Here I assumed Germany, Italy and Turkey made some kind of pact and I want to run an effect if they have more than 100 pp in total. This effects builds an array of 3 countries using add_to_array effect, calculates the sum of their pp by iterating on this array using for_each_scope_loop effect and removes 33pp from each if the sum is > 0 again using for_each_scope_loop.

This is just one example to usage of arrays. There are many more ways to interact with arrays, which can be found in my other post.

In addition to arrays that you can create or change, the game will also support "game variable arrays". Similar to "game variables", in various scopes you will be able to access such constant arrays which are built using in game data. For example accessing "enemies" array in country scope will let you access enemies of a country. If you loop through enemies, you will loop every for every enemy of that country. Current list of game variables and arrays can be found in my other post, please check it if you are interested and feel free to post your suggestions.

Meta-Effects and Meta-Triggers

This is something we borrowed from EU4, but the implementation and the usage is different. Meta-effects and meta-triggers will let modders to use non-dynamic effects/triggers (the ones that do not accept modifiers and can only use static tokens or constant values) as if they were accepting variables. It is hard to explain and so let's give an example! Consider following code

Code:
add_equipment_to_stockpile = {
    type = infantry_equipment_2
    amount = eq_amount
}

In this effect, amount is dynamic and can be set using a variable (here it is being set to eq_amount variable). However this effect does not let scripters to use a variable as equipment type. You can not store infantry_equipment_2 in a variable and use it here.

But with meta-effects anything is possible! Meta-effects will let scripters to use variables & scripted localization within their effect to build effects as if they were texts and run them. Now let's make previous effect accept equipment type and equipment level as variables stored in eq_type and eq_level.

Code:
set_temp_variable = { eq_type = 1 }
set_temp_variable = { eq_amount = 10 }
set_temp_variable = { eq_level = 2 }

meta_effect = {
    text = {
        add_equipment_to_stockpile = {
            type = [EQ_TYPE]_[EQ_LEVEL]
            amount = eq_amount
        }
    }
    EQ_LEVEL = "[?eq_level|.0]"
    EQ_TYPE = "[This.GetEquipmentName]"
}

# scripted localization
defined_text = {
    name = GetEquipmentName
    text = {
        trigger = {
            check_variable = { eq_type = 0 }
        }
        localization_key = "infantry_equipment"
    }
    text = {
        trigger = {
            check_variable = { eq_type = 1 }
        }
        localization_key = "artillery_equipment"
    }
    # give all equipment an index here
}

Here we created a meta_effect that takes two arguments. These arguments will be used replacing the parameters ([EQ_TYPE] and [EQ_LEVEL]) inside the meta effect. EQ_LEVEL will be replaced by [?eq_level|.0] which is the integer value of eq_level (in this case 2.000 becomes 2). EQ_TYPE is a bit more complicated, it is being replaced by a scripted localization. This scripted localization will check eq_type variable and depending on its value it will return the key token for the equipment. If it is 0, it will return infantry_equipment. If two, it will return artillery_equipment.

So the final result is [EQ_TYPE] is being replaced by "artillery_equipment" and [EQ_LEVEL] is being replaced by "2" and in the end our effect will be built as:

Code:
add_equipment_to_stockpile = {
    type = artillery_equipment_2
    amount = eq_amount
}

which will give you 10 artillery_equipment_2! Now you might think that this is extremely convoluted way of giving 10 artillery_equipment_2. But it will be possible to use and replace meta_effects in the scripted_effects or scripted_triggers, so this convoluted parts will be only written once.

Dynamic Modifiers

Currently our modifiers can only contain static values and you can't use variables in them. With dynamic modifiers, it will be possible add such modifiers to country and states. To keep things simple, we limited adding and removing dynamic modifiers only through effects, although some QoL improvements may be added in future.

Their declaration is similar to static modifiers, except that they will accept variables as modifier values.

Code:
dynamic_modifier_example = {
    political_power_factor = pp_factor_variable
}

And after declaring a dynamic modifier like that, you can run following effect to add this modifier to current scope.

Code:
set_variable = { pp_factor_variable = 0.15 }
add_dynamic_modifier = { modifier = dynamic_modifier_example }

This example will add "dynamic_modifier_example" dynamic modifier to the country of the scope. This modifier will give country pp gain factor equal to "pp_factor_variable" stored that in country. In this example we stored, 0.15 so the country will get 15% more pp gain. When you change the value of pp_factor_variable later through another effect, the bonus the country gets will also be updated.

Additionally you can define a scope while adding dynamic modifiers. In that case the modifier will fetch the variables from the scope that you specified. This will also let scripters to add multiple instances of same dynamic modifier that is targeting different countries (or states) so you can use them as if they were relationship modifier.

While adding modifiers, you can specify a duration as well, which makes them automatically removed after certain number of days. And it is possible to define a trigger, which will also remove the modifier when the trigger is false.

It will be possible to give dynamic modifiers icons. In that case they will show up in GUI. For example dynamic modifiers that are added country will show up if they were "national spirits" if an icon is defined.

View attachment 401600

In this example Turkey has two dynamic modifiers in it. And we defined an icon here so it shows up in national spirits list. Both of these dynamic modifiers are same but one is targeted at Italy and the other one is target at France and value of "Fuel Capacity" is being read from those scopes (and root is Turkey, you can use targeted variables if you want). Also the effect that added those modifiers defined a duration, and these modifiers will be removed in two days because of that.

More Scripted-GUI features

Modders are being extremely creative with this feature and I am delighted to see all those new cool mods that is being developed or in the workshop. Other than fixing some unfortunate bugs and insights in the live version, we are also adding "dynamic lists" support for scripted GUIs.

Dynamic lists will let modders to create their own lists and fill those lists using an array they specify. In an older dev diary, I showed this sneak peek:

View attachment 401601

This one is actually implemented using arrays. Each cell here is dynamically created using an array of 64 elements and value of each element represents the cell state. Each cell element is being built using the scope and the value of the the array element.

Another, more down to earth, example:

View attachment 401602

Bottom list is populated using allies of the country (using “allies” game array in country scope). For Germany, this array has two elements, Italy and Turkey and thus it creates two entries in the bottom list. While building the elements of the bottom list, it changes scope to each entry in the element (if the element is not scopable, there are ways to access the value & index of the element, which are also being shown in the example)

Top list is built using an array that is stored in country scope and initially it is empty. Pressing “Add Item” button at top calls an effect that adds random country to that array, which also updates the list itself.

The medium flags that are being shown as a grid is also another dynamic list. This example is given to show that the lists inside lists also possible.

And that is all from me for now. If you are interested more on those topics, check the in-depth topic on modder's forum and please give feedback.
Boy oh boy, does this get me hyped.

Quick question, is it possible to reference divisions, armies and army groups in arrays?
 
More generic naval commanders is kinda of a bummer. But overall that is better then nothing.
 
just put your carriers in port until you really need them? :)


I've been doing more or less that, leaving them on "Do not engage" in a seperate fleet from the main battlegroup. I switch them to "Weapons free" when hostile carriers show up, but the trouble there is that it's rather hit-and-miss right now to have them disengage again.

On a sort of related note, I've noticed the AI using carrier fighters, CAS, and NAV as if they were normal planes when their respective carrier is sunk. Any chance the AI could be told to auto-disband air wings composed of carrier aircraft that aren't on carriers?
 
Something tells me the Bismark is finnaly sailing to the Atlantic.
Not to mention making a German invasion of Norway possible hopefully?


Boy oh boy, does this get me hyped.

Quick question, is it possible to reference divisions, armies and army groups in arrays?

No, scripting language can't scope to specific units and unit leaders can't be stored as variable for now
 
Looking great. Have the full expectation now of C&C hierarchy for Naval, sorely needed. Donitz and Nimitz never commanded from a bridge during the war. Admirals need to have risk of being killed if leading from ships, in combat.

Also from naval traits, I’m guessing that transport/convoy abstraction is unfortunately fully remaining in MtG. This remains one of my largest peeves in HOI4. “Empty” transports never need protection as they can’t be attacked. Transports/Convoys can be attacked day after day, and not retain damage making them more succeptible the next day. I think the community is ‘ready’ to handle this level of detail.

In regards to modding, good improvements however still waiting to have direct access to units, which would be the biggest modding improvement you could possibly make.
 
Admirals need to have risk of being killed if leading from ships, in combat.
This is one of those things that sound cool but isn't in practice. ppl put a lot of work into grooming leaders and having them die in combat would just be rage inducing and lead to reloading of savegames or odd strategies around having the leaders survive.
 
The broad strokes are as outlined in the DD. Maneuvering is more useful within combat while Coordination most useful outside. more details will need to wait for when we cover combat changes


Xp gain is similar. some traits require certain stuff to be gained. Spotter is gained when spotting things for example. We'll see about commanders. Our plans atm are for more generics for all and <unannounced>
It seems like you are saying that admirals you purchase with political power will be able to earn traits after the expansion. If this is true can we get a confirmation? Will this also be true for the patch or only for the expansion?
 
No, scripting language can't scope to specific units and unit leaders can't be stored as variable for now
Well, here's hoping for the future then! :D

Still, great work there, I was wondering where mod support could go after variables and scriptable GUIs, but you guys just keep going and going.
 
This is one of those things that sound cool but isn't in practice. ppl put a lot of work into grooming leaders and having them die in combat would just be rage inducing and lead to reloading of savegames or odd strategies around having the leaders survive.

That is very definitely what I would do (and do do in other games).

Though I can imagine that the people for whom maximising the difficulty in games is where they find their fun wouldn't be so bothered.

But for me, anything that means I spend less time rage-reloading (because I won't NOT reload, because I won't let the RNG "win") is all too the good...