メインコンテンツまでスキップ

アーキテクチャ概要

このガイドは、MCE の C# ソースコード全体にアクセスできる Source / Studio エディションのユーザー向けです。

モジュールアーキテクチャ

矢印は意図的に一方向にしか向いていません。Core は Online にもインポーターにも決して依存せず、 だからこそオンラインレイヤーは、README 上だけでなく本当の意味でオプションになれます。

このドキュメントでは、モジュール階層、アセンブリ構造、依存性注入のパターン、そして Monster Capture Engine を構成する主要なランタイムシステムを扱います。

モジュール階層​

MCE は、レイヤードアーキテクチャに従うモジュールで構成されています。

Assets/
OpenMon/
Core/
Runtime/ # Core engine (REQUIRED)
Initialization/ # Engine startup, first-time wizard
Monster/ # MonsterInstance, Roster, evolution, breeding
MonsterDatabase/ # ScriptableObject definitions (species, moves, items, abilities)
Battle/ # BattleManager, 15 modules, state machine, AI
Characters/ # MCECharacterController, PlayerCharacter, followers
Actors/ # Actor system, CommandGraph visual scripting
World/ # GridController, GlobalGridManager, tiles, encounters
Saves/ # SavegameManager, SavableObject, GameVariables
Player/ # GlobalGameData, player state
UI/ # All UI controllers and views
Quests/ # Quest system (objectives, rewards, tracking)
SDK/ # Public API interfaces
GameFlow/ # Game state management
Configuration/ # ScriptableObject configs
Rendering/ # URP shaders, time-of-day, weather
Audio/ # AudioSettingsManager, AudioConfiguration (the playback engine is in Foundation)
Localization/ # Multi-language support
Badges/ # Badge tracking
Input/ # Input abstraction
MonsterDex/ # Dex tracking (seen/caught)
Animation/ # Animation utilities
WorldGenerator/ # Procedural region generator
Licensing/ # Tier and license checks
Shaders/ # Shader source files
Editor/ # Editor-only tooling
MonsterCreator/ # Monster creation wizard
Tools/ # Database Browser, Type Chart Editor, validators
Followers/ # Follower spritesheet tools
Actors/ # CommandGraph editor
Hub/ # The OpenMon Hub window
MapEditor/ # Scene View map painting overlays
Callbacks/ # Editor callback utilities

依存ルール​

  1. Core Runtime は、Online や Importer モジュールへの外部依存を一切持ちません。
  2. オンライン機能は、MCE_ONLINE スクリプティング define シンボルでオプトインします。
  3. エディターコードは、.asmdef の境界によってランタイムから厳密に分離されます。
  4. Runtime/SDK/ の SDK インターフェースは、コンパイル済み(DLL)エディションのユーザー向けのパブリック API の範囲です。

アセンブリ構造​

MCE は、Unity の Assembly Definition を使ってコンパイルの境界を強制します。

アセンブリ場所目的参照
OpenMon.Foundation.RuntimeFoundation/Runtime/共有フレームワーク:DI、オーディオ、ローカライズ、シーン管理、トゥイーンZenject と Unity パッケージ
OpenMon.Foundation.EditorFoundation/Editor/Foundation のエディターツールFoundation Runtime + UnityEditor
OpenMon.MCE.RuntimeCore/Runtime/コアのゲームシステムFoundation のライブラリのみ
OpenMon.MCE.EditorCore/Editor/エディターツールRuntime + UnityEditor
OpenMon.Hub.EditorCore/Editor/Hub/OpenMon Hub ウィンドウ(インポーターとオンラインのツールを名前で呼び出すため、どちらにも依存しません)Foundation Runtime
MCE.Online.RuntimeOnline/Runtime/Nakama ネットワーキングRuntime + Nakama SDK
MCE.Online.EditorOnline/Editor/オンラインのエディターツールOnline Runtime + UnityEditor
MCE.EssentialsImporter.RuntimeImporter/Runtime/PBS/rxdata のパーサーとインポートの検証Runtime + KaitaiStruct
MCE.EssentialsImporter.EditorImporter/Editor/インポートパイプラインRuntime + KaitaiStruct
OpenMon.SetupSetup/パッケージ依存関係のインストーラーとクイックセットアップなし(意図的に分離)
MCE.Runtime.TestsCore/Tests/Runtime/Core のプレイモードテストRuntime + NUnit
MCE.Editor.TestsCore/Tests/Editor/Core のエディットモードテストRuntime + Editor + NUnit

