ステラリス 開発者日記 第222回 LemにおけるMod制作可能箇所の更新

スポンサーリンク
更新情報

パラドックス社の公式フォーラムに
ステラリスの開発者日記 第222回が掲載されています。

今回はLemアップデートによってMod製作可能となる箇所についてのお話です。

以下パラドックスフォーラムの内容を意訳したものとなります。
※画像等はフォーラムより引用。
スポンサーリンク

ステラリス 開発者日記 第222回 LemにおけるMod制作可能箇所の更新

今回の担当はStellaris テクニカルスクリプターのCaligula Caesarさんです。
なお管理人はMod制作の技術的なところまでは詳しくないので今回の日記は簡易的な紹介とさせていただきます。ご了承くださいm(_ _)m

冒頭のあいさつ

ステラリスのMod制作に関する開発者日記へようこそ!
本日は、今後リリースされる3.1パッチにおける新しいスクリプト言語機能のいくつかについて説明します。

新しいシステムでは、GUIやローカルファイルでの作業が大幅に減り、「伝統」に対しての改造性が大幅に向上したことはすでに述べました。
例えば、ゲーム中に特定の決定をした場合にのみ利用可能になる伝統のツリーを、スクリプトで作成できるようにもなっています。
しかし今日は主に変数に焦点を当てます。

変数

私は前回、私たちが変数をより活用したいと思っていることをお伝えしました。

前回のパッチではゲーム内の様々な情報を保存する方法がいくつか追加されましたが、最も不足していたのはトリガー値を取得する簡単な方法でした。
それはたとえば惑星上のポップの数などです。

特にCK3(Crusader Kings III)のようなパラドックススタジオの新しいゲームと比べると、ステラリスで変数を使える場所はまだかなり限られていました。
また多くの場合、変数を使用するための構文も理想的な状態ではありませんでした。

Stellaris Ver3.1では変数の機能が大幅に強化されています。
まず形式ですが、これまでは変数の値を得ようとするとその変数自体を参照しなければならず、それが方法としては唯一でした。
今やさらにいくつかのことができるようになりました。

value = my_var #gets the value of my_var variable set on the current scope
value = from.capital_scope.my_var #gets the value of the my_var variable set on from’s capital
value = trigger:num_pops #gets the number of pops in the current scope
value = from.capital_scope.trigger:num_pops #gets the number of pops in from’s capital

このようにドット・スコープを行うことができ、多くの酷い記述を省略することができますし、これだけでも大きな改善となるでしょう。
また、trigger:<trigger>のようにして、トリガーを参照することもできます。
これは数字をチェックするすべてのトリガーをサポートし、{ }書きを使うことなく数字をチェックできます。

(注:異なるスコープ間で変数をコピーするために以前使われていた酷いフォーマットは削除されました。例えば、value = { scope = x variable = y }」と指定するようなものです)

3.0においてすでにexport_trigger_to_variableという効果がありましたが、これはfleet_powerの引数でしか機能しませんでした。
これはプロトタイプのものであり、今やこの機能はすべてのトリガーに拡張されています。
重要なのはこの効果によって、{ }を使ったもう少し複雑なトリガーから、単一の数値を比較した値を得ることができることです。

export_trigger_value_to_variable = {
    trigger = num_assigned_jobs
    parameters = {
        job = miner
    }
    variable = num_miner_jobs
}

また3.0では、Modの数値や資源の備蓄量などのゲームの値を変数に入れる方法がたくさん追加されました。
また、add_resourceやadd_modifierでの乗算など、変数を使用できる場所も増えています。
Ver3.1では、次のように変数を使用できる項目が大幅に増えました。

  • 単一の数値をチェックするトリガーの値。例えば、num_pops > my_variable”, “intel = { who = from value < trigger:num_pops }”のようなもの。
  • 単一の数値を使用するエフェクトの値。例えば、add_experience = my_variable
  • トリガーされた資源テーブルの乗数パラメータの値として。例えば(例:in a building)
resources = {
    category = planet_buildings
    cost = {
        trigger = { <triggers> }
        minerals = 100
    }
    multiplier = my_var/owner.trigger:num_pops
}
  • MTTH/AIの機会の改造
ai_chance = {
    factor = 1
    modifier = {
        add/factor = my_var/trigger:num_pops
        is_variable_set = my_var
    }
}
  • add_modifierに倍率パラメータの他にtime_multiplierが追加されたので、そちらを使うことができます。例えば死のカルト教団の場合、10年×edict_length_multの修正を加えるために使用します
  • ordered_script_listsはパラドックスの新しいゲームから採用された機能です。トリガードキュメントのエントリーで説明します。
ordered_owned_fleet - Iterate through each fleet owned by the country - executes the enclosed effects on one of them for which the limit triggers return true. Picks the specific object according to the order specified (position 0, order_by = trigger:num_pops would run the effects on the X with the most pops)
ordered_owned_fleet = {
    limit = { <triggers> }
    position = <integer, starting with 0>
    order_by = <variable>/trigger:<trigger>
    inverse = yes/no (default: no - if yes, then 0 is lowest rather than highest)
    <effects>
}
Supported Scopes: country
  • もし変数が正確すぎる数値の場合は、round_variable_to_nearestを使って、その値を10の倍数に丸めることができるようになりました。

これらの機能の概要は、eventsフォルダ内のinformationファイルに追加されています(この日記にも添付されています)。
またこれらの変数の使い方をさらに拡張することも考えられますので、将来的にはさらに多くの機能が追加される可能性があります。
今回の変更はすでに私たちにとって次のような形で非常に便利なものであることが証明されています。

  • デスカルトの報酬の改善:約1,000行のスクリプトを削減しましたが、新バージョンではより多くの要素を考慮して適切な報酬を決定することができました。
  • ゴールデンルールのキャッシュペイアウトの修正:以前のソリューションでは、数字をごまかして、実際の支払いとあまり関係のない金額を与えていました。これはもう必要ありません。
  • 連邦科学リーダーシップ・チャレンジの改善:プレイヤーが研究したテクノロジーと反復取得可能なテクノロジーの実際の数を要素として追加します
  • 他にもいろいろあります

スプライトシートの変更

これだけでもかなりの量ですがさらにいくつか紹介したいことがあります。
まず、古いゲームではアイコンにスプライトシートを使用していました。
これは1つの画像ファイルにアイコンのリストが並んでおり、例えばリストの5番目のアイコンを使用するように指定するといったシステムです。
これについては社内でもいくつか問題がありました(コロニーの自動化ボタンが誤ってロボットの牛になっていたのは記憶に新しいところです)。
また、Mod製作者からは、スプライトシートが上書きのボトルネックになっていると指摘されました。
というのも、一度にスプライトシートを上書きできるのは1つのModだけであり、そのため一度に新しいグラフィックを追加するオブジェクトのタイプを追加できるのも1つだけだからです。

スプライトシート内のアイコンに対するインデックス参照を通常のキー参照に変更する方法を見つけ出し、ゲームのこれらの要素を通常のシステムを使用するように変換することができました(新しいアイコンをスプライトシート内に配置する必要はありません)。
これは軍隊タイプ、コロニー自動化のタイプ、砲撃スタンス、そして(非常に困難でしたが!)船のサイズなどに展開されました。

一例:

spriteType = {
    name = "GFX_ship_size_military_1"
    sprite_sheet_sprite_type = "GFX_ship_sizes"
    default_frame = 2
}

船のサイズの場合はicon_frameのインデックス番号で複数のスプライトシートで使用するアイコンを指定していたので少し厄介でした。
最終的にはこのシステムを(新しいタイプのスターベースを追加する人はほとんどいないため)そのままにしておき、「icon=ship_size_military_1」という行で、複数のスプライトキー(GFX_text_ship_size_military_1、GFX_ship_size_military_1、GFX_ship_size_military_1_top、GFX_ship_size_military_1_top_damaged)を参照するようにゲームに指示しました。

影響を受けるオブジェクトを変更するModの場合、古いフォーマットはもはや機能しないので、これはいくつかの更新が必要になりますが、長期的には多くの互換性に関する悩みが解決されることを期待しています!

ランダム性

random_listなどのスクリプト関数のランダム性は、特定のケースではそれほどランダムではないことに気づいた人もいることでしょう。
特に、on_game_startから起動されたイベントでこの問題が発生しました(他にもいろいろon_actionsがありましたが、この要素が一番問題でした)。
これは非常に残念なことでした。なぜならこれは事実上、各ゲームごとに異なることを意図していた特定のものが…単にそうではなかったことを意味していたからです。
これに関連してwhileループやevery_xループを使用した場合、そのループ内で効果が発生するたびにランダムな結果が同じになるなど、以前からある問題もいくつか再検討しました。
(例:25 x random_listの場合と同様に、25xのランダムな結果ではなく、25x同じ結果になる)

私達はこれを徹底的に修正しました

  • on_game_startのようなon_actionsのランダム性の欠如は修正されました。今後、このようなミスが再発した場合ゲームは警告をしてくれるので、問題が永久追放されることを願っています。
  • whileループとevery_xループのランダム性が向上しています
  • 念のためreroll_randomエフェクトを追加しました

その他のクールなもの

またトリガーされたポップの修飾子をtraitに追加できるようになりました。
たとえば、ある惑星クラスにボーナスを与え、別の惑星クラスにペナルティを与えるtraitを追加できます。
この機能のアンロックによって広がる可能性はかなり大きいです。
例えばVoid Dwellersに2つの特性を与えるという、いささか直感的ではない(しかし非常に安易である)その場しのぎの解決策をやめ、代わりにどの種類の惑星にいるかによって適用される特性を与えることができるようになりました。

またご存知の方もいると思いますがClone Armyのオリジンは、これまでこのゲームではあまり探求されてこなかったいくつかのクールな新機能を備えています。
そのために追加したものの多くは将来的にさらにクールな用途を持つ可能性があります。

  • 種の性別をロックできるようになりました
  • 建築物のインスタンス数に帝国の制限を設定できるようになりました(また、ゲーム中に変更することもできます)
  • ゲームルールにshould_force_decline_speciesが追加されました。これは、ゲームルールで指定されたツールチップに基づいてアラートを発生させ、trueを返した種を惑星で減少させます。
    またポップが移住したり再定住したりして、すぐに衰退し始めるような場所に行かないようにするためにも使われています。

最後に、いつものようにたくさんの新しいエフェクト、トリガー、Mod修飾子を追加しました。そのうちいくつか紹介します。

  • set_visited= 調査していないシステムを表示します
  • set_saved_date 特定の日付 (将来の日付も可) を保存し変数[this.my_saved_date] のようにlocsで使用できるようにします
  • 技術的には最後の効果は実際には <scope>_flag を追加しているので、標準的なフラグの効果とトリガーはすべてのスコープに移植されています。
  • [loc] コマンドをボタンエフェクトで使用できるようになりました。
    これは、動的に変更されるようなUIに非常に便利です。
  • desc={text=X trigger={Y}}を使用して、地区、建物、ジョブ、特殊プロジェクトの説明を定義できます。またlocコマンドを使えるようになりました。
  • has_non_swapped_deditionとhas_dedition_swapを削除し、has_active_deditionに統合しました。
    Mod製作者は検索と置換を実行してください!
  • スクリプトフラグがないすべてのスコープ(例:country_flag)にスクリプトフラグが追加されました。また、変数はすべてのスコープで動作するようになりました。
  • Modを更新する際の注意事項:count_diplo_tiesはcount_relationに、count_armiesはcount_owned_armyまたはcount_planet_army(状況に応じて)になります。
    any/every/random_mining_station/research_stationも無意味なため削除されました。
    代わりにmining_station/research_station/orbital_stationのスコープ変更のみを使用します。
    またobservation_outpostは”limit”を必要としなくなりましたが、その補填としてexists = observation_outpostと記述することができます。

これらの新しい機能を追加することは私たちCustodianチームにとって大きな利益となり、その恩恵を受けられるゲームの古い部分に徐々に展開しています。
これは私が今後も楽しみにしていることであり(そして、正直に言うとほんの少し恐れています)、同様にMod製作者達がそれらを使ってどのようなことをするのかを楽しみにしています!

最後にもう一つ、従来のtrigger_docs.logは廃止され、その代わりにより使いやすくより包括的なscript_documentationフォルダが用意されました。その内容はこの投稿に添付されています。

ご存知の方もいらっしゃると思いますが、私たちはNemesisのアップデートのためにMod製作者向けの早期アクセスを行いました。
リリース当日には約10人のMod製作者に対してアップデートを行い、約160万人の加入者にサービスを提供しましたが、全体的にその結果とコミュニティの反応に非常に満足しています。 このまま順調にいけば徐々にこの実験をModコミュニティに拡大していきたいと考えています。
Lemアップデートに関しては、アーリーアクセスの実験にさらに10人のMod製作者を追加する予定です。
ご興味があればModder Early Access Requestフォームにご記入ください。

日記最後にある添付ファイルについては元サイトにてご確認ください。


以上

フォーラム内のやり取り(Q&A)

フォーラム内のやり取りで気になったものを紹介。

※引き続き管理人多忙のため休止中です。再開まで今しばらくお待ち下さい😥

感想・まとめ

以上、Stellaris 開発者日記 第222回の紹介でした。

技術的な事はMod制作に長けた方々に任せるとして、素人なりにちょっと気になったところを感想として挙げたいと思います。

まず1つ目、スプライトシートの箇所で新しいスターベースを追加する人は殆どいないので一部の機能をそのままに放置している点です。
「ほとんどいない」ということは少しはいらっしゃるということなので(実際私もスターベースのModは見たことがあります)、スターベース追加Modについては今後ちょっと難しい面が出てくるかもしれませんね。

2つ目ですが、今回かなり大規模なコード記述の仕様変更が行われることで、旧来使えていて更新が止まっているようなModは使えなくなるかもしれない点です(´・_・`)
これはゲームが更新されていけば仕方がないことなんだけど、自分が使っているModがLemアップデート後に使えるかはチェックした方が良さそうですね。

とりあえずLemアップデート後にMod関係は色々変わりそうなので変な挙動にならないか気をつけたいと思いました。