冒険先の生成 - kjirou/hello-adventurers-core GitHub Wiki

🗺️ 冒険先の生成の概要

  • Adventure Destination(冒険先) とは、プレイヤーが冒険者パーティを選択し操作してクリアを目指す、具体的な冒険先の1つのことである
    • この中には、難易度・敵・罠・報酬など、冒険を行うにあたり必要な情報が全て入っている
  • 冒険先の内容は、基本的に設定値よる制御を加えたランダム生成である

🤔 冒険先の生成の存在意義

  • プレイヤーにとって冒険とは、パーティビルドの成果を、冒険への準備・冒険中の操作・勝利を得る、それぞれの過程で実感する場である
  • 多様なパーティビルドに対して多様な冒険先を用意して、その間に相性が存在するようにすることで、楽しい意思決定を提供する

🐦 生成手順の概要

  • 以下のような3段階の生成フローである
    • 1)キャンペーンは、クエストと共に Adventure Destination Query(冒険先要求) をランダム生成する
    • 2)冒険先要求から Adventure Destination Blueprint(冒険先設計図) をランダム生成する
    • 3)冒険先設計図から冒険先をランダム生成する
  • 段階が分かれている理由
    • A と B,C との境目は、A までがキャンペーン上のギミックや難易度を考慮するレイヤーとするため
      • 例えば、冒険レベル上昇に従い敵が徐々に強くなるような配慮はここまでで行う
      • B,Cは渡された設定値通りに生成するのみ
      • これを分けないと、固定の冒険先を定義しにくくなる
    • B と C との境目は、さほど理由がなく、ランダム生成を複数回行う箇所があるので、途中の状態を管理しやすいように値の定義をしたかったため

1️⃣ Adventure Destination Query(冒険先要求)の生成

プロパティ

  • 📁 Adventure Destination Query(冒険先要求)
    • Adventure Level(冒険レベル)
    • Necessary Progression(必要進行度)
    • Location Candidates(目的地候補リスト)
    • Enemy Candidates(敵候補者リスト)
      • [単純構成ID]
    • Enemy Quality Adjustment(敵品質補正)
    • Boss Id(ボスID)?
    • Enable Invisible Dungeon Cards(不可視有効フラグ)
      • 生成せずキャンペーン側で難易度調整目的で個別設定、初期はOff

Adventure Level(冒険レベル)の生成

  • 冒険の主たる難易度の指標
  • キャンペーン側から渡す

Necessary Progression(必要進行度)の生成

  • 冒険のクリアに必要な進行度の累計
    • プレイヤーが取得した進行度がこの値以上になると場札へ出口カードを出す
  • 通常は 50
    • 最序盤から序盤は少し下げるかもしれない

Location Candidates(目的地候補リスト)の生成

Location(目的地)

  • 目的地により、ダンジョンカードの内容に傾向が決まる
    • 出来事・地形を決めた結果、総枚数も決まる
    • また、冒険先の名称へ「洞窟」「森」のような文言を含める演出上の役割もある
  • 屋内と屋外で基準値を決め、その値との差分のみ明示的に定義する
    • 屋内の基準値
      • 地形: 通路6,十字路6,迷路6,大広間6,小部屋6
      • 出来事: 罠6,固有イベント5,宝箱3,キャンプ1、残りは戦闘で15
      • 強敵数: 3
    • 屋外の基準値
      • 地形: 道6,交差路6,複雑な地形6,広場6,洞6
      • 出来事: 罠6,固有イベント5,宝箱3,キャンプ1、残りは戦闘で15
      • 強敵数: 3
  • データ定義の方針
    • 地形は、どんなに少なくても一種類3枚は残す
      • 出来事の配置ができなくなるため
    • 地形や出来事は、多くすると特定のスキルでの稼ぎに使える点に注意
    • 罠の数は、屋内に比べて屋外はやや少なめ
      • 罠を考えるのが難しいので、いっそ傾向にしてしまう
  • Location(目的地)のプロパティや下記表の補足
    • Enemy Encounter Tendency(敵出現傾向)
      • {パーティメンバー最小数}-{パーティメンバー最大数},{敵品質}
名前 出現 地形 出来事 強敵 敵出現傾向 抽選罠数,罠の種類 不可視率 備考
屋内
Cave(洞窟) - - - 1-9,-1 3,矢の罠・崩落・毒ガス・トラバサミ・落とし穴・警報 120%
Ruins(廃墟) - - +1 1-9,-1 3,矢の罠・崩落・トラバサミ・警報・炎のルーン・冷気のルーン 100%
Labyrinth(迷宮) 迷路+4,大広間-2,小部屋-2 罠+6 - 1-3,+1 4,刃の振り子・酸のスプレー・圧殺天井・スパイク床・炎のルーン・冷気のルーン・電撃のルーン・無限回廊 150%
Catacombs(地下墓地) 大広間-1,小部屋+1 罠+2 +1 3-5,0 3,刃の振り子・毒ガス・スパイク床・冷気のルーン・太古の呪い・死の鐘 120%
Fort(砦) 迷路-2,小部屋+2 罠-2 +2 5-9,-1 2,矢の罠・警報・炎のルーン・電撃のルーン 100%
Valut(宝物庫) - 宝箱+3 +5 1-9,0 3,酸のスプレー・落とし穴・トラバサミ・警報・炎のルーン・冷気のルーン・電撃のルーン・太古の呪い 120%
屋外
Wasteland(荒野) - 罠-2 - 1-9,-1 2,落石・落とし穴・羽蟲の群れ・トラバサミ 80%
Plains(平原) 十字路-1,迷路-2,大広間+3 罠-3 -1 3-9,-2 2,羽蟲の群れ・カマイタチ・落雷・濃霧・魔力の澱み 50%
Forest(森) 十字路+2,迷路+1,大広間-2,小部屋-1 罠+3 - 1-7,-1 3,羽蟲の群れ・棘の蔦・濃霧・魔力の澱み・幻惑の道 120%
Mountains(山) - - +1 1-7,0 3,落石・落とし穴・崖崩れ・落雷・マナ地雷 100%
Settlement(集落) 通路-1,迷路-2,大広間+1,小部屋+2 罠-2 +2 3-7,0 2,トラバサミ・警報・炎のルーン・冷気のルーン 80%
Mystic Forest(迷いの森) 通路-1,迷路+3,大広間-2 罠+4 - 1-7,0 4,羽蟲の群れ・棘の蔦・濃霧・魔力の澱み・幻惑の道・無限回廊 160%
Sacred Site(聖地) - 宝箱+2 +3 1-9,0 3,カマイタチ・落雷・マナ地雷・太古の呪い・死の鐘 80%

目的地候補リストの生成

  • キャンペーン毎の設定により、キャンペーン進行度に応じて、候補が変わる
    • 序盤は癖がないものを小数にする

Enemy Candidates(敵候補者リスト)の生成

  • 大枠の生成手順
    • どの Enemy Group(敵グループ) を使うかを決める
    • その中から、敵グループの設定した範囲の数の敵を選択して、敵候補者リストにする
  • Enemy Group(敵グループ)
    • 「ゴブリン」「炎」などのテーマに沿った敵の単純構成IDリスト
      • 基本的には、3-12くらいの範囲で、Tierを少なくとも3段階の範囲で散らして、グルーピングする
      • 同じ敵が複数のグループへ所属しても良い
    • キャンペーンに対して、数十グループ設定する
    • 敵グループのプロパティ
      • 名前
      • 敵リスト
        • [単純構成ID]
      • 選択数設定
        • 最小と最大 or 固定 or 敵グループ全員
  • 敵グループの平均戦力
    • Tier別戦力の合計 / 敵の数 = 敵グループの平均戦力
    • Tier別戦力の計算
      • Tierが1上がる毎にx1.5、2から3の間だけはx2.0
        • この意図は、Tier3から個性を持った敵やリーター的な敵の定義になり、大きくかわるから
      • 一覧
        • Tier 1 = 1
        • Tier 2 = 1.5
        • Tier 3 = 3
        • Tier 4 = 4.5
        • Tier 5 = 6.75
  • 敵グループのランダム選択
    • 手順
      • 敵グループ指標値を決める
        • 敵グループ指標値 = 冒険レベル / 2、最低0、最高40
      • 敵グループリスト内の使用する範囲を決める
        • 敵グループリストを平均戦力で低い順に並べる
        • 敵グループリストを、最小要素が全要素に対する敵グループ指標値%・最大要素が最小要素+60%、の範囲のみになるように抽出する
          • 例えば、敵グループリストの要素が100個のとき
            • 敵グループ指標値 0 なら、低い順に 0 から 59 番目の要素まで選択
            • 敵グループ指標値 5 なら、低い順に 5 から 64 番目の要素まで選択
            • 敵グループ指標値 40 なら、低い順に 40 から 99 番目の要素まで選択
        • つまり、冒険レベルの上昇に応じて、強い敵が多く含まれる敵グループが選択されやすくなる
          • 冒険レベル80でMax
    • 上記で抽出した敵グループリストから、ランダムで1つ選択する
  • 敵候補者リストを決める
    • 最終的に1つ選択した敵グループの中から、なるべくTier別に同じ数になるようにランダム選択する
    • 手順
      • 選択済みの敵の数にTier別に偏りがある場合、抽出対象リストからそのTierの敵を除外する
      • 1体をランダム選択する
      • 敵グループの選択数分、繰り返す

Enemy Quality Adjustment(敵品質補正)の生成

  • 冒険先設計図の敵品質へ加算する値
  • デフォルト 0 で、設定しても +1 までの想定
  • ギルドクエストは +1、地域クエストも報酬増加と連動して +1 するものがある

Boss Id(ボスID)の生成

  • 単純構成IDまたは空を設定する
  • ギルドクエストの場合は50%・地域クエストの場合は25%で、敵候補者リストの最も高いTierの敵からランダム選択して設定

2️⃣ Adventure Destination Blueprint(冒険先設計図)の生成

プロパティ

  • 📁 Adventure Destination Blueprint(冒険先設計図)
    • 冒険レベル
    • 必要進行度
    • 目的地
    • 📁 ダンジョンカード設定
      • 地形別枚数設定
        • {地形種別}: 枚数
      • 不可視枚数
      • 出現固有イベント種別設定:
        • [{固有イベント種別}]
      • キャンプ数
      • 固有イベント数
      • 宝箱数
      • 罠数
      • 強敵数
      • 警戒度比率:
        • {警戒度}: 出現比率
    • 📁 敵設定
      • 📁 一般戦闘設定
        • パーティ別最大メンバー数
        • パーティ別最小メンバー数
        • 敵候補者リスト
        • 敵品質
      • ボス単純構成ID?

各項目の生成手順

  • 冒険者レベル
    • 冒険者要求からコピー
  • 必要進行度
    • 冒険者要求からコピー
  • 目的地
    • 目的地候補リストから重み付けランダム選択する
      • 高=8,中=4,低=2,稀=1
  • 地形別枚数設定
    • 目的地から派生
  • 不可視枚数
    • = 総枚数 * 冒険レベル(上限100)% * 0.3 * 目的地の不可視率枚(切り上げ)
    • 不可視有効フラグがOffなら0枚
  • 出現固有イベント種別設定
    • 全ての固有イベントを登録
  • キャンプ数・固有イベント数・宝箱数・罠数・強敵数
    • 目的地から派生
  • 警戒度比率
    • {0:80, 1:20} 固定
  • パーティ別最大メンバー数・パーティ別最小メンバー数
    • 目的地から派生
  • 敵候補者リスト
    • 冒険者要求からコピー
  • 敵品質
    • = 目的地の派生値 + 敵品質補正
  • ボス単純構成ID
    • 冒険者要求からコピー

3️⃣ 冒険先の生成

