コンテンツにスキップ
Stellaris v3.6 対応 翻訳

イベントのMOD制作

イベント型

型 対象
event ゲーム全体(グローバルイベント)
country_event 帝国全体
planet_event 惑星
fleet_event 艦隊
ship_event 艦船
pop_faction_event 派閥
pop_group_event POP単位。4.0以降、旧pop_event。
observer_event 観察者。開発用で、observeコマンドで観察者モードへ入ります。
system_event 星系(galactic_object)。3.0以降。
starbase_event 星系基地。3.0以降。
leader_event リーダー。3.0以降。
espionage_operation_event 諜報作戦。3.0以降。
first_contact_event ファーストコンタクト。3.0以降。
situation_event 状況。3.3以降。
agreement_event 従属国契約。3.4以降。

基本挙動

名前空間とイベントID

イベントファイルの先頭には名前空間を置きます。技術的には使用前に読み込まれればどこでも構いませんが、先頭以外は推奨しません。名前空間はファイル内のイベントを識別する基礎です。たとえばon_action_events.txtの先頭付近にnamespace = actionがあり、イベントIDはその名前空間、ピリオド、一意の数値で構成されます。

namespace = action

country_event = {
    id = action.8
    hide_window = yes
    is_triggered_only = yes
    trigger = {
        is_country_type = default
        from = { is_country_type = default }
        NOT = { has_communications = from }
        is_hostile = from
    }
    immediate = {
        establish_communications = from
        fromfrom = {
            conquer = root
            set_controller = root
        }
    }
}

ゲーム内の他の場所はaction.8で呼び出します。1ファイルに複数の名前空間を置けます。名前空間は長くでき、100文字まで動作確認されています。数字も含められます(バニラのparagon_2など)。IDのピリオド後は数字だけにし、文字を入れるとnamespace.0として認識されます。先頭の0は切り捨てられ、.003と.3は同一です。

100文字の動作確認について、原文はStellaris Modding DenのDiscord投稿を根拠として挙げています。

実行

既定では、すべてのイベントが毎日(場合によっては毎tick)すべての対象オブジェクトに対してトリガーを検査し、成立したオブジェクトのスコープで実行されます。非常に高負荷なので、通常は次のいずれかを使います。

  • is_triggered_only = yes — 常時ポーリングから除外し、別の場所から呼びます。
  • mean_time_to_happen — 検査間隔を広げます。

fire_only_once = yesもありますが、実行まではポーリングし続け、1回実行後にだけ除去されます。2.1.2以降、2回目の発火を条件側でも除外しないとエラーログが出ます。

条件

trigger内の条件が偽ならイベントは発生しません。次はapoc.1の例です。

trigger = {
    owner = { NOT = { has_country_flag = encountered_first_gateway } }
    from = {
        has_star_flag = abandoned_gateway
        any_system_megastructure = { is_megastructure_type = gateway_ruined }
    }
}

事前トリガー

完全な条件より先に検査する高速な真偽判定で、対象を早期除外して性能を改善します。省略した項目は無視され、惑星、POP、星系、星系基地、リーダーで使えます。通常トリガーとは名前が似ていてもコードを共有せず、独立した仕組みです。ゲーム内資料は000_added_pre_triggers_to_planet_events.txtを参照してください。

惑星:

pre_triggers = {
    has_owner = yes          # 惑星に所有者がいるか
    is_homeworld = no        # 所有者の母星か
    original_owner = yes     # 最初の所有者が今も所有しているか
    has_ground_combat = no   # 惑星で地上戦が進行中か
    is_capital = no          # 所属帝国の首都惑星か
    is_occupied_flag = no    # 惑星が占領されているか
    is_ai = no               # 惑星の所有者がAI操作か、人間の操作か
}

is_ai以外には通常トリガーの対応物があります。旧版では惑星スコープのis_aiが機能しませんでしたが、3.3のスクリプト刷新で修正されたと思われます。

職業のPOP(common/pop_jobs/000_pretriggers.txt参照):

possible_pre_triggers = {
    has_owner = yes          # POPのいる惑星に所有者がいるか
    is_enslaved = no         # POPが奴隷化されているか
    is_being_purged = no     # POPが浄化中か
    is_being_assimilated = no # POPが同化中か
    has_planet = yes         # POPが惑星にいるか
    is_sapient = yes         # POPに知性があるか
    is_robotic = yes         # POPがロボットか(4.0以降)
}

