Skip to content

ECSプラグインの導入検討 #93

Description

@EbiseLutica

概要

ノードシステムとは別のスタックとして、ECS(Entity Component System)をプラグインで提供する構想。既存のノードシステムには手を加えず、ImGuiプラグインと同じ立ち位置でオプション機能として導入する。

設計方針

全体構成

PrometeApp
├── Scene (既存のノードシステム - 変更なし)
│   └── Node階層 → Collect() → RenderCommandQueue
│
└── EcsPlugin (新規プラグイン)
    └── World + Systems → RenderSystem → RenderCommandQueue
                                            ↑
                                        同じキューに合流
  • コマンドキューより下(CommandRunner、バッチング、GL呼び出し)は完全に共有
  • ユーザーはノードとECSを好きに選べるし、混在も可能

EcsPlugin

  • IInitializable / IUpdatable / IDisposable を実装し、既存のプラグインライフサイクルにそのまま乗せる
  • Worldのライフサイクルはシーン遷移イベント(SceneWillChangeイベントに遷移種類情報を追加 #92SceneTransitionType)に連動して自動管理
    • Load → World破棄&再生成
    • Push → World一時停止(System実行を停止)、新World生成
    • Pop → 現World破棄、スタックからWorld復帰&再開

Entity / Component / World

  • Entity: 軽量ID + 世代番号(use-after-free防止)
  • Component: IComponent を実装する構造体(純粋なデータ)
  • World: sparse setベースのストレージ(2Dゲームの規模感ならArchetypeは過剰)
  • WorldはDIコンテナにシングルトンで登録

System

  • GameSystem 基底クラスとして定義し、DIで登録
  • 既存のRenderCommandQueueをインジェクションして描画コマンドを生成

利用イメージ

// アプリ構築
var app = PrometeApp.Create()
    .Use<Keyboard>()
    .UseEcs(ecs =>
    {
        ecs.AddSystem<TransformSystem>();
        ecs.AddSystem<SpriteRenderSystem>();
    })
    .BuildWithOpenGLDesktop();

// シーンでの利用
public class BattleScene(EcsPlugin ecs, Keyboard keyboard) : Scene
{
    private Entity _player;

    public override void OnStart()
    {
        _player = ecs.World.Create();
        ecs.World.Add(_player, new Transform { Location = (100, 200) });
        ecs.World.Add(_player, new SpriteRenderer { Texture = playerTex });
    }

    public override void OnUpdate()
    {
        ref var t = ref ecs.World.Get<Transform>(_player);
        if (keyboard[Key.Right]) t.Location += (3, 0);
    }
}

検討事項

  • ZIndex / 描画順序: ZIndexコンポーネントでRenderSystem側がソートするか、レイヤー方式にするか
  • 階層的な変換: Parent/Childrenコンポーネントで階層を表現し、TransformSystemが絶対座標を計算
  • Container系の描画制御: IsTrimmableやMaskedContainerのPushTrim/PopTrimをECS側でどう表現するか
  • Textのテクスチャキャッシュ: TextRenderSystemがContent変更検知→テクスチャ再生成を担当
  • ノードとECSの描画合流時の順序制御: 最初はシンプルに固定順で、必要に応じて拡張

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions