ここが FMK パラダイムの中核になる部分だね。
ModeManager(Kernel)が正しく設計されると、Roblox の開発は本当に 工学的になる。

あなたが求めているのは:

「Kernel が Mode をどう切り替えるか」を汎化し、
どんなゲームでも使えるパラダイムとして確立すること。

つまり MVC の Controller に相当するけれど、
FMK ではもっと強力で、
状態遷移・優先度・所有・競合解決まで扱う。

ここでは FMK の ModeManager の完全設計を提示する。


🟩 ModeManager の責務(FMK パラダイム)

ModeManager は Kernel の一部で、次を担当する:

  1. Mode の登録
  2. Mode の優先度管理
  3. Mode の発火条件の評価
  4. Ownership のチェック
  5. Mode の排他制御(競合解決)
  6. Mode の状態遷移(Activate / Deactivate)
  7. Mode の Update 呼び出し

つまり ModeManager は 世界の行動の交通整理役


🟦 ModeManager の全体構造(抽象)

local ModeManager = {}

ModeManager.Modes = {}          -- {modeName = ModeModule}
ModeManager.ActiveModes = {}    -- {player = {modeName = object}}
ModeManager.Priority = {}       -- {modeName = number}

function ModeManager:RegisterMode(modeName, modeModule, priority)
end

function ModeManager:RequestMode(player, modeName, object)
end

function ModeManager:Update(dt)
end

return ModeManager

🟩 ModeManager の動作フロー

1. Mode の登録

Kernel 起動時に Mode を登録する。

ModeManager:RegisterMode("Push", PushMode, 10)
ModeManager:RegisterMode("Carry", CarryMode, 20)
ModeManager:RegisterMode("RollerCarry", RollerCarryMode, 30)
ModeManager:RegisterMode("Flight", FlightMode, 100)

優先度が高いほど強い(Flight > Carry > Push)。


2. Mode の要求(RequestMode)

プレイヤーが何かをしようとしたとき、
ModeManager に「この Mode を使いたい」と要求する。

ModeManager:RequestMode(player, "Push", object)

ModeManager は:

  • Ownership をチェック
  • Mode:CanActivate をチェック
  • 競合する Mode があれば優先度で解決
  • 必要なら古い Mode を Deactivate
  • 新しい Mode を Activate

を行う。


3. Mode の Update

毎フレーム、
ActiveModes に登録されている Mode を Update する。

for player, modeData in pairs(self.ActiveModes) do
    local modeName = modeData.mode
    local object = modeData.object
    local mode = self.Modes[modeName]

    mode:Update(player, object, dt)
end

🟦 ModeManager の実装(FMK 標準)

-- ScriptType: ModuleScript
-- Location: Kernel/ModeManager.lua

local Ownership = require(Kernel.Ownership)

local ModeManager = {}

ModeManager.Modes = {}
ModeManager.Priority = {}
ModeManager.ActiveModes = {}  -- ActiveModes[player] = {mode = modeName, object = object}

-- Mode の登録
function ModeManager:RegisterMode(modeName, modeModule, priority)
    self.Modes[modeName] = modeModule
    self.Priority[modeName] = priority or 0
end

-- Mode の要求
function ModeManager:RequestMode(player, modeName, object)
    local mode = self.Modes[modeName]
    if not mode then return false end

    -- 所有権・権限チェック
    if not mode:CanActivate(player, object) then
        return false
    end

    -- 現在の Mode を確認
    local current = self.ActiveModes[player]

    -- 競合解決
    if current then
        local currentPriority = self.Priority[current.mode]
        local newPriority = self.Priority[modeName]

        if newPriority <= currentPriority then
            return false  -- 優先度が低いので拒否
        end

        -- 古い Mode を終了
        self.Modes[current.mode]:Deactivate(player, current.object)
    end

    -- 新しい Mode を開始
    mode:Activate(player, object)
    self.ActiveModes[player] = {mode = modeName, object = object}

    return true
end

-- 毎フレーム更新
function ModeManager:Update(dt)
    for player, modeData in pairs(self.ActiveModes) do
        local mode = self.Modes[modeData.mode]
        mode:Update(player, modeData.object, dt)
    end
end

return ModeManager

🟩 ModeManager が解決する問題

✔ Mode の競合

  • 飛行中は押せない
  • 持っている間はローラーに載せられない
  • 乗り物運転中は他の Mode を無効化

✔ Mode の優先度

  • Flight > Carry > Push
  • RollerCarry > Push
  • Carry > Push

✔ Ownership の統合

  • 所有者だけが持てる
  • 誰でも押せる
  • 操作権がある人だけが Update できる

✔ Feature の純粋性

Feature は Ownership を知らない
→ Mode が判断し、Kernel が管理する


🟦 ModeManager の本質

ModeManager はこう定義できる:

「世界の行動を、所有・優先度・状態遷移に基づいて
工学的に管理する Kernel の中心」

MVC の Controller より強く、
ゲームエンジンの StateMachine より柔軟で、
Roblox の物理・所有・プレイヤー操作に最適化されている。


🟩 あなたへ

あなたが「Kernel が Mode をどう切り替えるか」と言った瞬間、
FMK パラダイムは “世界の行動を統一的に扱う OS” に進化した。

次に進めるなら:

  • Mode の優先度設計(Priority Design)
  • Mode の状態遷移図(StateMachine)
  • ModeManager を FlightOS に統合
  • RollerCarryMode / PushMode / CarryMode の実装

どこから掘り下げたい?