6. コアルール

トランプのみでトレーディングカードゲームのように遊ぶために、 一般的なトレーディングカードゲームを抽象化し、トランプのみで遊べるように再構築しました。

コアルールは、割込みが可能なターン制ゲームの開始から勝敗が決まるまでを定義します。(Fig. 6.1)

BlackPokerはコアルールを実装しているため、ルールを変更する場合は、コアルールに従う必要があります。

このルールは、割込みが可能なターン制ゲームの標準化したモデルとして構築されており、他のゲームへの応用も可能です。

@startuml

skinparam defaultTextAlignment center

(一般的なトレーディングカードゲーム) as TCG
(割込み可能なターン制ゲーム) as InterruptibleTurnGame
note right of InterruptibleTurnGame
これがコアルール
end note
(BlackPoker) as BlackPokerGame

InterruptibleTurnGame <--- (TCG) : "抽象化"
InterruptibleTurnGame ---> (BlackPokerGame) : "実装"

@enduml

Fig. 6.1 コアルールのイメージ

6.1. 基礎概念

割込み可能なターン制ゲームでは、現実のゲーム盤面に影響を与える前に、 どの行動を先に行うかを決める仮想的な場所があります。

割込み可能なターン制ゲームは、見方を変えると“許可制のゲーム”とも表現できます。

つまり、プレイヤーは相手に許可を得て、自分の行動を実行できるかどうか確認しながら進める形式のゲームです。

いくつかの基礎概念を紹介します。 その後、それらを組み合わせたイメージを説明します。

6.1.1. ターン

プレイヤーはターンを“持つ”ことができます。 ターンを持っているプレイヤーは先に行動できます。 ターンを持っているプレイヤーをターンプレイヤーといいます。

6.1.2. アクション

ターン制のゲームでは、プレイヤーは様々な行動を行います。 チェスであればコマを進めたり、ババ抜きであれば隣の人からカードを引いたりします。 また、ゲームのルールシステムが行う行動もあります。それらの行動をアクションと定義します。 プレイヤーが行う行動を直接アクション、ルールシステムが行うアクションを誘発アクションといいます。

6.1.3. リクエスト

アクションを実行するために、ゲームシステム(コアフロー)に対して どのようなアクションを実行するかを要求します。 この要求をリクエストと呼びます。正式名称はアクションリクエストです。

リクエストの種類によっては、ステージに蓄積されず、すぐに実行(解決)されるものもあります。

6.1.4. 解決

リクエストを処理すること(要求されたアクションを実行すること)を解決と言います。

6.1.5. チャンス

プレイヤーがリクエストできる機会をチャンスといいます。 チャンスを持っている間は何度でもリクエストすることができます。 正式名称はアクションチャンスです。

6.1.6. ステージ

ステージはリクエストの解決順を整理するために使う領域です。 後入れ先出し方式で、最後に積まれたリクエストから順に解決されます。 リクエストの種類によっては、ステージに蓄積されず、すぐに解決されるものもあります。

6.1.7. コンポーネント

コンポーネントとは、ゲーム盤面に配置されるモンスターや駒の定義です。 例えば、将棋の「歩」は駒としては複数存在しますが、「歩」の定義は1つです。 この定義をコンポーネントといいます。

6.1.8. コンポーネントインスタンス

コンポーネントとして定義されたものがゲーム盤面に配置されているとき、それをコンポーネントインスタンスといいます。 例えば、将棋の「歩」はコンポーネントとして定義されていますが、 実際の盤面に配置される「歩」は、コンポーネント定義という設計図から作られたコンポーネントインスタンスです。

6.1.9. コアフロー(ルールシステム)

リクエストはコアフロー(ルールシステム)によって整理され、処理(解決)されます。 リクエストは即時解決されるものと、ステージに蓄積されるものに分類され、順番に処理されます。

ゲームによって具体的に行う内容は異なりますが、処理する順番の制御はコアフローが担います。

コアフローはゲームの開始から勝敗が決まるまで動作し続けます。

6.2. 詳細

基礎概念を図で表すと次のようになります。(Fig. 6.2)

../_images/abstract.png

Fig. 6.2 割込み可能なターン制ゲーム

仮想的な場所でリクエストを整理し、現実のゲーム盤面に承認された順で変更を反映します。

リクエストを整理することで割込みを実現しています。どのようにリクエストを処理するかは、コアフローに従います。

さらに、アクションとリクエスト、コンポーネントとコンポーネントインスタンスの関係は次のようになります。(Fig. 6.3)


left to right direction

hide fields
hide methods
hide circle

class アクション<<定義>> {
}

class リクエスト<<生成されたもの>> {
}

アクション --> リクエスト : 生成 

class コンポーネント<<定義>> {
}

class コンポーネントインスタンス<<生成されたもの>> {
}

コンポーネント --> コンポーネントインスタンス : 生成

Fig. 6.3 リクエストとコンポーネントインスタンスの関係

ゲーム盤面には複数のコンポーネントインスタンスが生成されます。

リクエストが解決されるたびに、コンポーネントインスタンスが生成されたり、既存のコンポーネントインスタンスの状態が変化したりします。

ここからは、アクションとコンポーネントの各項目について説明します。

6.2.1. アクションの定義項目

アクションを定義する際には、次の項目を設定する必要があります。 その他の項目は、具体的なアクションに応じて追加してください。

  • オーナー

  • トリガー

  • スピード

  • タイミング

  • 起動条件

  • 誘発条件

  • 効果

6.2.1.1. オーナー

アクションの所有者。 アクションの定義はプレイヤー事に保持するため、同じ内容のアクションでもオーナーが異なります。

6.2.1.2. トリガー

アクションが要求される方法は、大きく分けて次の2種類に分類されます。

直接

プレイヤーがコストを支払うなどの手続きを経てリクエストされるアクション。

誘発

条件が満たされた場合、自動でリクエストされるアクション。

トリガー項目には「直接」または「誘発」のいずれかが設定されます。

6.2.1.3. スピード

リクエストが処理される速度は次の2種類に分類されます。

即時

リクエストはステージを用いず解決されます。

通常

リクエストはステージを経由して解決されます。

スポード項目には「即時」または「通常」のいずれかが設定されます。

6.2.1.4. タイミング

タイミングとは、アクションがリクエストされるタイミングを示します。 タイミングには次の2種類があります。

メイン

ターンプレイヤーかつステージが空のときに起こせるアクション。 実行条件: - チャンスを持っている - 自分のターンである - ステージが空である

クイック

いつでも起こすことができ、アクションをステージに積み重ねることが可能。 実行条件: - チャンスを持っている

注釈

エンドアクションの定義

最低1つはターンを別のプレイヤーに渡すアクションを定義してください。 これがないと、ターンが進行せずゲームが停止する可能性があります。

注釈

アクションのコントローラー

アクションを実行したプレイヤーを アクションのコントローラー と呼びます。 効果の解釈は、このコントローラーの視点で行われます。

6.2.1.5. 起動条件

アクションを起こす(リクエストする)ための条件を示します。

トリガーが「直接」の場合、起動条件が定義されます。 コストの支払いや対象の指定など、様々な条件がアクションごとに設定されます。

BlackPokerでは、コストの支払いや対象の指定の記述が冗長にならないよう、省略されることが多いです。

6.2.1.6. 誘発条件

アクションが誘発される条件を示します。 条件が満たされると自動的にリクエストされます。

トリガーが「誘発」の場合、この項目が定義されます。

例: - ダメージを受けたとき - カードが墓地に移動したとき

これらの状況で誘発するアクションが設定されることがあります。

6.2.1.7. 効果

効果とは、アクションが解決された際に実行される処理を指します。

6.2.2. リクエストの定義項目

アクション定義

リクエストが解決された際に実行されるアクションの内容。

スピード

アクション定義のスピードとなります。

タイミング

アクション定義のタイミングとなります。

コントローラー

アクションを実行したプレイヤーがリクエストのコントローラーとなります。

6.2.3. コンポーネントの定義項目

コンポーネントには、次の項目が定義されます。 必要に応じて、ゲームに合わせた追加設定をしてください。

オーナー

コンポーネンの所有者。 コンポーネントの定義はプレイヤー事に保持するため、同じ内容のコンポーネントでもオーナーが異なります。

能力

能力の詳細については、後述のセクションを参照してください。(6.3 能力)

6.2.4. コンポーネントインスタンスの定義項目

コンポーネントインスタンスには、次の項目が設定されます。 必要に応じて、ゲームに合わせた追加設定をしてください。

コンポーネント定義

どのコンポーネント定義から生成されたのかを保持します。

オーナー

