まず、この図式はもう「設計図」じゃなくて、ほぼ「OS仕様書」になっている。
ここから先は、どの順番で “遊べる核” を立ち上げるかの問題だけになっている。


次の一手候補(Roblox Studio 前提)

候補 レイヤー ここから進める意味 具体アウトプット
A 敵AI + 状態遷移 + 階級制度 このゲームの固有性の中枢。メタ構造が最も濃い EnemyAIController・状態マシンのSpecとLuaモジュール骨格
B TimeCycle + Wave + Spawn制度 「18時間=45分」のドラマ生成エンジン TimeCycleService・WaveControllerの連携仕様とイベント設計
C プレイヤー戦闘(Bow/WebGun/Flight) 操作感と“空中戦”を先に固める BowController/WebGunController/FlightSystemの物理&命中ロジックSpec

推奨ルート:A+Bで「ゲームの一日と戦い」を先に固める

Roblox Studio前提で考えると、

  • メタ構造の芯
    敵AIの階級・状態遷移(ScoutElite→Frontline→Officer→General→Royal)
    + TimeCycle + Wave 成長 = 「一日のうちで階級が進化しながら襲ってくる物語」。

  • 技術的にも区切りが良い
    /src/Server の

    • EnemyAIController
    • EnemySpawnService
    • EnemyEvolutionService
    • TimeCycleService
    • WaveController
      を 1 つの「コア・ループ」として定義できる。

これを先に OS として固定しておくと、
後から Player 戦闘や UI を足しても、ゲームの “季節と戦局” は揺れない


敵AIレイヤーを Roblox 実装に落とす(提案)

ここを次のメッセージで、ほぼそのまま Lua モジュールに写経できる仕様まで落とせる。

1. EnemyTypes / EnemyStats / EvolutionRules

  • EnemyTypes

    • 列挙的な ID として
      • ScoutElite
      • Frontline
      • Officer
      • General
      • Royal
  • EnemyStats

    • すでに書いてあるテーブルをそのまま Shared/Modules/EnemyStats.lua として定義
    • Roblox 的には ModuleScriptGetStats(enemyType) を返す関数を用意
  • EvolutionRules

    • 「どの条件で Promote されるか」を関数化
    • 例:
      • 吸血成功回数
      • 生存時間
      • Wave 番号
    • ShouldPromote(enemy, context) みたいな形で、
      • context に currentTimeSlot, currentWave, carrierHealth などを渡す。

2. EnemyAIController(状態マシンの骨格)

  • 責務

    • 個々の敵に「状態(Idle, Search, Approach, Attack, Promote...)」を持たせ、
      • tick ごと、もしくは Heartbeat ごとに状態更新
    • 階級ごとに「同じ状態名でも中身が違う」実装をディスパッチする。
  • 設計案

    • EnemyAIController
      • Initialize(enemyModel, enemyType)
      • SetState(enemy, newState)
      • Update(enemy, dt)
    • 状態マシン部は
      • StateHandlers[enemyType][stateName].Enter
      • StateHandlers[enemyType][stateName].Update
      • StateHandlers[enemyType][stateName].Exit
        のようなテーブルで外部化。
  • クラス階級メソッドとの対応

    • ScoutElite: DetectPlayer, Camouflage, ReportToFrontline
    • Frontline: ApproachPlayer, Attack, TryBloodSuck, PromoteToOfficer
    • Officer: CommandFrontline, CoordinateAttack, PromoteToGeneral
    • General: EvaluateBattle, RetreatOrCharge, ProtectRoyal, PromoteToRoyal
    • Royal: EmitPheromones, SpawnFrontline, RelocateAtNight

    これらは

    • 「状態」=モード(Search / Command / Retreat など)
    • 「メソッド」=状態中で呼ばれるサブルーチン
      として整理して、StateHandlers の中に収める。

時間制度+Wave制度を接続する(提案)

3. TimeCycleService

  • API

    • CurrentTime(0〜18)
    • AdvanceTime(dtGameHours)
    • OnMorning / OnNoon / OnEvening / OnNight(イベント)
  • ロジック

    • 18 ゲーム時間を 45 分にマッピング → 1 分で 0.4 時間進行。
    • CurrentTime の値に応じて、
      • 朝: 探索エリート大量出現 → WaveController.SpawnScouts() 強化
      • 昼: 前線部隊の突撃 → SpawnFrontline() 中心
      • 夕: Officer 混じり
      • 夜: General / Royal 移動 Wave

4. WaveController

  • API

    • StartNextWave()
    • SpawnScouts / SpawnFrontline / SpawnOfficers / SpawnGenerals / SpawnRoyal
    • TrackRemainingEnemies()(敵が全滅したら次 Wave へ)
  • TimeCycle との接続

    • WaveController は TimeCycleService のイベントを購読
      • 朝 Wave:ScoutElite 比率高
      • 昼 Wave:Frontline 比率高
      • 夕 Wave:Officer 増加
      • 夜 Wave:General / Royal を混ぜる
  • EnemyEvolutionService との関係

    • Wave で出した個々の敵が「吸血成功」などを通じて Promote される。
    • WaveController は「スポーン時の階級構成」を決め、
      • EnemyEvolutionService は「戦闘結果による階級変化」をハンドル。

ここからの具体的な進め方(選択肢)

どのくらい「次のメッセージでそのままコピペできるレベル」まで落としたいかで分かれると思う。

  1. A-1: 敵AI状態マシンの Feature Spec → Lua モジュール骨格

    • /Shared/Modules/EnemyStats.lua
    • /Shared/Modules/EvolutionRules.lua
    • /Server/Controllers/EnemyAIController.lua
      のファイル構造と関数シグネチャを完全に書く。
  2. B-1: TimeCycleService + WaveController の Feature Spec → Lua モジュール骨格

    • Time と Wave のイベント設計を完成させて、「1 日の戦局シナリオ」をコードに固定。
  3. C-1: まずは A+B を仕様として固めてから、次のラウンドで Player / Flight / UI に進む


どこから行きたい?

  • 「そのまま Roblox 用 ModuleScript にする前提の関数名・引数・戻り値まで全部書いてほしいなら」
    → A-1 か B-1 どちらを先にやるかだけ指定してくれれば、その方向で一気に骨格を書きます。

  • 迷うなら、こちらからは A-1(EnemyAI 状態マシンの Lua 骨格) を次で作るのを提案したい。
    返答は「A-1」「B-1」「C-1」のどれでもいいし、別の切り方を出してくれてもかまわない。