is_roboticは4.0以降です。派閥のcan_join_pre_triggersも同じ項目を受け付けます。

  • 星系: has_owner(所有者のいる星系基地があるか)、is_capital(所有者の首都が星系内にあるか)、is_occupied_flag(全惑星を含め、所有者以外に完全占領されているか)。
  • 星系基地: has_owner(所有者がいるか)、is_occupied_flag(支配者が所有者と異なるか)。
  • リーダー: has_owner、is_idle(リーダーが任務に割り当てられているかを判定)。

これら以外の構文(コメントを除く)を事前トリガーブロックへ書くとエラーになります。

表示

既定ではイベントウィンドウが出るため、少なくとも1つの選択肢と表示文章が必要です。hide_window = yesで非表示にでき、実績判定やプレイヤーへ知らせない処理イベントに使います。

コード実行

主な処理はimmediate内の効果文へ置き、多くのイベントは全処理をこのブロックへ収めます。ifも使えます。次はcolony.events.txtの例です。

immediate = {
    if = {
        limit = {
            event_target:subterranean_nation = {
                NOT = { has_country_flag = tech_request_approved }
            }
        }
        create_army = {
            name = "NAME_Invading_Horde"
            owner = event_target:subterranean_nation
            species = event_target:subterranean_species
            type = "industrial_army"
            leader = last_created_leader
        }
    }
}

表示イベントには最低1つの選択肢が必要で、各選択肢も効果を持てます。イベント実行時のスコープは呼出し方に強く依存します。

平均発生時間

mean_time_to_happen(MTTH)は、他の条件成立後に平均で指定期間だけ遅らせます。実際の日数には大きなばらつきがあります。内部での遅延の正確な実装は不明ですが、他のトリガーと同様に定期的に検査されると考えられます。

mean_time_to_happen = { months = 5 }
mean_time_to_happen = { days = 15 }

単位はdays、months、yearsです。条件付き補正をいくつでも加えられ、計時開始後にも影響するようです。単純なMTTHは各スコープで指定期間中に50%の確率で呼ばれ、その時点でトリガーを検査します。しかしMTTHへ補正を付けると各スコープで毎日条件を検査し、著しく高負荷になります。

MTTHは非推奨傾向

性能が悪いためバニラではMTTHを減らし、ランダム遅延付きのイベント呼出しへ移行しています。

他イベントからの呼出し

実行中イベントから任意のオブジェクトへイベントを呼び、そのオブジェクトのスコープで実行できます。実際の呼出しまで1tick以上遅れる場合があります。

random_galaxy_planet = {
    planet_event = { id = my_planet_event.1 }
}

country_event = { id = crisis.2000 days = 200 random = 100 }は200~300日遅延します。実行時に条件を満たさなければ発生しません。遅延イベントの条件はキュー投入時ではなく実行直前だけ検査します。

3.0以降はscopes = { from = fromfrom }で呼出しスコープを上書きできます。ただしローカルイベントターゲットは呼出し先で正しくスコープされません。

On Action

常時ポーリング以外で最も一般的な呼出し方法です。バニラの登録はcommon/on_actions/00_on_actions.txtにあります。MODは固有名のファイルをcommon/on_actionsへ追加でき、バニラのイベントに加えて呼ばれます。MOD制作のガイドラインにも従ってください。

月次・年次の低頻度ポーリングから、地上侵攻終了、調査完了、星系進入などの出来事まであります。登録イベントはis_triggered_only = yesにし、同じ出来事へ多数登録された候補から各トリガーで実際に呼ぶものを絞ります。ランダムイベントは出来事のたびに確率判定し、追加トリガーにより表面上の確率よりさらに稀になることがあります。

これは多くの高水準言語のGUI環境でイベントを登録する仕組みに相当します。効果フィールドを持つアノマリー、布告、政策、外交アクションなどからも直接イベントを呼べます。布告なら、有効化するたびに呼ばれます。

3.0以降はスクリプトから独自On Actionを発火できます。

fire_on_action = {
    on_action = <string>
    scopes = { from = X fromfrom = Y }
}

fire_on_action自体が1スコープとして数えられるようで、イベントターゲット以外はprevを1つ追加します。発火元はfrom = prev、その前はfrom = prevprevです。fromfrom以上へローカルイベントターゲットを指定すると、呼出しイベントで正しくスコープされません。この制約はグローバルイベントターゲットには適用されません。

条件付き説明

planet_event = {
    id = colony.182
    title = "colony.182.name"
    desc = {
        trigger = { owner = { NOT = { has_authority = auth_machine_intelligence } } }
        text = colony.182.desc
    }
    desc = {
        trigger = { owner = { has_authority = auth_machine_intelligence } }
        text = colony.182.desc.mach
    }
}

複数の条件が成立すると1つをランダム表示し、1つも成立しない場合は最初の説明を表示します。3.0以降、複数のdesc自体もランダムに1つ選ばれます。条件付きと静的説明を併用できます。

desc = {
    trigger = { owner = { NOT = { has_authority = auth_machine_intelligence } } }
    text = colony.182.desc
}
desc = colony.182.desc.mach

1つのdescへ、条件に応じて複数の文章断片を連結する動的ローカライズも作れます。

desc = {
    trigger = {
        text = colony.182.desc.top
        success_text = {
            text = colony.182.desc.multiplayer
            is_multiplayer = yes
        }
        fail_text = {
            text = colony.182.desc.singleplayer
            is_multiplayer = yes
        }
        # 追加条件
        text = colony.182.desc.bottom
        # 追加条件
    }
}

これを複数のdescエントリとも組み合わせられます。

選択肢

すべての表示イベントには最低1つのoptionが必要です。afterは選択肢と同じ階層へ置き、どの選択肢を選んでもその後に実行されます。Javaなどの例外処理におけるfinallyに似ています。

フィールド 説明
name 表示名。事実上唯一の必須値で、通常はローカライズキー。翻訳済みの既定文字列も多数利用できます。条件付きの複数nameも使えます。
trigger 選択肢を表示する条件。偽なら表示も選択もできません。
exclusive_trigger 成立すると他の全選択肢を無効化します。2.0以降。
default_hide_option = yes 名前と異なり隠しません。「キャンセル」キーを押した際の既定選択肢にします。
icon 任意のアイコンスプライト。
sound 選択時に鳴らす任意の音声ファイル。
allow 選択可能条件。偽でも表示でき、特定条件で解禁される選択肢を見せられます。ウィンドウを最初に開いたときだけ検査し、その後の進行では更新しません。
tag event_window_type = leader_recruitの帝国イベントで、解雇/雇用ボタンを示します。3.8以降。
hide_option_if_not_allowed 同じリーダー雇用画面で、許可されない選択肢を隠します。3.10以降。

条件付き名称:

option = {
    name = { trigger = { <display_triggers> } text = <localization_string> }
    name = { trigger = { <display_triggers> } text = <localization_string> }
    ...
}

効果文は選択肢本体へ直接置きます。ゲームは効果からツールチップを自動生成します。custom_tooltipは追加説明、hidden_effectは中の効果に基づく自動ツールチップを抑止します。tooltip内の効果は実行せず、ツールチップだけ生成します。

option = {
    name = "xxx"
    custom_tooltip = "yyy"
    hidden_effect = {
        # 選択時に実行する効果
    }
}

ai_chanceは利用可能な選択肢間でAIの半ランダム選択を重み付けします。次は天上戦争イベントの例です。

ai_chance = {
    factor = 100
    modifier = {
        factor = 0
        OR = {
            has_valid_civic = civic_hive_devouring_swarm
            has_valid_civic = civic_fanatic_purifiers
            has_valid_civic = civic_machine_terminator
        }
        # is_homicidal = yesでも同等
    }
}

外交イベント(diplomatic = yes)では次も使えます。

  • response_text — 応答文キー。is_dialog_onlyなしでは文章とOKボタンを表示し、afterを即座に実行してOKを待ちません。
  • is_dialog_only — 文章応答だけを開く任意の真偽値です。ボタン効果は実行してもイベントを閉じないためafterは実行しません。response_text必須で、省略するとゲームはエラーを出してイベントを終了します。
  • custom_gui — 指定GUIでイベント外観を変更します。選択肢内でもその選択肢のGUIを変更できます。インターフェースのMOD制作のカスタムウィンドウも参照してください。
  • custom_gui_option — 全ボタンを指定GUIへ変更します。選択肢内では使えず、各選択肢のcustom_guiで上書きできます。

推奨事項

他のゲームファイルは後勝ちですが、eventsは最初に読み込まれた定義だけが有効です。ファイル全体を上書きせずバニライベントだけを置換するには、UTF-8順でバニラより先になるファイル名が必要です。通常は!!vanilla_override_event.txtのように先頭へ感嘆符を付けます。

発火方法

hide_windowとis_triggered_onlyが最も一般的で、両方を持つイベントも多数あります。ポーリングにランダム性を加える設定としてMTTHもよく使われます。常時ポーリングは巨大なCPU負荷になりうるため、必要最小限にします。推奨は次の方法です。

  • すぐ偽になる安価な条件を持つ門番イベントだけをポーリングする。
  • On Actionからイベント列を開始する。
  • On Actionから門番イベントを呼ぶ。

イベント連鎖・スコープ・実行順

バニラではイベントを長く連鎖させる例が多く、正しい実行順・スコープ設定に必要と考えられます。特に、非表示イベントが実際の準備処理を行い、表示イベントを呼ぶ形が非常に一般的です。immediateの変更も内部キャッシュを越えて反映されるまで、次イベントの呼出しまで待つ必要がある可能性を示します。

表示イベント例

1.6.2版の旧「機械の反乱」の例です。このイベントは現在削除されています。

country_event = {
    id = crisis.2192
    title = crisis.2192.name
    desc = crisis.2192.desc
    picture = GFX_evt_robot_assembly_plant
    show_sound = event_laboratory_sound
    location = root
    is_triggered_only = yes
    immediate = { set_country_flag = robots_pacified }
    option = {
        name = crisis.2192.a
        custom_tooltip = crisis.2192.a.tooltip
        hidden_effect = { set_country_flag = ai_perfect_servants }
    }
    option = {
        name = crisis.2192.b
        hidden_effect = {
            country_event = { id = crisis.2000 days = 400 random = 400 }
        }
    }
}

非表示イベント例

1.8.3のプレスリン危機テストイベントです。

原文には「銀河規模の大量絶滅や食欲不振を引き起こすかもしれない」という警告があります。hide_windowはプレイヤーへ知らせず起動処理を行うために必要です。trigger = { always = no }については「呼ばれたときだけ発生させると思われる」と原文は説明しています。グローバルフラグは危機発生をゲームへ知らせるために設定します。

country_event = {
    id = crisis.199
    hide_window = yes
    trigger = { always = no }
    immediate = {
        set_global_flag = prethoryn_invasion_happened
        set_global_flag = prethoryn_transmission
        begin_event_chain = { event_chain = "coming_storm_chain" target = ROOT }
        random_rim_system = {
            set_star_flag = swarm_invasion_target_1
            save_event_target_as = prethoryn_invasion_system
        }
        create_point_of_interest = {
            id = coming_storm_poi.1
            name = "coming_storm_poi_1_poi"
            desc = "coming_storm_poi_1_poi_desc"
            event_chain = "coming_storm_chain"
            location = event_target:prethoryn_invasion_system
        }
        country_event = { id = crisis.17 days = 10 }
    }
}

全パラメータ例

次の一覧はイベント本体で利用する全主要フィールドをまとめたものです。