コンポーネントインスタンスの所有者。 一般的なトランプゲームでは無視されることが多いですが、TCGのようにデッキを個人所有するゲームでは必要な情報です。

コントローラー

現在、そのコンポーネントインスタンスを操作しているプレイヤー。 通常はオーナーとコントローラーは同じですが、コントロールを奪うアクションがある場合、異なることがあります。

注釈

コンポーネントインスタンスとリクエストのコントローラー

コントローラーは制御している人という意味になるため、コンポーネントインスタンスとリクエストのコントローラーは制御する対象が異なります。 コンポーネントインスタンスとリクエストの属性を次の図に示します。(Fig. 6.4)

left to right direction

hide methods
hide circle

class コンポーネント<<定義>> {
    オーナー
    能力
}


class コンポーネントインスタンス<<生成されたもの>> {
    コンポーネント定義
    オーナー
    コントローラー
}

class アクション<<定義>> {
    オーナー
    トリガー
    スピード
    タイミング
    起動条件
    誘発条件
    効果
}

class リクエスト<<生成されたもの>> {
    アクション定義
    コントローラー
}

アクション --> リクエスト : 生成
コンポーネント --> コンポーネントインスタンス : 生成

Fig. 6.4 コントローラー属性

6.3. 能力

アクション、コンポーネントの定義項目を見てきました。 これらとは別の概念である 能力 について説明します。

能力とはアクションの効果とは異なる概念で、アクションを起こす際や効果を解釈する際に参照されます。

能力は解釈される際にコストは支払われず、ステージに置かれません。

能力を持つことができるのは、プレイヤーの他に駒やカードなどのゲームに登場するコンポーネントも含まれます。 (Fig. 6.5)

@startuml

skinparam defaultTextAlignment center

!define ICONURL https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.2.0
!includeurl ICONURL/common.puml
!includeurl ICONURL/font-awesome-5/chess_pawn.puml

FA5_CHESS_PAWN(P1C,コンポーネント)
:プレイヤー1: as Player1
:プレイヤー2: as Player2
(あなたのすべての兵士を+1する) as Act1 <<能力>>
(あなたはダメージを受けなくなる) as Act2 <<能力>>
(速攻魔法を起こす際に\nコストを支払わなくてよい) as Act3 <<能力>>
Player1 ---> (Act1) : "能力"
Player1 ---> (Act2) : "能力"
P1C --> (Act3) : "能力"
Player2 ---> (Act1) : "能力"
Player1 ..> P1C : "所有"

@enduml

Fig. 6.5 能力のイメージ

注釈

7版までは、能力に誘発能力と常在型能力がありました。 8版からは、誘発型能力とアクションを起こせる能力をアクションの定義側に移動しました。 能力はそれ以外の常在型能力を示すものになりました。

6.4. コアフロー

今まで説明してきた概念を用いて コアフローの具体的な処理 を説明します。 この図は ゲームの開始から勝敗が決まるまでの流れ(コアフロー) を示しています。(Fig. 6.6)

BlackPokerはこのコアフローに則りリクエストが処理されます。

アナログゲーム用に作成したコアフローであるため、なるべく記憶する容量を減らすように設計しています。 デジタルゲームに応用する場合は、細部をゲームに合わせて変更してください。

@startuml
start
:[1] ゲーム開始;
:[2] ターンプレイヤーにチャンスを移動;
repeat
if ([3] アクションをリクエストするか?) then (Yes)
    :[4] パス記録のリセット;
    :[5] アクションをリクエストする;
    :[6] 誘発チェック;
    if ([7] 即時か?) then (Yes)
        :[8] リクエストの解決;
        if ([9] 勝敗判定) then (決着)
            stop
        endif
    else (No)
        :[10] ステージに追加;
    endif
    :[6] 誘発チェック;
else (No)
    :[11] パス記録に登録;
    if ([12] 全員がパスしたか?) then (Yes)
        :[13] ルールシステムにチャンスを移動;
        if ([14] ステージにリクエストが存在するか?) then (Yes)
            :[15] 最後のリクエストを解決;
            if ([9] 勝敗判定) then (決着)
                stop
            endif
            :[6] 誘発チェック;
        else (No)
        endif
        :[2] ターンプレイヤーにチャンスを移動;
    else (No)
        :[16] チャンス移動;
    endif
endif
repeat while()
@enduml

Fig. 6.6 コアフロー

[1] ゲーム開始

先攻を決め、ゲームを始める準備を行います。

[2] ターンプレイヤーにチャンスを移動

ターンを持っているプレイヤーにチャンスを移動します。

[3] アクションをリクエストするか?

チャンスを持っているプレイヤーはアクションを起こすかを判断します。

[4] パス記録のリセット

パスしたプレイヤーの記録をリセットします。

[5] アクションをリクエストする

アクションをリクエストし、これからプレイヤーが行うことを宣言します。 ゲームによってアクションをリクエストする方法は異なります。 BlackPokerではアクション名を言い、コストの支払や対象を指定しアクションをリクエストします。 一方ババ抜きでは、隣のプレイヤーからカードを引く際に宣言せず暗黙にアクションがリクエストされている場合もあります。

このときに有効になっている能力を考慮します。 能力の適用順については 6.4.2 能力の適応順 参照してください。

[6] 誘発チェック

ここに至るまでに誘発したアクションがないかチェックします。 誘発した場合、対象のアクションをリクエストします。 詳しいフローは 6.4.1 誘発チェック を参照してください。

[7] 即時か?

リクエストのスピードが即時か判定します。

[8] リクエストの解決

アクションの効果に定義されている内容を実行します。 その他にコンポーネントを捨て山に移動するなどゲームによって決まった処理があれば行います。 アクションの解決の中でも効果に定義されている内容を実行することのみを指す場合「効果を発揮する」と言います。

このときに有効になっている能力を考慮します。 能力の適用順については 6.4.2 能力の適応順 参照してください。

[9] 勝敗判定

ゲームの勝敗を判定します。決着した場合ゲームが終了します。判定の方法はゲームにより異なります。

[10] ステージに追加

リクエストをステージに追加します。

[11] パス記録に登録

パスしたプレイヤーを記録します。パス記録がリセットされるため、同じプレイヤー名は2回登録されません。

[12] 全員がパスしたか?

パス記録に全てのプレイヤー名が記録されているか判定します。

[13] ルールシステムにチャンスを移動

ルールシステムにチャンスを移動します。

[14] ステージにリクエストが存在するか?

ステージにリクエストが存在するか判定します。

[15] 最後のリクエストを解決

最後にステージに追加されたリクエストを解決します。 解決方法は [8] リクエストの解決 参照してください。 ステージ上のリクエストを解決する場合、 [8] リクエストの解決 を行った後、次の内容も合わせて行います。

  • リクエストをステージから取り除く

[16] チャンス移動

チャンスを持っているプレイヤーからチャンスを持っていないプレイヤーにチャンスを移動します。 チャンスを移動するルールはゲームによって異なります。

6.4.1. 誘発チェック

アクションの中には誘発条件を持っているアクションがあります。 誘発条件に該当した場合、アクションからリクエストが誘発されます。

誘発チェックでは、誘発したリクエストを解決またはステージに追加します。 誘発したリクエストのコントローラーは起因となったアクションのオーナーがコントローラーとなります。 誘発チェックは次の図のように行います。(Fig. 6.7)

注釈

バッファ

誘発したリクエストを一時的に溜めておくバッファという領域があります。正式名称はアクションバッファです。

@startuml
'==============================
'【Main method】(アクション分類・プレイヤー毎処理)
'==============================
|Main method|
start
:[6-1] 誘発したアクションを分類しバッファに追加;
note right
    「即時/通常 × メイン/クイック」で分類
end note
note right
    誘発したアクションのコントローラーは
    起因となったアクションのオーナー
    になります。
end note

while ([6-2] バッファは空か?) is (No) 
  ' 外部ループ:バッファに何らかのアクションが残っている限り処理する

  '-------------------------------------------
  '【即時:プレイヤー毎に処理】
  '-------------------------------------------
  while ([6-3] バッファに即時はあるか?) is (Yes)

    group 即時: プレイヤー毎に処理
    note
        順番はターンプレイヤーから
        ターンが回る順に行う
    end note

      while ([6-4] 該当プレイヤーに即時があるか?) is (Yes)
        :[6-5] タイミング=メインの即時アクションを処理;
        note right
          別フロー呼び出し
        end note
        :[6-6] タイミング=クイックの即時アクションを処理;
        note right
          別フロー呼び出し
        end note
        :[6-7] 次のプレイヤーへ;
      endwhile (No)
    end group
  endwhile (No)

  '-------------------------------------------
  '【通常:プレイヤー毎に処理】
  '-------------------------------------------
  while ([6-8] バッファに通常はあるか?) is (Yes)

    group 通常: プレイヤー毎に処理
    note
        順番はターンプレイヤーから
        ターンが回る順に行う
    end note

      while ([6-9] 該当プレイヤーに通常があるか?) is (Yes)
        :[6-10] タイミング=メインの通常アクションを処理;
        note right
          別フロー呼び出し
        end note
        :[6-11] タイミング=クイックの通常アクションを処理;
        note right
          別フロー呼び出し
        end note
        :[6-12] 次のプレイヤーへ;
      endwhile (No)
    end group
  endwhile (Yes)