Assembly Definition が重要な理由​

  • コンパイルの分離:エディターコードの変更が、ランタイムの再コンパイルを引き起こしません。
  • 依存関係の強制:コンパイラーが、ランタイムがエディターの API を参照するのを防ぎます。
  • ビルド時の除外:エディターのアセンブリは、プレイヤービルドから除外されます。
  • テストの分離:テストアセンブリは、本番で公開することなく、内部を参照できます。

依存性注入(Zenject)​

MCE は、依存性注入に、インストーラーパターンを備えた Zenject(Extenject)を使います。

インストーラーパターン​

各サブシステムは、バインディングを登録する独自のインストーラーを持ちます。ほとんどは ScriptableObject のインストーラーで、バトルランチャーのものが典型的です。

[CreateAssetMenu(menuName = "MCE/Dependency Injection/Battle Launcher Installer",
fileName = "BattleLauncherInstaller")]
public class BattleLauncherInstaller : LazySingletonScriptableInstaller<BattleLauncher>
{
public override void InstallBindings()
{
Reference.Reset();

Container.QueueForInject(Reference);

Container.Bind<IBattleLauncher>().FromInstance(Reference).AsSingle().Lazy();
}
}

BattleLauncher 自体が ScriptableObject(アセット)であり、インストーラーのアセットがそれを指しています。依存性注入 のページに、すべてのインストーラーが一覧されています。

主要なインストーラー​

インストーラーバインドするもの
GameFlowInstallerコアのゲームフローのサービス
PlayerCharacterInstallerPlayerCharacter、キャラクターのサービス
BattleLauncherInstallerIBattleLauncher、バトルのエントリポイント
GridInstallerシーンのグリッド(MonoInstaller)
SceneInfoInstallerSceneInfo、シーンのメタデータ
WorldDatabaseInstallerWorldDatabase、グローバルなマップデータ
TileDataInstallerタイルタイプのデータ
GlobalGridManagerInstallerマップ間のナビゲーション
SavegameInstallerSavegameManager、シリアライズ
EvolutionManagerInstallerEvolutionManager

規約​

  • バインディングは、規約として .AsSingle().Lazy() です(単一のインスタンスで、初回使用時に作成)。
  • [Inject] は、コンストラクターではなく Construct() メソッドで使います。
  • 実行時の UI のインスタンス化には、DialogManager.Factory パターンを使います。
  • シーンスコープのインストーラー(たとえば MonoInstaller の GridInstaller)は、シーンごとのサービスを扱います。
  • プロジェクトスコープのインストーラー(ProjectContext プレハブ上の ScriptableObject アセット)は、グローバルなサービスを扱います。

注入ポイント​

public class SomeManager : MonoBehaviour
{
// Field injection (for MonoBehaviours).
// Note: of the SDK interfaces, only IMonsterCaptureEngine is bound —
// take Database/Battle/Player/SaveSystem from its properties.
[Inject] private IMonsterCaptureEngine engine;

private IBattleSystem battle;

private void Awake()
{
battle = engine.Battle;
}

// Method injection (preferred for explicit dependencies on engine-internal types)
[Inject]
public void Construct(MCESettings settings, MonsterDatabaseInstance database)
{
this.settings = settings;
this.database = database;
}
}

主要なランタイムシステム​

MCEInitialization のフロー​

MCEInitialization は、ゲームの開始時に最初に実行されるものです。

