差分

ナビゲーションに移動 検索に移動
21,956 バイト追加 、 月曜日 04:32
スコープの日本語化(kagi)
{{version|1.1}}
[[File:CK3 Scopes.png|thumb|right|CK3 スコープ概要チャート]]

※2025/10/6、英wikiよりkagi翻訳を通しました。機械翻訳なので一部不自然な日本語があるかもしれません。ぜひ編集してくれるとありがたいです。

'''スコープ'''は、[[トリガー]]のチェックや[[効果]]の実行のために、[[スクリプト]]内で対象となるエンティティを選択するために使用されます。
[[File:Exportedscopes190.png|alt=|thumb|これらは1.8.0時点の色分けされた直接スコープで、ゲームファイルから自動出力で生成されたものです。]]

== 定義 ==
{{go to top}}
=== データベース・スコープ ===

スコープとは、最も一般的にはデータベース上のオブジェクトを指し、データベース自体はスコープの種類(スコープタイプ)として参照されます。例としてはキャラクター、称号、プロヴィンスなどが含まれます。

利用可能なスコープタイプの全一覧は[[Scopes_list|event_scopes.log]]にあります。

特に断りがない限り、スコープという用語は常にデータベース・スコープを指します。

データベース・スコープは通常、以下の3つの特性を持ちます。

* [[トリガー]]を使って、情報を読み取ることができる
* [[効果]]を使って、情報を書き込んだり変更したりできる
* 別のスコープへ移動できる

一部のスコープはゲーム開始時に作成されます。{{path|history}}ファイル(歴史的キャラクター、称号)、{{path|map data}}(プロヴィンス)、{{path|common}}フォルダ(文化、信仰、政体、特性…)などが出典です。

一部のスコープは実行時にも、コード上(例:自然出産したキャラクター)やスクリプト上(例:<code>create_character</code>効果で作られたキャラクター、動的称号)で作成されます。

=== プリミティブ・スコープ ===
{{go to top}}
数値、ブール値(yes/no)、フラグ値(<code>flag:some_string</code>)は、いわゆるプリミティブ・スコープです。これらは変更やアクセスができません。「数値もスコープである」という表現は初心者には混乱を招くかもしれませんが、上級機能やエラーログの理解には有用です。

=== トップ・スコープ ===
{{go to top}}
トップ・スコープは、ゲームが情報を保持するために作成する一時的かつ抽象的なオブジェクトで、ローカライズやGUIでの表示などに利用されます。

== スコープへのアクセス ==
{{go to top}}
特に断りがない限り、スコープという用語は常にデータベース・スコープを指します。

スクリプトでは、[[効果]]と[[トリガー]]はコンテキスト内で実行され、多くは特定のスコープタイプから機能します。

例:[[トリガー]]<code>is_ai = no</code>は現在のスコープがプレイヤーかどうかを判定しますが、これはキャラクタースコープの文脈でのみ意味を持ちます。別のスコープタイプの文脈で用いるとエラーになります。

この章では、スクリプトが解釈されるコンテキストを変更する方法を説明します。スコープは[[効果]]や[[トリガー]]の引数としても使用でき、その場合も以下のアクセス方法が用いられます。

==== root ====
{{go to top}}
[[トリガー]]ブロックや[[効果]]ブロックには、コード側でデフォルトのコンテキストが与えられていることがよくあります。その場合、コンテキストが変更されない限り、[[トリガー]]はそのスコープの文脈で評価され、[[効果]]は実行されます。

例:イベントの<code>immediate</code>効果ブロックでは、コンテキストはイベントを受け取ったキャラクターであり、デフォルトではそのブロック内の全ての効果は当該キャラクタースコープの文脈で実行されます。

[[効果]]ブロックや[[トリガー]]ブロックにデフォルトのコンテキストがある場合、<code>root</code>はそのデフォルト・コンテキストへのショートカットです。よくある誤解に反して、<code>root</code>はプレイヤーを意味しません。実際、このゲームでは複数のプレイヤーが存在し得るため、「プレイヤー」という概念自体が曖昧です。

すべての[[効果]]ブロックや[[トリガー]]ブロックに<code>root</code>があるわけではありません。例えば、[[character interactions|キャラクター相互作用]]内のものにはありません。送信者と受信者のどちらを指すか曖昧になり得るためです。

<code>root</code>が必ずしもキャラクタースコープであるとは限りません。<code>root</code>が存在するか、またそれがどのスコープかは、各[[効果]]ブロックや[[トリガー]]ブロックに依存します。

=== コンテキスト切り替え ===
{{go to top}}
[[効果]]ブロックや[[トリガー]]ブロックのコンテキストは、設定したいスコープ名の後に等号<code>=</code>と開き波括弧<code>{</code>を置いて新しいスクリプトブロックを開くことで、任意の時点で変更できます。対応する閉じ波括弧<code>}</code>が現れるまで、そのコンテキスト変更は有効です。

例:イベントの<code>immediate</code>効果ブロック
<pre>immediate = {
< ここでのコンテキストはイベントを受け取ったキャラクター(キャラクタースコープ) >
title:k_france = {
< ここでのコンテキストはフランス王国(称号スコープ) >
}
< ブロックを閉じると、元のキャラクタースコープに戻る >
}</pre>

スクリプトブロックをネストしてさらに開くことで、コンテキストは複数回切り替えられます。新しいブロックを開くたびにインデントを増やし、閉じたら減らします。インデントを整えておくと、どの文脈で[[トリガー]]や[[効果]]が解釈されるのかが一目で分かります。

<code>root</code>が提供されている場合は、いつでもそれにアクセスしてコンテキストを戻せます。

例:
<pre>immediate = {
title:k_france = {
< ここでのコンテキストはフランス王国 >
root = {
< ここでのコンテキストはイベント受領キャラクター >
}
}
}</pre>

無効なスコープにコンテキストを変更しようとすると、コンテキスト切り替えは失敗します。
例:
<pre>immediate = {
title:k_frnace = {</pre>
この誤字により、<code>k_frnace</code>が未定義のためコンテキスト切り替えは失敗します。

=== データベースへのアクセス ===
{{go to top}}
スコープはデータベース・オブジェクトであるため、一意のキーやIDを持ちます。<code><scope type>:<scope key></code>という構文で識別されます。

例:<code>title:k_france</code>は<code>common/landed_titles/</code>で定義されているフランス王国です。
<pre>title:k_france = {
# ここでのコンテキストはフランス王国
}</pre>

キャラクターには2種類のIDがあります。履歴IDと実行時IDです。
履歴IDは{{path|history}}ファイルで事前に決められているため、歴史的キャラクターはそのIDでアクセスできます。一方、非歴史的キャラクターは実行時に割り当てられるIDしか持たず、事前には分からずゲームごとに一貫しないため、スクリプトから参照できません。したがって非歴史的キャラクターにはこの方法でアクセスできません。

=== イベントターゲット ===
{{go to top}}
一意の関係で結ばれているスコープ同士は、イベントターゲットを通じてアクセスできます。ゲームは全てのイベントターゲットのスコープタイプを把握しているため、これらには接頭辞が付きません。

利用可能なイベントターゲットの全一覧は[[Scopes_list|event_targets.log]]にあります。

例:
<pre>holder - スコープ中の称号の保有者を取得
入力スコープ: landed_title
出力スコープ: character</pre>

<code>出力スコープ</code>はイベントターゲットのスコープタイプです。
<code>入力スコープ</code>はイベントターゲットを使用できるスコープタイプです。

称号は常に同時にただ一人のキャラクターにしか保有されません。そのため、<code>holder</code>イベントターゲットにより、称号スコープからその称号を保有する唯一のキャラクタースコープへ移動できます。
<pre>title:k_france = {
holder = {</pre>

イベントターゲットはドットで連結してチェーンできます。

例:
<pre>title:k_france.holder = {</pre>

以下のイベントターゲットには特有のコンテキスト動作があります。

==== this ====
{{go to top}}
<code>this</code>は現在のスコープです。特に[[scope comparison|スコープ比較]]や、現在のスコープを引数として渡す際に有用です。

==== prev ====
{{go to top}}
<code>prev</code>は直前のスコープです。<code>this</code>同様、[[scope comparison|スコープ比較]]や直前のスコープを引数に渡す際に有用ですが、下記のリストビルダーと併用する場合にも役立ちます。

<pre>title:k_france = {
holder = {
prev = {
# ここでのコンテキストは一段戻って title:k_france になる</pre>

CK2とは異なり、<code>prev</code>は複数段さかのぼるためにチェーンすることはできません。

=== 保存されたスコープ ===
{{go to top}}
保存されたスコープは、<code>scope:<scope name></code>という構文で、特定のスコープへの任意の名前付きポインタです。

保存されたスコープはコード側で保存され、提供されることがあります。例えば、[[Interactions modding|キャラクター相互作用]]では、<code>scope:actor</code>は相互作用を送るキャラクター、<code>scope:recipient</code>は受け取るキャラクターです。

一部のon_actionでも事前に保存されたスコープが提供されます。どのスコープが利用できるかはファイル内のコメントを確認してください。

保存されたスコープは、<code>save_scope_as</code> [[effect]]を使ってスクリプトからも保存できます。これは現在のスコープを指定した名前で保存します。

<pre>title:k_france.holder = {
save_scope_as = king_of_france
}</pre>

以後、その保存済みスコープにはいつでもアクセスできます。

<pre>scope:king_of_france = {</pre>

保存されたスコープは、UIからスクリプトGUIやスクリプト値/カスタムローカライズへ、AddScopeで受け渡しできます。

<code>"[ScriptedGui.Execute( GuiScope.SetRoot( GetPlayer.MakeScope ).'''AddScope( 'target', CharacterWindow.GetCharacter.MakeScope )'''.End )]"</code>

<code>"[GuiScope.SetRoot( GetPlayer.MakeScope ).'''AddScope( 'target', CharacterWindow.GetCharacter.MakeScope''' ).ScriptValue('sval_name')|0]"</code>

保存されたスコープは、連続した効果チェーンの間ずっと引き継がれます。例えば、イベントAで<code>scope:king_of_france</code>を保存し、そのイベントAがイベントBを発火した場合、イベントBでも<code>scope:king_of_france</code>にアクセスできます。

連続した効果チェーンが終わると、保存されたスコープは自動的にクリアされます。必要に応じて、<code>clear_saved_scope</code> [[effect]]で手動クリアも可能です。

<code>save_temporary_scope_as</code>は[[effect]]としても[[trigger]]としても使えます。保存された一時スコープは連続効果チェーンを跨いで引き継がれず、保存された[[効果]]ブロックまたは[[トリガー]]ブロックの終端で失効します。

同じ名前の保存スコープは同時にひとつしか存在できません。同名で新たに保存すると、以前のものは上書きされます。

=== リストビルダー ===
{{go to top}}
一対多の関係を持つスコープは、イベントターゲットではアクセスできません。

例えば、キャラクターには母親は常に一人であり、<code>mother</code>イベントターゲットでアクセスできます。しかし逆は成り立ちません。母親には複数の子がい得るため、曖昧になる<code>child</code>イベントターゲットは存在しません。

この場合、スコープはリストとして提供され、リストビルダーを用いてアクセスできます。リストビルダーには[[effect]]の派生が3種、[[trigger]]の派生が1種あります。

以下の節では、全てキャラクタースコープの文脈で<code>child</code>リストを用いたスクリプト例を示します。スクリプト内で構築されるリストを含め、さまざまな種類のリストがあります。

{{Main|Lists}}

==== every_X ====
{{go to top}}
<code>every_X</code>はリスト内の全てのスコープに順にアクセスし、それぞれに対して内包された[[効果]]を実行する[[effect]]です。

<pre>every_child = {
add_gold = 10
}
# 現在のキャラクタースコープの全ての子が金10を得る</pre>

リストが空であれば、内包された[[効果]]は実行されません。

[[limit]]ブロック内の[[トリガー]]を使って、リストを絞り込むことができます。リミットがtrueと評価されたスコープに対してのみ[[効果]]が実行されます。

<pre>every_child = {
limit = { is_female = yes }
add_gold = 10
}
# 現在のキャラクタースコープの全ての娘が金10を得る</pre>

絞り込み後のリストが空であれば、内包された[[効果]]は実行されません。

前述の通り、リストビルダーでは<code>prev</code>がよく使われ、リストビルダーを用いた元のスコープへ戻るのに役立ちます。

<pre>every_child = {
limit = { is_female = yes }
prev = {
add_gold = 10
}
}
# 対象キャラクターは、娘1人につき金10を得る</pre>

<code>every_X</code>でスコープを保存するのは有用ですが、同名の保存スコープは同時に1つしか存在できないため、<code>every_X</code>の実行が終わると、最終的に保存されているのはリストの最後のスコープのみです。

<pre>every_child = {
limit = { is_female = yes }
save_scope_as = female_child
}
scope:female_child = {
# これはリスト中の最後の娘であり、全員ではない
}</pre>

==== random_X ====
{{go to top}}
<code>random_X</code>はリストからランダムに1つのスコープにアクセスし、そのスコープに対してのみ内包された[[効果]]を実行します。

<pre>random_child = {
add_gold = 10
}
# 子ども1人が金10を得る</pre>

リストが空であれば、内包された[[効果]]は実行されません。

[[limit]]ブロック内の[[トリガー]]でリストを絞り込め、<code>random_X</code>はtrueと評価されたスコープの中からランダムに1つを選びます。

<pre>random_child = {
limit = { is_female = yes }
add_gold = 10
}
# 娘1人が金10を得る</pre>

リスト内に[[limit]]の条件を満たすスコープがない場合、内包された[[効果]]は実行されません。

保存スコープは<code>random_X</code>と併用されることが多く、特定のキャラクターにスコープしたい場合に特に有用です。ゲーム内の多くのキャラクターは歴史的IDを持たずID参照ができないため、他のスコープから相対的にアクセスして保存スコープとして確保し、後で再アクセスしやすくします。

<pre>
random_child = {
limit = {
is_female = yes
is_adult = yes
is_married = no
}
save_scope_as = celibate_daughter
}</pre>

==== ordered_X ====
{{go to top}}
<code>ordered_X</code>は<code>order_by</code>パラメータに従ってリストをソートし、デフォルトでは降順で最初のスコープにアクセスして、そのスコープに対してのみ内包された[[効果]]を実行します。<code>order_by</code>には名前付き値またはスクリプト値を指定でき、リスト中の各スコープの文脈で解釈されます。

注意:[[script math]]では、<code>ordered_X</code>の既定動作はリスト中の全スコープを順に反復処理することです。これがバグなのか仕様なのかは不明です。

<pre>ordered_child = {
order_by = age
add_gold = 10
}
# 最年長の子が金10を得る</pre>

[[limit]]ブロック内の[[トリガー]]でリストを絞り込め、<code>ordered_X</code>はtrueと評価された中からリストの先頭のスコープを選びます。

<pre>ordered_child = {
limit = { is_female = yes }
order_by = age
add_gold = 10
}
# 最年長の娘が金10を得る</pre>

<code>position</code>パラメータで既定の動作を上書きし、指定したインデックス(0始まり)のスコープにアクセスできます。整数または自動的に小数点以下切り捨てのスクリプト値を使えます。<code>position = 0</code>は先頭のスコープです。

<pre>ordered_child = {
limit = { is_female = yes }
order_by = age
position = 1
}
# 上から2番目に年長の娘が金10を得る</pre>

<code>min</code>と<code>max</code>パラメータにより、<code>ordered_X</code>はインデックスが<code>min</code>以上<code>max</code>以下の範囲にある全スコープを順に処理します。<code>check_range_bounds</code>パラメータは、指定範囲がリストサイズを超える場合のエラーを回避します。

<pre>ordered_child = {
limit = { is_female = yes }
order_by = age
max = 2
check_range_bounds = no
}
# 最年長から数えて上位3人の娘が順に金10を得る</pre>

==== any_X ====
{{go to top}}
<code>any_X</code>は、リスト内のスコープに不定順でアクセスし、内包されたトリガーがいずれかのスコープでtrueになるまで評価を続け、trueになった時点で<code>any_X</code>自体がtrueと評価されます。全てのスコープでfalseになる、またはリストが空なら、<code>any_X</code>はfalseです。

<pre>any_child = {
age > 10
}
# 子どものうち誰かが厳密に10歳を超えていればtrue</pre>

<code>filter</code>ブロック内のトリガーでリストを絞り込めます。<code>any_X</code>内のトリガーは、<code>filter</code>がtrueと評価されたスコープに対してのみチェックされます。

<pre>any_child = {
filter = { is_female = yes }
age > 10
}
# 娘のうち誰かが厳密に10歳を超えていればtrue</pre>

<code>save_temporary_scope_as</code>を使うと、内包トリガーが全てtrueになった最初のオブジェクトを保存し、同じトリガーブロック内で後から参照できます。

<pre>any_child = {
filter = { is_female = yes }
age > 10
save_temporary_scope_as = teenage_daughter
}</pre>

<code>count</code>パラメータを使うと、<code>any_X</code>内のトリガーがtrueになるスコープの数に任意の下限を要求できます。

<pre>any_child = {
condition = { is_female = yes }
age > 10
count >= 2
}
# 10歳を厳密に超える娘が少なくとも2人いればtrue</pre>

<code>percent</code>パラメータを使うと、<code>any_X</code>内のトリガーがtrueになるスコープの割合に任意の下限を要求できます。

<pre>any_child = {
condition = { is_female = yes }
age > 10
percent >= 0.5
}
# 10歳を厳密に超える娘が半数以上いればtrue</pre>

=== 保存されたスコープ値 ===
{{go to top}}
保存されたスコープ値は、<code>scope:<scope name></code>という構文で、特定のプリミティブ・スコープへの任意の名前付きポインタです。

保存されたスコープ値はコード側で保存・提供されることもありますが、保存スコープに比べると稀です。例えば、[[character interaction|キャラクター相互作用]]に<code>option_1</code>という選択肢がある場合、<code>scope:option_1</code>はブールのスコープ値で、選択されていればtrue、されていなければfalseです。

保存されたスコープ値は、<code>save_scope_value_as</code>効果を使ってスクリプトからも保存できます。指定したスコープ値を、指定名で保存します。

<pre>save_scope_value_as = {
name = some_name
value = <boolean>/<number>/<flag value>
}</pre>

同様に、<code>save_temporary_scope_value_as</code>トリガーまたは効果で一時的な保存スコープ値を保存できます。

保存されたスコープ値や一時保存スコープ値の利用範囲は、保存スコープと同じ規則に従います。

== 参考 ==
<references/>

{{Modding navbox}}
[[Category:Modding]]
{{Mechanics navbox}}
98

回編集

案内メニュー