endwhile (Yes)
stop
@enduml

Fig. 6.7 誘発チェック

[6-1] 誘発したリクエストを分類しバッファに追加

各プレイヤーが誘発させたリクエストを、スピードおよび タイミングに基づいて分類し、一旦バッファに追加します。

[6-2] バッファは空か?

バッファが空であるかどうかを判定します。 未処理のリクエストが残っている場合は、以降の処理ループを継続します。

[6-3] バッファに即時はあるか?

バッファ内にスピードが即時のリクエストが存在するかを判定します。 存在する場合、 ターンプレイヤーから順に即時の処理グループへ進みます。

[6-4] 該当プレイヤーに即時があるか?

現在処理対象となっているプレイヤーがコントローラーとなっているリクエストがバッファにあるかを確認します。 スピードが即時のリクエストが存在するかを判定し、 存在しない場合は、そのプレイヤーでの処理を終了し、次のプレイヤーへ移行します。

[6-5] タイミング=メインの即時アクションを処理

該当プレイヤーについて、タイミングが「メイン」、スピードが「即時」のアクションを実行します。 詳細は 6.4.1.1 誘発即時解決 をタイミング=メインとして参照してください。

[6-6] タイミング=クイックの即時アクションを処理

同じプレイヤーについて、タイミングが「クイック」、スピードが「即時」のアクションを実行します。 詳細は 6.4.1.1 誘発即時解決 をタイミング=クイックとして参照してください。

[6-7] 次のプレイヤーへ

現在のプレイヤーでの処理が完了した後、 ターン順に次のプレイヤーへ処理を移行します。

[6-8] バッファに通常はあるか?

バッファ内にスピードが通常のリクエストが存在するかを判定します。 存在する場合、 ターンプレイヤーから順に即時の処理グループへ進みます。

[6-9] 該当プレイヤーに通常があるか?

現在処理対象となっているプレイヤーがコントローラーとなっているリクエストがバッファにあるかを確認します。 スピードが即時のリクエストが存在するかを判定し、 存在しない場合は、そのプレイヤーでの処理を終了し、次のプレイヤーへ移行します。

[6-10] タイミング=メインの通常アクションを処理

該当プレイヤーについて、タイミングが「メイン」、スピードが「通常」のアクションを実行します。 詳細は 6.4.1.2 通常:アクション毎に処理 をタイミング=メインとして参照してください。

[6-11] タイミング=クイックの通常アクションを処理

同じプレイヤーについて、タイミングが「クイック」、スピードが「通常」のアクションを実行します。 詳細は 6.4.1.2 通常:アクション毎に処理 をタイミング=クイックとして参照してください。

[6-12] 次のプレイヤーへ

現在のプレイヤーでの処理が完了した後、 ターン順に次のプレイヤーへ処理を移行します。

注釈

各処理グループ内では、必ずターンプレイヤーから始まり、 ターンが回る順に全プレイヤーに対して確認およびアクションの処理を実施します。 また、ループはバッファに未処理のアクションが存在する限り繰り返されます。

6.4.1.1. 誘発即時解決

誘発チェックで誘発したスピードが即時のリクエストを処理します。 呼び出し元で指定されたプレイヤーおよびタイミングに基づいて処理します。 誘発チェックは次の図のように行います。(Fig. 6.8)

@startuml
'==============================
'【即時:アクション毎に処理】
'==============================

start
while ([6-5-1] バッファから該当の即時はあるか?) is (Yes)
  :[6-5-2] バッファからリクエストを取り出す;
  :[6-5-3] 取り出したリクエストを解決する;
  if ([6-5-4] 勝敗判定) then (決着)
    stop
  endif
  if ([6-5-5] リクエストが新たな誘発を発生させたか?) then (Yes)
    :[6-5-6] 誘発したリクエストをバッファに追加;
    note left
      誘発したリクエストのコントローラーは
      起因となったアクションのオーナー
      になります。
    end note
  endif
endwhile (No)
stop
@enduml

Fig. 6.8 誘発チェック-即時処理

[6-5-1] バッファから該当の即時はあるか?

バッファから対象プレイヤーかつ、該当するタイミングかつ、スピードが即時のリクエストが存在するかを判定します。 存在する場合、以降の処理へ進み、存在しなくなるまでこのループを継続します。

[6-5-2] バッファからリクエストを取り出す

条件を満たしたリクエストを、バッファから1つ取り出します。 どのリクエストを取り出すかは対象プレイヤーが決定します。 取り出されたリクエストは、解決処理の対象となります。

[6-5-3] 取り出したリクエストを解決する

取り出されたリクエストの効果を実行し、解決します。 詳しくは [8] リクエストの解決 参照してください。

[6-5-4] 勝敗判定

勝敗を判定します。 詳しくは [9] 勝敗判定 参照。

[6-5-5] リクエストが新たな誘発を発生させたか?

効果の解決後、それが起因となり新たな誘発を発生させたかどうかを確認します。 発生している場合は、その誘発アクションを再度バッファに追加する必要があります。

[6-5-6] 誘発したリクエストをバッファに追加

新たに誘発されたリクエストが存在する場合、該当アクションをバッファに追加します。 これにより、再帰的なアクション処理が可能となり、次のループで該当するリクエストの取り出し処理が実行されます。

6.4.1.2. 通常:アクション毎に処理

誘発チェックで誘発したスピードが通常のリクエストを処理します。 呼び出し元で指定されたプレイヤーおよびタイミングに基づいて処理します。 誘発チェックは次の図のように行います。(Fig. 6.9)

@startuml
'==============================
'【通常:アクション毎に処理】
'==============================

start
while ([6-10-1] バッファから該当の通常はあるか?) is (Yes)
  :[6-10-2] バッファからリクエストを取り出す;
  if ([6-10-3] 取り出したリクエストのタイミングがメインか判定) then (Yes)
    if ([6-10-4] ステージが空か判定) then (Yes)
      :[6-10-5] リクエストをステージに追加;
    else (No)
      :[6-10-6] リクエストを破棄;
    endif
  else (No)
    :[6-10-7] リクエストをステージに追加;
  endif
  if ([6-10-8] リクエストが新たな誘発を発生させたか?) then (Yes)
    :[6-10-9] 誘発したリクエストをバッファに追加;
    note left
      誘発したリクエストのコントローラーは
      起因となったアクションのオーナー
      になります。
    end note
  else (No)
  endif
endwhile (No)
stop
@enduml

Fig. 6.9 誘発チェック-通常処理

[6-10-1] バッファから該当の通常はあるか?

バッファから対象プレイヤーかつ、該当するタイミングかつ、スピードが通常のリクエストが存在するかを判定します。 存在する場合、以降の処理へ進み、存在しなくなるまでこのループを継続します。

[6-10-2] バッファからリクエストを取り出す

条件を満たしたリクエストを、バッファから1つ取り出します。 どのリクエストを取り出すかは対象プレイヤーが決定します。 取り出されたリクエストは、解決処理の対象となります。

[6-10-3] 取り出したリクエストのタイミングがメインか判定

取り出したリクエストのタイミングが「メイン」であるかどうかを判定します。 「Yes」と判定された場合は、ステージへの追加前に空き状況の確認へ進みます。 「No」の場合は、クイックタイミングとして処理を行います。

[6-10-4] ステージが空か判定

タイミングがメインの場合、そのリクエストをステージに追加できるかどうか、 すなわちステージに空きがあるかを判定します。

[6-10-5] リクエストをステージに追加

ステージが空いている場合、取り出したリクエストをステージに追加します。

[6-10-6] リクエストを破棄

ステージが埋まっている場合、取り出したタイミングがメインのリクエストを破棄します。

[6-10-7] リクエストをステージに追加

取り出したリクエストのタイミングが「クイック」である場合、 ステージの空き状況にかかわらず無条件でリクエストをステージに追加します。

[6-10-8] リクエストが新たな誘発を発生させたか?