1. Screen setup (resolution, orientation)
2. Load databases (monsters, moves, items, abilities)
3. Download localization data (if remote)
4. Run first-time wizard (if needed)
5. Initialize subsystems (save manager, audio, input)
6. Signal ready
7. Load main menu or continue saved game

これは、シーンのロードをまたいで存続する永続的な GameObject 上の MonoBehaviour です。

モンスターシステム​

モンスターのデータモデル:

MonsterEntry (ScriptableObject - species definition)
├── Base stats, types, abilities
├── List<DataByFormEntry> (private per-form overrides)
├── DataByFormEntry.Evolutions: List<EvolutionData> (evolution paths)
└── Move lists (level-up, TM, egg, tutor)

MonsterInstance (runtime - individual monster)
├── Species reference (MonsterEntry)
├── Level, XP
├── IVs[6], EVs[6]
├── Nature
├── Current HP, Status
├── MoveSlot[4] (with PP)
├── Friendship, OT data
└── Form index

Roster (party of up to 6 MonsterInstances)
MonsterStorage (PC boxes)

バトルシステム​

詳細は バトルの内部 を参照してください。

ワールドシステム​

GlobalGridManager (cross-map navigation)
└── GridController (per-scene grid)
├── TileData grid (collision, type per tile)
├── EncounterTile zones
└── SceneInfo (metadata)

MCECharacterController (movement)
├── PlayerCharacter (input + encounters)
└── ActorCharacter (NPC AI movement)

セーブシステム​

SavegameManager
├── MCESavesSerializer (JSON read/write)
├── SavableObject[] (registered savables)
└── GameVariables (global state)

コードスタイル​

コードベースは、次の規約に従います。

  • 4 スペースのインデント、波括弧は新しい行に。
  • パブリックな型、メソッド、プロパティは PascalCase。
  • プライベートなフィールドとローカルは camelCase。
  • public フィールドより [SerializeField] private。
  • Runtime/ と Editor/ は .asmdef の境界で分離。
  • Conventional Commits:feat:、fix:、docs:、refactor:。
シリアライズされたフィールド

移行計画なしに、シリアライズされたフィールドの名前を変更してはいけません。シーンとプレハブは、シリアライズされたフィールド名に依存しています。名前変更には [FormerlySerializedAs("oldName")] を使ってください。

エンジンの拡張​

新しいシステムの追加​

  1. Runtime/YourSystem/ にクラスを作成します。
  2. 依存性注入のためのインストーラーを作成します。
  3. インストーラーを、適切なシーンコンテキストまたはプロジェクトコンテキストに追加します。
  4. セーブデータが必要なら、SavableObject を拡張します。
  5. エディターツールがあるなら、Editor/YourSystem/ にクラスを作成します。

既存システムの変更​

  1. 既存のコードを読み、モジュールの依存関係を理解します。
  2. 変更が、修正ではなく設定や拡張で実現できないか確認します。
  3. 修正する場合は、そのモジュール内の既存のパターンに従います。
  4. 変更をカバーするようにテストを更新します。
  5. 変更をコミットメッセージに記録します。

パフォーマンス上の考慮事項​

  • SDK を通じたデータベースの検索(GetMonster(dexNumber)、GetMonster(name))は、種のリストを走査します。頻繁に呼ぶ場合は、エントリをキャッシュしてください。
  • バトルモジュールはバトルの GameObject のコンポーネントで、ターンごとではなく、バトルごとに 1 回、一緒に作成されます。
  • 大きなタイルマップは、1 歩ごと、1 フレームごとのコストが高くなります。非常に大きなマップは、接続された複数のシーンに分割してください(グリッドベースの移動 の Neighbours を参照)。
  • セーブのシリアライズは、メインスレッドで同期的に行われます。セーブデータのサイズは妥当に保ってください。
  • CommandGraph の実行はコルーチンベースです。ノードが多い複雑なグラフはイベントスクリプティングには問題ありませんが、フレームごとのロジックには使うべきではありません。