ダンジョンカードの生成

  • 手順
    • A)地形別枚数設定に従い、地形だけを設定したダンジョンカードリストを生成する
    • B)固定で出口カード1枚生成する
      • 山札へは追加しない
    • C)進行度を1から5の整数の範囲で均等に割り振る
      • ランダムではなく均等に設定する
        • 例えば、30枚なら、1から5までそれぞれ6枚になる
        • 5の数で割り切れない余りは、期待値が変わらないように割り振る
    • D)不可視枚数分のダンジョンカードを、ランダム選択して不可視にする
    • E)キャンプ出来事をキャンプ数分、配置可能な地形のダンジョンカードへランダムに配置する
      • 配置できる地形がない場合は消失する
        • なお、出来事の消失は後ほど発生するので、プレイヤーに有利な出来事順に配置するべき
          • キャンプ>宝箱なのは、キャンプが小部屋にしか置けないから
    • F)宝箱カードを宝箱数分、配置可能な地形のダンジョンカードへランダムに配置する
      • 配置できる地形がない場合は消失する
    • H)固有イベント出来事を設定する
      • 配列の要素順に処理をする
      • その固有イベントを配置可能な地形のダンジョンカードへランダムに配置する
      • 配置できる地形がない場合は消失する
    • I)罠出来事を罠数分、配置可能な地形のダンジョンカードへランダムに配置する
      • 配置できる地形がない場合は消失する
    • J)残りのカードの内容を戦闘出来事で埋める
    • K)強敵数の分、ランダム選択した戦闘カードへ強敵化のフラグを設定する
    • L)戦闘カード・出口カードの敵パーティの内容を生成する
      • 出口カードはボス単純構成IDが存在する時のみ
      • 敵パーティの生成をする
        • 詳細は後述
      • 警戒度の設定
        • ボス・強敵化フラグを持つ場合: 警戒度へ1を設定
        • その他の場合: 警戒度比率に従った警戒度を設定
    • M)罠の内容を生成する
      • 詳細は後述
    • N)シャッフルする

👿 敵パーティの生成

ボスの生成

  • ボス単純構成IDが存在すればボスが存在する冒険になる
  • インスタンス化して、ボススキルを付与し、敵インスタンスリストへ追加する

敵メンバーの生成

数の決定

  • 手順
    • 最小数を決める
      • 固定で1、わざわざ宣言しているのは後で調整しやすいようにするため
    • 最大数を決める
      • 固定で9、わざわざ宣言しているのは後で調整しやすいようにするため
    • 最小数から最大数の間を重み付けランダム選択する
      • 中央値が出やすいように調整する
      • 平均値と最小値or最大値の差を出す
      • 差+1を基準出現比率として、平均値からメンバー数の差を出現比率から差し引く
        • 最小1から最大5,平均3,差+1=2
          • 1名=1,2名=2,3名=3,4名=2,5名=1
        • 最小1から最大9,平均5,差+1=5
          • 1名=1,...,5名=5,...,9名=1
        • 最小2から最大5,平均3.5,差+1=2.5
          • 2名=1,3名=2,4名=2,5名=1

敵の種類の決定

  • 敵品質に応じて、敵のTierに対する抽選度合いを決める
  • 敵品質
    • -2以下
      • -1の出現比率の二乗が出現比率
        • Tier4,3,2 が出現する場合は、Tier4=1,Tier3=4,Tier2=9の出現比率
        • Tier4,3,1 が出現する場合は、Tier4=1,Tier2=4,Tier1=16の出現比率
    • -1
      • 出現敵の中で最小のTierを1として、それより上のTierはその差を加算する。それの反比例が出現比率。
        • 最も自然な配分で、これが標準的な扱いである
        • Tier4,3,2 が出現する場合は、Tier4=1,Tier3=2,Tier2=3の出現比率
        • Tier4,3,1 が出現する場合は、Tier4=1,Tier2=2,Tier1=4の出現比率
    • 0
      • Tier無関係に同じ出現比率
    • +1
      • -1の反比例
    • +2以上
      • -2以下の反比例
  • 敵を1体ずつ、出現比率による重み付けランダムで抽選する

インスタンス化

  • 上記の処理に従いインスタンス化し、敵インスタンスリストへ追加

エリート化

  • 強敵化フラグが渡された場合、パーティ全員へエリートスキルを付与する
    • ボス化とは重複しない

リーダー化

  • パーティには1人のリーダーが存在する
  • 選択フロー
    • ボスが存在すれば必ずリーダー
    • そうでなければ、Tierが高いクリーチャーから一人をランダム選択
  • 統率スキル決定
    • ボスの場合: 弱 or 中 or 強 を同じ比率でランダム選択
    • その他の場合: 弱:3 or 中:2 or 強:1 の比率でランダム選択

