MitiruEngine は C++ で書くゲームロジック と HTML/CSS/JS で書く UI を、薄い signal-only bridge で繋いだヘッダオンリーのゲームエンジンです。このページは、エンジンの中身を「速い部分」「遅い部分」「未対応の部分」まで含めて開示することを目的にしています。
1. 1 行サマリ
エンジンコア (game loop / scene / ECS / asset / audio / input / graphics / save / network / physics) は header-only な C++20 として include/mitiru/ 配下に展開され、#include <mitiru/Mitiru.hpp> 1 行から段階的に利用できます。画面に出る UI / HUD / 演出は CEF (Chromium Embedded Framework) 上の HTML/CSS/JS で組み、両者は「JS → C++ は入力 event のみ」「C++ → JS は view update のみ」という薄い bridge で連絡します。
2. レイヤー図
3 層構成です。矢印は bridge を通る方向と内容を示します。
コンポーネント図
C++ コアの主な subsystem と、CEF view 側で動く JS runtime を並べたものです。
データフロー (入力 → 状態 → 描画)
入力 → C++ ロジック → 状態更新 → 描画、という 1 フレームの大まかな流れです。
ビルドパイプライン
ソースからユーザに渡る実行ファイル (+ CEF runtime 同梱) までの流れです。
CEF プロセスモデル (single-process workaround の位置)
通常の CEF は複数プロセス構成ですが、本エンジンは現状 --single-process で 1 プロセスに集約しています (詳細は §5.3)。下図は両構成を並べたものです。
--single-process workaround。後者は GPU / V8 が host と同一プロセスに同居するため、クラッシュ分離を失う代わりに subprocess spawn 問題を回避している。詳細は §5.3。3. 技術スタック
実態は CMakeLists.txt、include/mitiru/、external/ から読み取った内容です。推測なし。
| 項目 | 採用 |
|---|---|
| 言語 | C++20 (cxx_std_20 を CMakeLists.txt で要求) |
| ビルドシステム | CMake 3.21+、cmake --preset default 対応 |
| 形態 | Header-only INTERFACE library (MITIRU_HEADER_ONLY=ON がデフォルト、約 700 個の .hpp) / STATIC ビルドも可 (MITIRU_HEADER_ONLY=OFF) |
| 対応 OS | Windows (primary、DX12 + CEF + DX11 が完動)、Linux / macOS (best-effort、Vulkan + OpenGL)、Emscripten (WebAssembly + WebGL2) |
| Graphics backend | DX12 / DX11 (Windows) / Vulkan (Linux + macOS via MoltenVK / Windows) / OpenGL (SDL2 or GLFW) / WebGL2 (Emscripten) / NullDevice (headless) |
| Window backend | Win32Window / GlfwWindow / Sdl2Window / WebGL canvas |
| UI 層 | CEF 128.4.12 (Chromium Embedded Framework)、MITIRU_DISABLE_CEF=ON で除外可 |
| JSON | nlohmann/json + NLOHMANN_DEFINE_TYPE_* マクロ規約 (詳細は §4) |
| Audio | miniaudio (デスクトップ) / WebAudio (Emscripten) / PulseAudio (Linux 検出時) / NullAudioEngine |
| Save schema | Versioned envelope + MigrationChain<T> (include/mitiru/data/SaveSchema.hpp) |
| Profiling | Tracy zones (include/mitiru/debug/TracyZones.hpp、オプション有効化) |
| Networking | GameNetworkingSockets opt-in (MITIRU_ENABLE_GNS=ON)、デフォルトは NullReliableTransport スタブ |
| 3rd-party (submodule) | sgc / mml / stb / tinyobjloader / miniaudio / cgltf / nanovg、Chromium 派生は CEF binary distribution として外部から取得 |
| Test framework | Catch2 v3 (ctest --test-dir build -C Debug)、最新 main で 2259 件 green |
| ライセンス | MIT |
4. 主要な設計判断
エンジン設計の根幹となる 3 つの判断を簡潔にまとめます。
- C++ ゲームプレイ + CEF は View 専用: 当初 hybrid runtime (gameplay を JS で書く) として開始しましたが、二言語境界の認知負荷、V8 GC 由来の frame drop、CEF subprocess 問題などから「gameplay は C++、CEF は view 専用」に方針転換しました。bridge は signal-only に絞り、状態は C++ 側に一元化しています。
- scripting 言語を embed しない: Lua / Squirrel / GDScript 等の embed をやめ、Siv3D をロールモデルに pure C++ 路線を採用しました。Lua VM / NodeGraph / LuaCodeGen 等を全削除しています。iteration speed は
MITIRU_HEADER_ONLY=ONの incremental compile と asset hot reload で確保します。 - JSON binding: nlohmann macros + Versioned envelope: codegen / external reflection に頼らず、
NLOHMANN_DEFINE_TYPE_INTRUSIVEベースの 1 行マクロとMigrationChain<T>で save / content / balance すべての JSON I/O を統一しました。std types を直接使う方針 (std::string/std::vector/std::optionalを独自エイリアスで隠さない) もこの延長です。
5. パフォーマンス特性
このセクションは「速い部分」「重い部分」「未対応の部分」を分けて、できるだけ正直に書きます。実測がない箇所は明示的に「未計測」と書きます。
5.1 速い部分
- C++20 gameplay は普通のネイティブ速度で動く: DX12 backend は Windows + GPU 環境で完動し、60 FPS を目標とした game loop が前提です。
include/mitiru/core/GameLoop.hppとFrameTimer.hppで固定タイムステップを実装しています。 - header-only による inline 効きやすさ:
MITIRU_HEADER_ONLY=ONがデフォルトのため、consumer 側の translation unit ごとに inline 最適化が効きます。トレードオフは consumer 側ビルド時間 (PCH 推奨)。 - bridge 通信量は基本的に小さい: JS → C++ は input event のみ、C++ → JS は view update のみで、典型的なフレームでは数 event / 数 KB 以下に収まります。
- ECS / scene graph は header-only:
include/mitiru/ecs/、include/mitiru/scene/配下に展開され、prefab / system scheduler / component registry を直接 inline 利用できます。
5.2 重い部分 (実測値の有無を明記)
- CEF の off-screen rendering pipeline: CEF は OSR (off-screen render) → C++ 側でテクスチャに転送 → GPU upload という経路で画面に出ます。1280x720 RGBA で 1 フレームあたり約 3.5 MB の転送が発生する計算で、60 FPS なら約 210 MB/s のバンド幅を消費します。これは無視できないコストです (帯域は理論値、実測スループットは未計測)。
- CEF の起動コストと配布サイズ:
libcef.dllだけで 100 MB 級、Resources/・locales/・*.pak一式を含めるとコールドスタート 1〜3 秒 (環境依存、実測は未取得)。CEF を使わないゲームにはMITIRU_DISABLE_CEF=ONを用意しています。 - ベースラインメモリ: CEF + Chromium + V8 を含む構成で常駐メモリは数百 MB オーダー (実測未取得)。軽量 2D ゲームには CEF を外す選択肢が現実的です。
- JS → C++ event レイテンシ: single-process 構成で 1〜3 ms 程度の目安 (Chromium IPC の公開ベンチからの推定で、本リポジトリでの実測は未取得)。60 FPS のユーザー操作には十分ですが、毎フレーム数百 event を要する用途には不向きです。
5.3 既知の制限
- CEF subprocess launch failed:
error_code=63: 一部の Windows 環境で GPU process が spawn できず FATAL 終了する問題が継続しています。現状の workaround として--single-processモードをinclude/mitiru/cef/MitiruCefApp.hpp:94-107に hard-coded しています。原因の最有力候補はlibcef.dll(Release/MD) と consumer 側 (Debug/MDd) の CRT mismatch で、cmake/MitiruCef.cmakeで subprocess 専用の/MDwrapper を分けてビルドする対策を入れています。詳細:docs/CEF_SUBPROCESS_DIAGNOSTIC.md/docs/CEF_CRT_EXPERIMENT.md。 --single-processモードの弊害: GPU process が分離されないため、CEF クラッシュがホストプロセスを巻き込みます。本番リリース向けにはリスクが残り、根本対策は継続調査中です。- Linux / macOS は best-effort: primary tested path は Windows + DX12 + CEF。Linux は Vulkan + GLFW、macOS は MoltenVK 経由を前提に検出ロジックを書いていますが、CI による全 backend テストの coverage は限定的です。
- WebGL build は実験段階: Emscripten 向けの WebGL2 backend (
include/mitiru/gfx/webgl/) と WebAudio は存在しますが、CEF は WebAssembly 環境では動かないため、UI 層の代替設計が必要です (現状未整備)。
5.4 ベンチ数値
現時点で公開できる数値は次のとおりです (実測なしの項目は「未計測」と明記)。
| 項目 | 値 |
|---|---|
| Catch2 テスト件数 | 2259 件 green (main、2026-05-15 時点) |
| Header-only ファイル数 | 約 700 個の .hpp |
| CEF テクスチャ転送 (1280x720 RGBA, 60 FPS) | 約 210 MB/s (理論値、実測未取得) |
| Frame budget (target 60 FPS) | 16.6 ms / frame (gameplay + render + CEF compositor) |
| ECS query / pathfinding / JSON parse スループット | 未計測 (公式 bench は今後追加予定) |
6. 他エンジンとの違い
特定エンジンを下げる意図はありません。同じ「2D + scripted scene 中心のゲーム制作」ニーズに対する、それぞれのアプローチの違いです。
| エンジン | アプローチ | 強み | MitiruEngine との違い |
|---|---|---|---|
| Unity | C# + visual editor + asset store | エコシステム規模、エディタ機能、商用サポート | MitiruEngine は scripting 言語を持たず、IDE エディタも提供しません。ゲーム作者の手は常に C++ にあります。 |
| Unreal Engine | C++ + Blueprint + visual editor | AAA 規模、フォトリアル、巨大エコシステム | MitiruEngine は 2D / UI 中心、ヘッダオンリー、配布バイナリが小さい設計です。 |
| Godot | GDScript + C# + 統合エディタ | OSS、軽量、エディタ統合 | MitiruEngine は IDE エディタを作らず、UI は HTML/CSS で書きます。 |
| Siv3D (OpenSiv3D) | Pure C++ ライブラリ、Main.cpp から書く |
C++ 学習向け、依存が少ない | MitiruEngine も pure C++ ですが、CEF を view 層として分離している点が違います。Siv3D は同一プロセスで全描画を完結します。 |
| Phaser / Pixi.js | JavaScript / TypeScript engine、Web first | Web 配布、ブラウザで即動く | MitiruEngine は native binary。CEF は UI 層に限定しており、gameplay は C++ で書きます。 |
7. ロードマップと制限事項
- IDE / visual editor は作らない方針: 人間 + テキストエディタ + asset hot reload で十分という前提です。エディタ統合のコストを払わない代わりに、C++ ヘッダの API surface を直接配布しています。
- 3D は 2D と同等の重みで開発中 (実態):
include/mitiru/render/には 3D 系ヘッダが多数あります —Camera3D/Mesh/Scene3D/Pipeline3D/GBuffer/DeferredPipeline/ShadowMap/ShadowSystem/SSAOEffect/DepthOfFieldEffect/TAAEffect/FSREffect/GlobalIllumination/VolumetricLighting/ClusteredLighting/MultiLightSystem/DecalSystem/Billboard3D/ParticleSystem3D/Sprite3DRenderer/OffscreenRenderer3D/GpuSkinning/SkeletalAnimation/InstancedRenderer/FrustumCulling/OcclusionCuller/LODSystem/Skybox/Cubemap/PBRMaterial/PBRShaders/NPRShaders3D/ToonPipeline/GltfLoader/ObjLoaderほか。3D physics はinclude/mitiru/physics/配下のPhysicsWorld3D/PhysicsSystem3D/RigidBody3D/Collider3D/BroadPhase3D/NarrowPhase3D/ContactSolver3D/Constraints3D/CollisionDetection3D/PhysicsDebugRenderer3D(10 ファイル) と、Jolt Physics 統合 (JoltPhysics.hpp、外部 submoduleexternal/jolt/がある場合に有効化、なければNullJoltPhysicsWorldスタブにフォールバック) で構成されます。描画 backend (DX12 / Vulkan / OpenGL) も 2D と 3D 両方を通します。残っているのは「3D 専用 example の本数を増やすこと」「Jolt 連携の安定運用検証」「production-grade な GI / PBR 仕上げの確認」で、エンジン基盤としては揃っています。 - 3D 用 example の拡充: 描画 / 物理ともにヘッダは揃っていますが、エンドツーエンドの 3D サンプル本数は 2D に比べてまだ少なめです。
include/mitiru/render/Renderer3D.hpp/Renderer3D_DX12.hpp/Scene3D.hppを使った最小サンプルを順次追加していく予定です。 - 3D physics (Jolt) の安定化: Jolt Physics は MSVC で CRT mismatch を避けるため
MSVC_RUNTIME_LIBRARYを明示的に揃えていますが (CMakeLists.txt第 489 行付近)、長時間運用での挙動確認は継続中です。Jolt が見つからない環境ではNullJoltPhysicsWorldスタブにフォールバックする仕組みになっており、3D physics が必須でない build もそのまま通ります。 - Multiplayer は実験段階:
include/mitiru/network/に抽象化はあるものの、GameNetworkingSockets 連携 (MITIRU_ENABLE_GNS=ON) はオプトインで、本番運用実績はまだありません。 - CEF subprocess 問題の根本対策:
--single-processworkaround 依存を解消する作業が継続中です (CRT mismatch 仮説の検証込み)。 - WebAssembly distribution: WebGL2 backend は存在しますが、CEF を前提とした UI を WebAssembly 上でどう代替するかは未着手です。
8. ソースと公開状況
- Engine source: GitHub mogmog-0110/MitiruEngine — MIT、public
- Site source: 本サイトのソースも上記 public リポジトリの
site/配下に同梱されています。 - API リファレンス: API Reference を参照