Hello. This is Victoria, and today I will be covering the new script features coming in 1.7.
Our scripting language is the basis of all of the ingame content in Victoria 3. This means that every script functionality that we use in making game content is also usable by modders. As well as triggers and effects which interface with new features such as power blocs and building ownership, 1.7 and Sphere of Influence add several novel functionalities for modders. These include our new scripted progress bar system for journal entries.
Scripted Progress Bars
In 1.7, journal entries will have a new way to display data: scripted progress bars. Multiple progress bars can be added per journal entry, and progress bars can be shared between journal entries. Scripted progress bars can also be configured to automatically increment on weekly, monthly, and yearly ticks.
Previously, all journal entries with progress bars have worked off of a “goal” system, where the journal entry is tied to a variable, and incrementing this variable causes the journal entry to progress.
Pictured: When this journal entry is initialised, it gets the current amount of coffee buy orders in one’s market, and multiplies it by 2.5. That multiplied value is the “goal”, and the current value is always equivalent to the current amount of coffee buy orders in the market.
This previous system remains available, and all journal entries utilising it will stay functional. However, the scripted progress bar system permits for new and interesting use cases, such as better support for incrementing progress based on various conditions.
Each scripted progress bar has certain conditions which can change its progress on a weekly, monthly, or yearly basis, and can be changed by means of scripted effect, using the new “add_progress” and “set_bar_progress” effects.
Pictured: The add_progress effect. This is used in a journal entry scope.
Scripted progress bars also have loc support, allowing for printing whatever text one wants on them.
Pictured: Think of these thoughts as limitless light; exposing closing circuitry of fright;
Scripted progress bars are defined in the common/scripted_progress_bars folder, in files therein. Looking inside one of these files, one can see the structure of each progress bar in script.
Going line by line, the first thing one sees is the ID of the progress bar. This is used in the journal entry that the progress bar is connected to. Note that progress bars can be connected to multiple journal entries at once.
Next is the localisation for the progress bar. The desc is the text displayed on the bar itself, and the name is displayed in the tooltip when one mouses over the bar.
Next is the skin the progressbar uses.
This is the communism progress bar, and so it uses the colour red. This is what it looks like ingame.
A complete list of available progress bar skins follows:
- double_sided_gold
- default_green
- default_bad
- default
- double_sided_bad
The double-sided progress bars have two text fields, allowing those who use them to put text on both the left and right of the progress bar.
Pictured: The double_sided_bad progress bar skin, which uses the journal entry icon as the mid-point between its two sides. Switching the text was not WAD, but is WAD now.
Going back to the internals of the progress bar script, one now sees the conditions scripted in the progress bar. These are what makes it trend in one direction or the other over the course of various increments.
Pictured: If one’s country has any incorporated state with over 10% of the population as radicals, every incorporated state in the country with over 10% radicals will contribute their radical count to the progress of the journal entry.
For the purpose of this example, all that matters is the amount of radicals in one’s country. In practice, a progress bar can have however many factors behind it as one wants, and all of them will be printed in a nice and orderly list.
Lastly, there is the start_value, the min_value, and the max_value. These values define the bounds of the progress bar - its minimum bound, its maximum bound, and what value it will start with when the journal entry is initialised.
The value of a progress bar can be retrieved, compared, and used in variable math with the scripted_bar_progress trigger in a journal entry scope.
Miscellaneous Script Features
Diplomatic Pact Modifiers
Diplomatic pacts can now apply modifiers to both involved parties. These are controlled by the first_modifier and second_modifier fields in the diplomatic pact’s script–the first_modifier applies to the initiator, and the second_modifier applies to the other country.
For example, the Support Regime subject interaction gives the subject in question lowered radicalism, and less liberty desire, at the cost of some legitimacy for yourself.
Here is how this script looks ingame.
Pictured: I love the Regime.
Diplomatic Interaction Types
Diplomatic interactions now have types.
The type of a diplomatic action determines from where it can be accessed. Current diplomatic action types are as follows:
- general
- subject
- overlord
- power_bloc_leader
- power_bloc_member
General diplomatic actions are available for any country, mostly encompassing actions like defence pacts, alliances, and other currently existing actions. Subject interactions are available for subjects of countries petitioning their overlord for something, overlord interactions are available for overlords demanding things of subjects, and power bloc leader/member interactions are much the same, albeit with power blocs rather than subject relationships.
All of these diplomatic action types are scriptable, and can make use of the new diplomatic action modifier system to have a wide variety of different effects.
New Script Support
In addition to a selection of triggers, modifiers, and effects related to new features, several new and useful triggers for pre-existing game content have been added in 1.7. These include:
Triggers:
- country_innovation - compares against the total innovation produced by a country
- gdp_per_capita_ranking - compares against a list of all countries’ GDP/c stats. Note that in this case, lower is better, as the top GDP/c ranking is 1.
- sol_ranking - compares against a list of all countries’ Standard of Living stats.
- income_transfer - compares against the income transferred by a diplomatic pact.
- potential_diplomatic_play_power_ratio - compares against the expected power ratio in a diplomatic play between two countries.
- can_add_wargoal_against - evaluates true if a country can add a wargoal against a specified country.
- can_break_diplomatic_pact - evaluates true if a country can break a specified diplomatic pact with a specified country.
- can_create_diplomatic_pact - evaluates true if a country can create a specified diplomatic pact with a specified country.
- would_accept_diplomatic_action - evaluates true if a specified country would accept a request for a specified diplomatic pact.
- progressiveness - compares against the progressiveness of a given law type.
- law_progressiveness_difference - compares the progressiveness of two law types.
- journal_entry_age - compares against the time since a journal entry was activated, in days.
- enactment_chance_for_law - compares against the enactment chance for a law type, if it were to begin enactment immediately.
- can_trigger_event - takes an event ID, returns true if the event is currently fulfilling its trigger conditions.
- economic_dependence - compares against one country’s economic dependence on the another country.
- gdp_ownership_ratio - compares against the percentage of one country’s economy that is owned by another country.
Modifiers:
- allow_trade_routes_without_interest_bool - Boolean modifier that, when set to true, enables a country to establish trade routes with countries that it does not have an interest in.
- state_migration_quota_mult - increases or decreases the amount of people migrating to a given state.
- country_overlord_income_transfer_mult - increases or decreases the amount of money that a subject pays to its overlord.
- country_convoy_contribution_to_market_owner_add - increases or decreases the amount of convoys that a country contributes to its market.
- country_cannot_cancel_law_enactment_bool - Boolean modifier that, when set to true, forbids a country from manually cancelling a law enactment.
- country_port_connection_cost_mult - increases or decreases the convoy cost of port connections.
- tariff_[import/export]_outside_power_bloc_mult - increases or decreases tariffs for non-power-bloc members’ goods.
Effects:
- regime_change - immediately forces a Regime Change wargoal against the specified country, using the current country scope as a template.
To acquire a full list of triggers, effects, modifiers, and scopes, use the script_docs command in the console. This will export files full of useful documentation to your Documents/Paradox Interactive/Victoria 3/docs folder, or the equivalent on your computer.
I will now hand things over to Mikael to cover the modifier rework and new scripted widget system.
---
Modifier Rework
In 1.7, the modifier_types database has been replaced with the new modifier_type_definitions database, and the modifiers database renamed to static_modifiers. Loc strings for modifier types will no longer have “modifier_” appended to their beginnings.
Modifiers have been a mainstay in Paradox grand strategy games for several generations and are an integral component of the Clausewitz game engine, but their implementation details and usage patterns sometimes differ from game to game. In Victoria 3, modifiers are used to run the entire socioeconomic simulation, and define everything from the throughput of buildings and how many units of coal are being produced, to how much Political Strength an aristocrat can wield and how quickly a starving farmer radicalises. They propagate from modifier sources, such as technologies or commander orders, through a tree of game objects (for example technology -> country -> state -> building, or commander order -> unit -> battle). When a modifier reaches its final destination, it still needs to be aware of its origin so we can explain in a tooltip that the reason your soldiers are currently fighting at 125% their base strength is because of a certain mix of commander orders & traits, the technologies you've researched, and the mobilisation options you've permitted. This system of tracking, propagating, and aggregating variables is very flexible both for programmers and designers, and has the very nice side effect of also being highly useful to modders.
However, it is also very performance intensive; due to the web of interdependencies in the game object tree it needs to keep track of the validity of each modifier node and send a signal up the tree to refresh everything when it's no longer valid. For example, whenever you change a Production Method in a building, the entire economic state of your market needs to be refreshed, which could also have an effect on other objects interfacing with the economy (which, this being Victoria, is most objects in the game).
The number of modifier nodes and invalidation events of those nodes has the biggest impact on the aggregate performance of the game, competing with number of pops for the prestigious #1 spot of "worst performance factor". Due to the increased demand on the simulation coming with 1.7/Sphere of Influence, we have had to do a major overhaul to the modifier system in the Clausewitz engine, specifically to improve performance by avoiding unnecessary work in modifier node recalculations.
This rewrite comes at a cost. Whereas previously, new modifier types defined in the modifier_types database would propagate down the tree in accordance with the first part of the modifier type name (for example, country_ targets countries and will not propagate further; building_, when applied to f.ex. a technology, will propagate to the country, then its states, then all buildings in those states), new modifier types defined by modders in script (in the modifier_type_definitions database) will no longer have a designated target and will propagate everywhere. If you specify a new modifier type country_phlogiston_generation_add and apply it to a technology, it will not stop at countries that have that technology but will merrily copy itself down the whole tree, to states, buildings, interest groups, characters, etc - all game objects that could inherit modifiers from countries. While with some careful planning this might still permit your mod to work, it can cause both performance problems and confusing UX bugs, and in the worst scenario cause modifier duplication.
We're currently working on a solution to this issue that will allow you to optionally turn on custom modifier type registration in your mod. This will allow custom modifier types to propagate according to the earlier rules. We hope it will be ready for release, if not it should appear in a hotfix afterwards. Watch the patch notes for news on this, and until then try not to include new modifier types in your modding endeavours.
Scripted Widgets
Finally, some of you will be pleased to know that we have ported over the scripted_widgets system introduced in Crusader Kings III to Victoria 3, allowing you to more easily add new UI elements to your mod without causing conflicts with other UI mods touching the same files. In addition, the AI will now evaluate whether it should be taking actions defined in the scripted_gui database dependent on its ai_is_valid trigger, the ai_frequency noted (in months), and the ai_chance (number between 1-100) defined for the scripted gui. We hope these features will allow your mods to interface even deeper with the rest of the game mechanics!
---
And that is all. Thank you for reading. Next week, Hansi will cover the new map and culture changes coming in 1.7.