フィールド 説明
id 名前空間と一致する一意ID。
title タイトルのローカライズキー。
desc 説明キー。複数ならランダム。ブロック形式でtext、trigger、exclusive_triggerを使えます。trigger内ではcustom_tooltipと同様にtext、success_text、fail_textやswitchを使えます。textは任意の文章、success_textは条件成立時の文章(複数を連結可)、fail_textは不成立時の文章を表示します。exclusive_trigger成立時は他の説明をすべて無効化します(2.1以降)。
picture interface/xxx.gfxで定義したイベント画像。条件付きブロックではpicture、trigger、exclusive_triggerを使います。画像一覧はイベント画像。
location プレイヤーが移動できる関連オブジェクトのスコープ。
show_sound 表示時に鳴らすsound/xxx.assetの音声名。
hide_window 非表示処理イベント。タイトル・説明・選択肢が不要。
diplomatic 外交通信風の表示。ファーストコンタクトなど。
custom_gui / custom_gui_option 外交イベント本体/全選択肢ボタンのGUI。
picture_event_data 外交イベント画像のデータで、ほとんどの項目は任意です。portraitは動くポートレートで、帝国・リーダー・種族スコープを受け付けます。planet_backgroundは窓の向こうの惑星背景、graphical_cultureはその都市の画像種別、city_levelは都市規模(背景惑星を首都らしく見せる場合など)を指定します。roomは静止背景で、静止画像またはスコープを受け付けます。
major / major_trigger major = yesで他帝国にも表示し、major_triggerで対象国を絞る旧機能。たとえばhas_ethic = ethic_materialistなら全物質主義国へ表示します。3.8で削除された可能性があります。
auto_select 自動選択。
force_open 外交イベントを強制表示。
auto_opens ポップアップ抑制中でも強制表示。
fire_only_once 1ゲームに1回だけ発生。
trackable イベント上部の自動追跡ボタンを有効化。location必須。
is_triggered_only 自動発火せず、別イベントかOn Actionからのみ呼ぶ。
mean_time_to_happen 平均発生時間と条件付きmodifier。指定期間に平均して発生するよう、日ごとの確率を計算します。例のyears = 100にfactor = 0.1を適用すると平均10年です。monthsやdaysも指定できます。
trigger 発生条件。On Actionや遅延イベントのように呼出し時点で条件を保証できない場合にも使います。
immediate 発火直後の効果。競合防止フラグ、プレイヤーが選択を遅らせては困る効果(調査船の船長を死亡させるなど)、非表示イベントの全処理を置きます。
option 表示イベントに最低1つ必要。複数可。
abort_trigger 真になると選択肢効果を実行せずイベントを消します。ゲーム停止中は評価しません。
abort_effect 中断条件成立時の効果。
after 選択後の効果。hidden_effectに入れない限り、全選択肢へ共通ツールチップを生成します。
country_event = {
    id = example.1
    title = example.1.name
    desc = example.1.desc
    desc = {
        text = example.1.desc.conditional
        trigger = {
            text = example.1.desc.conditional
            success_text = { text = example.1.success <conditions> }
            fail_text = { text = example.1.failure <conditions> }
        }
        exclusive_trigger = { <conditions> }
    }
    picture = GFX_evt_exploding_ship
    picture = {
        picture = GFX_evt_exploding_ship
        trigger = { <conditions> }
        exclusive_trigger = { <conditions> }
    }
    location = from
    show_sound = event_ship_explosion
    hide_window = yes
    diplomatic = yes
    custom_gui = "enclave_caravaneer_window"
    custom_gui_option = "enclave_caravaneer_option"
    picture_event_data = {
        portrait = event_target:contact_empire
        planet_background = event_target:contact_empire
        graphical_culture = event_target:contact_empire
        city_level = event_target:contact_empire
        room = event_target:contact_empire.ruler
    }
    auto_select = yes
    force_open = yes
    auto_opens = yes
    fire_only_once = yes
    trackable = yes
    is_triggered_only = yes
    mean_time_to_happen = {
        years = 100
        modifier = { factor = 0.1 <conditions> }
    }
    trigger = { <conditions> }
    immediate = { <effects> }
    option = {
        name = example.1.a
        custom_gui = "enclave_curator_option"
        trigger = { <conditions> }
        exclusive_trigger = { <conditions> }
        allow = { <conditions> }
        custom_tooltip = example.1.a.tooltip
        tooltip = { <effects_for_tooltip_only> }
        hidden_effect = { <effects> }
    }
    abort_trigger = { <conditions> }
    abort_effect = { <effects> }
    after = { <effects> }
}

is_triggered_onlyもMTTHもない場合、条件成立中は毎日発生します。銀河全体への意図しない連続実行を防ぐため、必ず発火方式を指定してください。

イベント継承

3.4以降はbase = <event_id>で別イベントの性質を継承できます。desc_clear、option_clear、picture_clear、show_sound_clearで個別の継承項目を消し、挙動を再利用しながらフレーバーだけ変更できます。飛び地勢力のスクリプトなどで数千行を削減しました。基礎イベントは継承側より先に定義する必要があります。

原文の参考資料は開発日記第253回(2022年5月5日)です。

空イベントボックスの不具合

タイトル・文章・画像がなく、OKボタンだけのイベントが毎日画面を埋め、プレイ不能になることがあります。通常はMOD入り環境で起こります。

原因

破損したイベントファイルの読込みです。波括弧の位置が誤っているか、必要な括弧がないと、その後のイベントは存在だけ残り、タイトル、説明、毎日全オブジェクトで発火するのを防ぐ設定などが読み取られず空洞化します。多くはゲーム版間の構文変更へ未対応のMOD、または更新ファイルがローカルへ届いていないことが原因です。

対処

  1. debugtooltipコンソールコマンドを有効にし、OKボタンへカーソルを合わせてイベントIDを確認します。
  2. IDの名前空間などから原因MODを特定します。
  3. MODが古ければ無効化して更新を待ちます。公開版は新しいのにローカルだけ古ければ、購読解除・再購読で再取得します。

原文は、古い構文をMODフォルダ全体で修正する外部Pythonツールとして、FirePrince作のStellarisModpackUtilityのmodupdater.pyも紹介しています。


出典: Stellaris Wiki — Event modding(原文更新日: 2025年12月17日、版ID 112649)
翻訳日: 2026年9月18日 / 対応バージョン: 3.6
本ページは原文Wiki(CC BY-SA 3.0)の内容を翻訳した非公式ファン翻訳です。