『Victoria 3』開発日記#164ーMODが使えなくなる件について

『Victoria 3』開発日記#164はMODがつかえなくなる件についてについてです。

まあそうですが、問題はこれまでのMODもフォーマットが変わることでつかえなくなる可能性があるということです。
今回の内容はMOD作成時のフォーマットの変更点についてですが、とりあえず見ていきましょう。前回の記事は以下のリンクから。
MOD作成について
皆さん、こんにちは! ハッピーマンデー! システムデザイナーのTunayです。
今回のアップデートで追加された新しいモッディング関連のハイライトをいくつかお伝えすることにしました。いくつか重要なポイントがあるので、これ以上先延ばしにせずに進めていきましょう!
データベース入力モード
まず、このアップデートにより MOD が壊れることになりますが、この点については必ず強調しておきたいので、ここでもう一度繰り返します。
このアップデートによりMODが壊れる
ちょっと待ってください、皆さんが怒りをぶつけているのは分かりますが、説明させてください。これにはちゃんとした理由があるんです。Tinto Talks #85 – Moddingをご覧になった方もいるかもしれませんし、この記事を読んでいる頃には、EU5をプレイしてModを作った方もいるかもしれませんね!
EU5でスクリプト言語に導入された非常に重要な変更点の一つは、データベースエントリモードの追加です。この機能により、新しいキーワードを使用することで、MOD内のスクリプトがメインゲームまたは他のMOD内の既存のスクリプトとどのように相互作用するかを制御できるようになります。
この機能は、今回のアップデートで Victoria 3 にも導入される予定であり、私たちが強制する新しい構文に合わせて MOD を調整する必要があります。
初心者の方のために、私の新しいヒットMOD「 Victoria Tweaks Mod 2」の愛称で呼ばれているもののいくつかの例を使って、このシステムを解説します。
最初の変更として、農民徴税法を再構築し、農村民衆利益団体の精神と力強さを真に表現できるよう強化したいと考えています。
そのために、法自体のキーの前にINJECTキーワードを使用することで、既存の法にスクリプトを挿入することができます。この場合、法自体の補正ブロックを調整し、バランスを少し改善したいと考えています。
この変更により、「Doodlez の農民軍」は農村民衆の止められない武装部隊となります。
すでにお気づきの方もいるかもしれませんが、既存の補正への挿入は加算的に処理されるため、たとえば、メイン ゲームで国の威信を 25% 上げる補正があり、同じ補正を再度 50% で挿入すると、合計は 75% になります。
キーワードは全部で 6 つあり、便宜上ここにすべてリストしました。
INJECT:key - this mode tries to inject the script into an existing entry. Errors if the respective entry does not exist.
REPLACE:key - this mode replaces an existing entry with a new one. Errors if the respective entry does not exist.
TRY_INJECT:key same as INJECT: but does not error if the entry does not exist.
TRY_REPLACE:key same as REPLACE: but does not error if the entry does not exist.
REPLACE_OR_CREATE:key = { } # Same as REPLACE: but if the entry does not exist, it will create it
INJECT_OR_CREATE:key = { } # Same as INJECT: but if the entry does not exist, it will create it
これらのキーワードを適切に使用すると、多くの互換性の問題を完全に回避できるだけでなく、他のモッダーと話し合うことで、既存の複数のモッズとの互換性をより簡単に再編成できるようになります。
これらのキーワードを明示的に呼び出す必要があり、暗黙的な置換は許可されなくなり、それに応じて mod を更新する時間があることに留意してください。
最後に、この新しいシステムが適用されるデータベースのリストを以下に追加しました。
acceptance_statuses
ai_strategies
amendments
battle_conditions
building_groups
buildings
buy_packages
character_interactions
character_templates
character_traits
cohesion_levels
combat_unit_groups
combat_unit_types
combat_unit_experience_levels
commander_orders
company_charter_types
company_types
country_creation
country_definitions
country_formation
country_ranks
country_types
culture_graphics
cultures
decisions
decrees
diplomatic_actions
diplomatic_catalyst_categories
diplomatic_catalysts
diplomatic_plays
discrimination_trait_groups
discrimination_traits
dna_data
dynamic_company_names
dynamic_country_names
dynamic_country_map_colors
dynamic_treaty_names
technology
flag_definitions
game_concepts
geographic_regions
goods
government_types
harvest_condition_types
ideologies
institutions
interest_group_traits
interest_groups
journal_entry_groups
journal_entries
law_groups
laws
legitimacy_levels
liberty_desire_levels
military_formation_flags
mobilization_option_groups
mobilization_options
objective_subgoal_categories
objective_subgoals
objectives
parties
political_lobby_appeasement (factor)
political_lobby_appeasement (reason)
political_lobbies
political_movement_categories
political_movement_pop_support
political_movements
pop_needs
pop_types
power_bloc_coa_pieces
power_bloc_identities
power_bloc_map_textures
power_bloc_names
power_bloc_principle_groups
power_bloc_principles
prestige_goods
production_method_groups
production_methods
proposal_types
religions
social_classes
social_hierarchies
map_data/state_regions
state_traits
strategic_regions
subject_types
terrain_manipulators
terrain
themes
tutorial_lessons
tutorial_lesson_chains
labels
war_goal_types
alert_groups
alert_types
commander_ranks
scripted_buttons
scripted_progress_bars
treaty_articles
gfx/map/city_data/city_building_vfx
gfx/map/fleet_dioramas
gfx/map/fleet_entities
gfx/map/army_dioramas
gfx/map/front_entities
state_regions
sound/persistent_objects
music
notifications
modifier_type_definitions
ethnicities
script_values
scripted_guis
scripted_lists
scripted_modifiers
gui_animations
achievements
modifier_icons
gfx/portraits/accessories
gfx/portraits/portrait_modifiers
建物グループのクリーンアップ
起動時に MOD がクラッシュする原因について言えば:
まず、いくつかの建物の名前を変更しました。パッチがリリースされたらすぐに見分けられるはずですし、エディターで一括置換するだけで簡単に変更できます。これは、建物のキーの命名規則をより統一するためです。
2つ目、そしてより重要な変更点は、州リージョンリソースが建物グループではなく建物タイプに基づいて動作するようになったことです。
例として、map_data/state_regionsにおけるリソース設定の例を、新旧で比較してみましょう。
新:
arable_resources = { "building_wheat_farm" }
capped_resources = {
building_fishing_wharf = 4
}
resource = {
type = "building_oil_rig"
undiscovered_amount = 40
}
旧:
arable_resources = { "bg_wheat_farms" }
capped_resources = {
bg_fishing = 4
}
resource = {
type = "bg_oil_extraction"
undiscovered_amount = 40
}
この変更の理由は、リソース内で定義できるようにするためだけに存在していた建物グループ(bg_wheat_farms など)が多数存在し、建物グループシステム全体が非常に扱いにくくなっていたためです。
各農場が独自の建物グループを持つのではなく、それらはすべて bg_staple_crops の一部になりました。
削除されたグループは、レガシーシステムへの対応のため、現時点ではデータベースに残っていますが、今後は使用されないため、1.13 で完全に削除されます。
移行の負担を軽減するため、逆引き読み込みのサポートを追加しました。これにより、リソースに建物グループを入力すると、その建物グループのデフォルトの建物タイプを読み込もうとします。
ただし、このサポートは1.13で廃止されるため、MODを新しいフォーマットにアップデートすることをお勧めします。
改造可能な戦争目標
それでは、次のトピックであるスクリプト化された戦争目標の種類に進みましょう。
これは多くの皆さんが長い間ご要望をいただいていた機能だと承知しており、ようやく実現できたことを大変嬉しく思います。
この目的のため、common/war_goal_types フォルダという形で新しいデータベースを追加しました。(Alex、ありがとう! 🙂 )
アップデートが届くと、このフォルダには、このシステムにも転送されている通常の戦争目標が格納されます。
ただし、多くのバニラ目標の動作はコードで管理されているため、新しい目標を追加するだけでなく、変更する際には注意してください。
VTM2 に新しいクールな戦争目標を追加する時間がなかったので、私たち両方のために、ここにサンプル ドキュメントを追加することにしました。お楽しみください。
some_war_goal = {
icon = "gfx/interface/icons/war_goals/icon.dds"
### List of Kinds
# annex_country
# ban_slavery
# Will convert to law commitment treaty article for slavery banned
# colonization_rights
# conquer_state
# contain_threat
# enforce_treaty_article
# force_nationalization
# foreign_investment_rights
# Will convert to investment rights treaty article
# humiliation
# increase_autonomy
# independence
# join_power_bloc
# leave_power_bloc
# liberate_country
# liberate_subject
# make_dominion
# make_protectorate
# make_tributary
# open_market
# reduce_autonomy
# regime_change
# return_state
# revoke_all_claims
# revoke_claim
# secession
# take_treaty_port
# Will convert to treaty port treaty article
# transfer_subject
# unification
# unification_leadership
# custom
# No predefined effect. In case you only want to execute the on_enforced effect, but nothing else.
kind = war_goal_kind # The Kind of the war goal defines the code-side predefined package of behavior that war goal will have, primarily defining what effect the war goal has when executed.
### List of settings
# require_target_be_part_of_war
# Target country has to be in the war, can't target neutral countries
# can_add_for_other_country
# Allows adding the goal for other participating countries
# annexes_entire_state
# Flag for if the goal is expected to always annex the entire target state. This is used to calculate conflicts with other goals
# annexes_entire_country
# Flag for if the goal is expected to always annex the entire target state. This is used to calculate conflicts with other goals
# country_creation
# Flag for if the goal creates a new country
# overlord_is_stakeholder
# Flag for if the stakeholder of the war goal should be the overlord rather than the target country itself
# can_target_decentralized
# If the war goal can target decentralized countries
# has_other_stakeholder
# If the war goal has a different stakeholder than the target itself
# turns_into_subject
# If the war goal turns the target country into a subject. For conflict resolution purposes
# skip_build_list
# If the war goal should be available to be picked in the diplomatic play or not
# targets_enemy_subject
# If the war goal should target an enemy subject specifically rather than all enemies in the war goal
# targets_enemy_claims
# If the war goal should target the claims of a country, rather than the country itself
# requires_interest
# If the war goal requires you to have an interest in the relevant strategic zone
# debug
# No effect, used for code debug purposes.
# validate_subject_relation
# Validation behavior that checks if the resulting subject relation of this war goal is valid
# validate_formation_candidate_self
# Validation check to make sure the goal holder is a formation candidate
# validate_formation_candidate_target
# Validation check to make sure the goal target is a formation candidate
# validate_sole_formation_candidate
# Validation check to make sure the goal holder is the only formation candidate
# validate_target_not_treaty_port
# Validation check to make sure the target state is not a treaty port
# validate_join_power_bloc
# Special validation for join power bloc war goal kind
# validate_colonization_rights
# Special validation for colonization rights war goal kind
# validate_force_nationalization
# Special validation for force nationalization war goal kind
# validate_foreign_investment_rights
# Special validation for investment rights war goal kind
# validate_regime_change
# Special validation for regime change war goal kind
# validate_contain_threat
# Special validation for contain threat war goal kind
# validate_revoke_claims
# Special validation for revoke claims war goal kind
# validate_increase_autonomy
# Special validation for increase autonomy war goal kind
# validate_take_treaty_port
# Special validation for take treaty port war goal kind
# validate_independence
# Special validation for independence war goal kind
# validate_conflicts_war_goals_holder
# Validate conflicts with war goals of the same type from holder
# validate_conflicts_war_goals_all
# Validate conflicts with war goals of the same type from all participating countries
# validate_conflicts_conquer_state
# Validate conflicts with war goals that conquer states (i.e. that have the conflicts_with_annex_state)
# validate_conflicts_annex_country
# Validate conflicts with war goals that annex countries (i.e. that have the conflicts_with_annex_country)
# validate_conflicts_make_subject
# Validate conflicts with war goals that make new subjects (i.e. that have the conflicts_with_make_subject)
# validate_conflicts_existing_subject
# Validate conflicts with war goals that make new subjects (i.e. that have the conflicts_with_make_subject)
# conflicts_with_make_subject
# Marks the war goal as potentially conflicting with make subject war goals
# conflicts_with_country_creation
# Marks the war goal as potentially conflicting with country creation war goals
# conflicts_with_annex_country
# Marks the war goal as potentially conflicting with annex country war goals
# conflicts_with_annex_state
# Marks the war goal as potentially conflicting with annex state war goals
# conflicts_with_existing_subject
# Marks the war goal as potentially conflicting with existing subject war goals
settings = { # Settings further customize how the war goal is treated in different checks. A war goal can only have one kind, but multiple settings.
setting_1
setting_2
}
execution_priority = 80
### List of Contestion Types
# control_target_state
# control_target_country_capital
# control_any_target_country_state
# control_any_target_incorporated_state
# control_own_state
# control_own_capital
# control_all_own_states
# control_all_target_country_claims
# control_any_releasable_state
contestion_type = control_type
## Target Type
#What kind of entity the war goal primarily "targets". This primarily defines how the game generates potential alternatives for each war goal type when selecting one from the diplomatic play panel. Most war goal kinds will require a specific target type to work well and can't be changed (i.e. Conquer State can't have a Treaty Article target type). This field primarily allows you to have custom war goals target different entities.
### List of Target Types
# Country
# Loops over enemy countries to generate war goal alternatives
# State
# Loops over states belonging to enemy countries
# Treaty Article
# Loops over article types and then enemy countries
target_type = target_type
possible = {
# trigger to determine if a goal with its target data is listed when selecting a war goal in the diplo play panel
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
}
valid = {
# trigger in addition to some basic validation code-side
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
}
maneuvers = {
# script value
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
value = 10
}
infamy = {
# script value
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
value = 15
}
on_enforced = {
# script effect on top of the predefined code effect
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
}
}
文脈のないジャーナルエントリ
コンテキストレスジャーナルエントリ(以下「グローバルJE」と呼称)は、新しいタイプのジャーナルエントリフラグです。
肝心な部分に進む前に、もう一つ警告しておきます。このアップデートにより、多くのJEが動作しなくなる可能性があります。
破損を解除するには、ジャーナルエントリグループ(common/journal_entry_groups 内)に移動し、カスタムグループにコンテキストが設定されていることを確認する必要があります。
これは、すべてのJEグループに2つのコンテキストフラグのいずれかを追加するだけで可能です。
「コンテキスト = なし/国」
「country」は、単純に生成されて国に関連付けられるすべての通常の JE グループに添付する必要があるデフォルトのコンテキストであり、「None」は、グローバル ジャーナル エントリに使用する新しいコンテキストです。
グローバルJE自体は他のジャーナルエントリとほぼ同じようにスクリプト化されていますが、複数の国で共有されるオブジェクトである可能性を考慮し、多数の新しいトリガーとエフェクトが追加されています。
全体的には説明の必要がないかもしれませんが、非常にクールでエキサイティングな機能であり、今後頻繁に使用していく予定です。皆さんにもぜひお試しください!
以下に、私たちが「リッペ危機」と呼んでいる社内テストからの Global JE の例を添付しました。
# Sample JE for global journal entries
je_global_test = {
icon = "gfx/interface/icons/event_icons/event_map.dds"
group = je_group_global_test
is_shown_when_inactive = {
always = no
#always = yes
}
modifiers_while_active = {
lippe_crisis_ongoing
}
scripted_button = je_global_test_button
scripted_button = je_global_test_button_2
should_be_involved = {
OR = {
country_rank >= rank_value:great_power
country_definition = cd:LIP
country_definition = cd:SCM
}
}
should_show_when_not_involved = {
OR = {
country_rank >= rank_value:major_power
country_definition = cd:LIP
country_definition = cd:SCM
}
}
possible = {
always = no
}
complete = {
any_country = {
count < 1
OR = {
country_definition = cd:LIP
country_definition = cd:SCM
}
}
}
fail = {
any_country = {
count > 2
OR = {
country_definition = cd:LIP
country_definition = cd:SCM
}
}
}
immediate_all_involved = {
if = {
limit = { exists = c:LIP }
change_relations = { country = c:LIP value = -10 }
}
if = {
limit = { exists = c:SCM }
change_relations = { country = c:SCM value = -10 }
}
}
on_become_involved_after_activation = {
if = {
limit = { exists = c:LIP }
change_relations = { country = c:LIP value = -10 }
}
if = {
limit = { exists = c:SCM }
change_relations = { country = c:SCM value = -10 }
}
}
on_no_longer_involved = {
if = {
limit = { exists = c:LIP }
change_relations = { country = c:LIP value = 10 }
}
if = {
limit = { exists = c:SCM }
change_relations = { country = c:SCM value = 10 }
}
}
on_complete_all_involved = {
add_modifier = { name = lippe_crisis_averted years = 10 }
}
on_fail_all_involved = {
add_modifier = { name = lippe_crisis years = 10 }
}
on_timeout_all_involved = {
add_modifier = { name = lippe_crisis years = 10 }
}
on_weekly_pulse = {
effect = {
scope:journal_entry = {
every_scope_je_involved = {
limit = {
NOR = {
country_rank >= rank_value:great_power
country_definition = cd:LIP
country_definition = cd:SCM
}
}
scope:journal_entry = { remove_involved_country = prev }
}
}
scope:journal_entry = { remove_involved_country = c:FRA }
scope:journal_entry = { add_involved_country = c:ARG }
}
}
weight = 1000
timeout = 1825
should_be_pinned_by_default = yes
}
地理的地域
追加したもう 1 つの新機能は地理的地域です。これは、あらゆる種類のトリガーやチェックに使用できる、任意に定義された静的なスクリプトリストです。
これらの地理的領域を追加するのは非常に簡単です。まず、common/geographic_regions フォルダーに新しいファイルを作成し、そこにリストを書き込みます。
以下のドキュメントも添付しておきます:
geographic_region_key = {
# All state/strategic regions are added together to form a geographic region
# the key to access this in script lists i.e <any/..>_<state/...>_in_europe
short_key = "europe"
# The Strategic Regions this geographic region encompasses
strategic_regions = { sr:<key> sr:<key> sr:<key> }
# The State Regions this geographic region encompasses
state_regions = { <STATE_REGION> <STATE_REGION> }
}
# Add a "<geographic_region_key>_desc" localization key to include fluff/lore description of your geographic region
地域的な生産方法
地理的地域と非常に密接に結びついた新機能の 1 つは、世界の一部に固有の生産方法を定義できることです。
これにより、たとえば「湿潤コーヒーベルト」地理的地域で特別なコーヒー生産方法のロックを解除するなど、既存の建物にもさらに多くのバリエーションを追加できます。
文化的に定義された名前の順序
カルチャー データベースの新しいフラグを使用して、名前の表示順序を定義できるようになりました。
デフォルトでは first_last に設定されますが、代わりに last_first を選択することもできます。つまり、姓または家族の名前が最初になり、個人名または名前が最後になります。
コンソール
コンソールのボタンも、よく使用されるコマンドやチート用の新しいボタンが多数追加されるなど、若干改良されています。
鋭い目を持つ方は、新しい「国を検査」ボタンに気づいたかもしれません。このボタンをクリックすると、現在選択または監視している国のスクリプトランナーウィンドウが開きます。
コンソールコマンドを使ってインスペクターを開くこともできます。例えば「inspect_country GBR」と入力すると、イギリスのウィンドウが開きます。
CK3にインスパイアされ、右クリックメニューボタンで選択したキャラクターをキルするなど、コンテキスト依存のデバッグボタンもいくつか追加しました。もちろん、テスト目的のためだけにです!
今後さらに追加していく予定です。
スクリプトのみの補正
ついに、スクリプト専用補正(私が「偽の補正」と呼んでいるもの)を適切に定義する機能が追加されました。
common/modifier_type_definitions 内の修飾子に「script_only = yes」フラグを追加することで、本来であれば発生するはずのエラーが抑制され、エラーログが詰まらなくなるはずです。
法律改正
前回の開発日記でVictoriaが紹介した法律改正も、もちろん完全にMOD化可能です!新しく作成された common/amendments データベースで改正を定義し、新しい効果を使って法律に追加することができます。
もう一度、以下に例を追加します。
amendment_test = {
parent = law_peasant_levies # optional reference to a law that dictates what stances IGs and movements have toward this amendment
allowed_laws = { # list of laws that the amendment can be added to
law_professional_army
law_national_militia
law_mass_conscription
law_census_voting
}
modifier = {}
tax_modifier_very_low = {}
tax_modifier_low = {}
tax_modifier_medium = {}
tax_modifier_high = {}
tax_modifier_very_high = {}
possible = {
always = yes
}
can_repeal = { always = yes }
ai_will_revoke = {
always = yes
}
}
# The effect:
## add_amendment
Adds an amendment to the scoped law.
add_amendment = {
type = amendment_example
sponsor = interest_group
cooldown = 120 # months
timeout = 240 # months (optional, 0 = none)
}
**Supported Scopes**: law
しかし、既にかなり膨大なリストが蓄積されており、開発日記も長くなってきているので、残りの部分は数週間後の変更ログに残しておきます。
皆さんの継続的なサポートと、皆さんが作成している素晴らしい MOD に改めて感謝したいと思います。:)
次回の開発日記は今週の木曜日です。そこでは、アップデート 1.12 とIberian Twilightの両方でスペインについてすべてお伝えします。




