フィールドへ配置

  • 配置フロー
    • 敵を配置順用に整列する、なるべく重要な敵から配置するため。以下は優先順位が高い整列基準の順番。
        1. リーダーである
        1. Tierが高い
    • 敵インスタンス別にループ
      • 空きマスがなければ、最後に敵インスタンスリストから除外できるようにして、終了
      • 敵移動方式別に配置比率を決める
        • 列の位置
          • 密着・近接の場合) 1マス目:2マス目:3マス目 = 2:2:1
          • 射撃・遠隔の場合) 2マス目:3マス目:4マス目 = 1:2:2
          • 間合いの場合) 2マス目:3マス目:4マス目 = 1:1:1
          • その他の場合) 全てのマスで等分
        • 行の位置
          • 全てのマスで等分
      • 埋まっているマスを除外して、配置比率による重み付けランダムで決定

🪤 罠の生成

!!!罠の種類の設定が必要で、かつ罠のデータ定義が必要!!!

🗣️ 補足・Tips

敵パーティの生成はどういう方針だと楽しいのか?

  • まず、逆の発想で避けるべき結果を考えてみる
    • 冒険選択時に適切なパーティの選択がしにくい
      • 敵の種類や出現パターンが多すぎて、情報として実質無意味
    • どんなパーティでも勝利できる
      • Aボタン連打で勝てるくらい敵が弱い
        • これはパーティ生成時に考慮する問題ではない
  • 何が楽しいか?
    • 冒険単位で傾向があると、パーティ選択時の相性パズルをしやすいので楽しい
      • 例えば、敵の傾向が一定に寄せてあると、相性パズルをしやすい
        • → 出現する敵の種類を系統別にする
      • 例えば、敵の数と強さの傾向を一定に寄せてあると、これも相性パズルをしやすい
        • → 強めの敵が少しだと弱体や防御の長期戦が有用、弱めの敵が多くだと全体火力が有用
  • 特に楽しさへ寄与しなさそう
    • パーティ単位の戦力を平準化する
      • パーティ生成をコスト制にして、強力な敵を少し or 弱い敵の多く or その中間のいずれかになるようにする
      • → 冒険上の工夫で回避できるし、それも楽しさの一部なので、逆に無い方が良さそう
    • 冒険単位の戦力を平準化する
      • → 冒険を選択時に回避できるので、なくても問題は少なさそう

進行度を1から5以外の幅にする意味はある?

  • 思いつかなく、なさそう
  • 期待値を変える意図なら必要進行度の方で調整すれば良いし、分散を調整する意味が思いつかなかった

敵候補者リスト生成周りの仕様の目的

  • 複雑でこれでええんかという気はするが、目的はあってそれを表現した結果ではあるので、目的を記しておく
  • 目的
    • A)ひとつの冒険先に出現する敵の種類は、一定数以下になるように制御したい
      • 最終的に敵グループをそのまま選択対象にしないのはこのため
      • あまりに種類が多いと、プレイヤーが対策として相性が良いパーティを割り当てにくくなるから
    • B)冒険者レベルに応じて、強い敵の種類が出る頻度を上げたい
      • 冒険者レベル自体に敵を強化する効果はあるが、強化の曲線として足りないので、強い敵をより多く抽選することも行いたい
      • また、出現する敵を遷移することで、飽きないようにしたい
    • C)Bを考慮しつつ、弱い敵も出したい
      • 飽きないようにするため
      • これは不要な配慮かもしれない
    • D)変化はなるべく連続的にしたい
      • 例えば、「冒険レベル20ずつ変わる」のようにしたくなかった
        • その閾値を覚えて対策すると大きく有利になる可能性が出てしまうため
        • つまり覚えるのが必須になってしまうかもしれない
      • 最終的に、覚えてハックしてくれることをプレイヤーに期待してもいいのかもしれないが、今の段階ではこちらの仕様にした
    • E)敵の定義時に全体とのバランスを考えないようにしたい
      • 平均戦力比という概念は、敵のTierだけ考えて付与すれば、いい感じに難易度と連動できるかなという目的で作った
      • しかし、そんな上手い話があるとも思えないので、実際に破綻したなら、ちゃんと敵グループに対してTierを付与するようにした方が良い