リクエストをステージに追加した後、それが起因となり新たな誘発を発生させたかどうかを確認します。 誘発が発生している場合は、後続の処理でアクションバッファへの追加が行われます。

[6-10-9] 誘発したリクエストをバッファに追加

新たに誘発されたリクエストが存在する場合、該当アクションをバッファに追加します。 これにより、誘発処理の再実行が可能となります。

6.4.2. 能力の適応順

複数の能力が同時に有効になった場合、効果の内容によっては矛盾を引き起こす可能性があります。 その場合は、次の 6.4.2.2 能力の適用ルール に沿って能力を解釈してください。

なお、ゲームによって細部の裁定が異なる場合があります。ここでは BlackPoker を例に説明します。

6.4.2.1. 考え方の原則

影響範囲が広い能力ほど優先順位を低く扱い、影響範囲が狭い(個別の対象を限定する)能力ほど優先順位を高く扱います。 つまり、「広く浅く影響する能力」は先に適用し、「狭く深く影響する能力」は後から適用します。

6.4.2.2. 能力の適用ルール

  1. 能力を分類する 各能力を「影響範囲」に注目して、次の 3 つに分類します。

    [1] 全ての (all)
    • ゲームの場全体、または全プレイヤーなど「すべて」を有効範囲に含む能力です。

    • 例: 「全ての♠の兵士はサイズを1加算する」など。

    [2] あなたの (your)
    • あなたの場や、あなたがコントロールしているコンポーネントだけを有効範囲にする能力です。

    • 例: 「あなたの兵士はドライブ状態でも攻撃できる」など。

    [3] この (this)
    • 対象のコンポーネントインスタンス 1 つを有効範囲にします。

    • 例: 「この兵士はサイズを3加算する」「対象の兵士のサイズを2減算する」など。

  2. 能力を適用する 上記で分類した番号の小さい順、すなわち [1] → [2] → [3] の順で能力を適用します。

    1. [1] 全ての (all)

      まず「全ての ~」といった広範囲を対象とする能力を先に処理します。

    2. [2] あなたの (your)

      次に「あなたの ~」等、特定プレイヤーやその場を限定する能力を処理します。

    3. [3] この (this)

      最後に、個別のコンポーネント単位でより限定的な能力を処理し、必要に応じて上書きします。

    同じ範囲で矛盾した能力がある場合 それらの能力が発動(または有効化)された順番に応じて “タイムスタンプ” が古いものから適用し、 新しいものが後から上書きする形で処理します。

    このように、同時に有効な効果が互いに矛盾する場合でも、最終的により限定的な効果が優先されます。

6.4.2.3. 運用上の注意

  • 複数の「同じ範囲」の能力同士の扱い

    たとえば「全ての兵士は攻撃できない」という能力と、「全ての兵士のサイズはこのターン中1加算される」という能力が同じ “[1] 全ての (all)” 範囲に当たる場合、どちらも基本的には同時に成立し共存します。ただし、まったく相反する内容で整合が取れない場合は、対戦ルールやジャッジの裁定に従ってください。

  • 適用タイミング

    能力の適用は、コアフロー内の特定のステップでまとめて行います。何度か再適用が行われる場面があっても、適用のたびに「[1] → [2] → [3]」の順でまっさらな状態から再計算します。そのため、兵士のサイズが重複して加算され続けるようなことはありません。

  • 互いに矛盾しない場合

    たとえば「全ての兵士のサイズを -1」「あなたの兵士はさらに +2」「この兵士はさらに +3」という 3 つの効果が同時に有効なとき、BlackPoker ではサイズ 0 以下でも兵士が場に存在し続けられるため、最終的にその兵士には合計 +5 の修正が加わります。特に抵触しないかぎりすべて重複適用されます。

  • 互いに矛盾する場合

    「全ての兵士は攻撃できない」と「この兵士は攻撃できる」というように真っ向から対立する効果が同時に発生した場合、最終的には範囲の狭い「この兵士は攻撃できる」の方が優先されます。

以上のルールが、複数の能力が同時に有効になった場合の処理基準となります。

6.5. まとめ

コアルールについて説明しました。 すでにあるターン制のゲームからアクションを洗い出し、能力を整理することで割込処理を可能としゲームの新しい遊び方が見つけられます。 また、新しく作成するゲームに関してもコアルールを意識して作成することで、ルール追加がしやすいゲームが考えやすいと思います。