# 機能設計書 43-C#サポート

## 概要

本ドキュメントは、Godot EngineにおけるC#スクリプト言語サポート機能（GodotSharp/Mono統合）について、設計仕様を記載する。

### 本機能の処理概要

C#サポートは、Microsoftの.NETランタイム（旧Mono）をGodot Engineに統合し、C#言語でゲームロジックを記述できるようにする機能である。.NET 6以降のCoreCLRランタイムを使用し、高性能な実行環境とVisual Studio/Rider等のIDEとの完全な連携を実現する。

**業務上の目的・背景**：多くの企業開発者にとってC#は既知の言語であり、大規模プロジェクトや既存の.NETライブラリ資産を活用したゲーム開発が可能となる。静的型付けによるコンパイル時エラー検出、リファクタリングツール、IntelliSense等の高度なIDE支援を受けられる。

**機能の利用シーン**：
- 大規模ゲームプロジェクトでの型安全な開発
- .NETライブラリ（NuGet）の活用
- Visual Studio/Rider等のIDEによる高度な開発支援
- チーム開発でのコード品質維持
- 既存C#資産の再利用

**主要な処理内容**：
1. .NETランタイム（CoreCLR/hostfxr）の初期化
2. GodotSharpアセンブリのロード
3. C#クラスとGodotノードのバインディング
4. プロパティ/メソッド/シグナルの相互運用
5. ホットリロードによる開発効率化
6. ガベージコレクション管理

**関連システム・外部連携**：MSBuild/dotnet CLI、NuGetパッケージマネージャー、Visual Studio/Rider IDE、デバッガー（vsdbg）と連携する。

**権限による制御**：[Tool]属性でエディタ内実行、[GlobalClass]属性でエディタへのクラス登録が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | スクリプトエディタ | 参照画面 | C#スクリプトの表示（外部エディタ連携推奨） |
| 30 | スクリプト作成ダイアログ | 主機能 | 新規C#スクリプトファイルの作成 |

## 機能種別

スクリプト実行 / 言語統合

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| script_path | String | Yes | C#スクリプトファイルパス | .cs拡張子 |
| assembly_path | String | No | コンパイル済みアセンブリパス | .dll拡張子 |
| class_name | String | Yes | C#クラス名 | 有効なC#識別子 |
| namespace | String | No | 名前空間 | 有効なC#名前空間 |

### 入力データソース

- .csソースファイル
- .csprojプロジェクトファイル
- .slnソリューションファイル
- NuGetパッケージ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CSharpScript | Script | C#スクリプトリソース |
| assembly | .dll | コンパイル済みアセンブリ |
| errors | List<ScriptError> | コンパイル/実行時エラー |

### 出力先

- プロジェクトアセンブリ（.godot/mono/temp/bin/）
- エクスポート時のアセンブリ埋め込み

## 処理フロー

### 処理シーケンス

```
1. ランタイム初期化
   └─ GDMono::initialize()
   └─ hostfxr/CoreCLR DLLロード
   └─ ランタイムホスト起動

2. アセンブリロード
   └─ _load_project_assembly()
   └─ GodotSharp.dllのロード
   └─ プロジェクトアセンブリのロード

3. スクリプトバインディング
   └─ CSharpScript::reload()
   └─ update_script_class_info()
   └─ プロパティ/メソッド情報抽出

4. インスタンス作成
   └─ CSharpScript::instance_create()
   └─ _create_instance()
   └─ GCハンドル管理

5. メソッド呼び出し
   └─ CSharpInstance::callp()
   └─ マネージド/アンマネージド相互運用

6. ガベージコレクション
   └─ mono_object_disposed()
   └─ GCハンドル解放
```

### フローチャート

```mermaid
flowchart TD
    A[C#スクリプト作成] --> B[MSBuildビルド]
    B --> C{ビルド成功?}
    C -->|No| D[コンパイルエラー表示]
    C -->|Yes| E[アセンブリ生成]
    E --> F[GDMono::initialize]
    F --> G[ランタイム初期化]
    G --> H[アセンブリロード]
    H --> I[CSharpScript登録]
    I --> J[TypeInfo抽出]
    J --> K[プロパティ/メソッド解析]
    K --> L[スクリプト使用可能]
    L --> M[instance_create]
    M --> N[マネージドオブジェクト作成]
    N --> O[GCハンドル取得]
    O --> P[Godotノードにアタッチ]
    P --> Q[実行]
    Q --> R{スクリプト変更?}
    R -->|Yes| S[ホットリロード]
    S --> H
    R -->|No| Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-01 | partial class必須 | Godotノードを継承するクラスはpartialが必要 | スクリプト定義時 |
| BR-43-02 | [Export]属性 | プロパティをエディタに公開 | エディタ編集時 |
| BR-43-03 | [Signal]属性 | C#デリゲートをGodotシグナルとして公開 | シグナル定義時 |
| BR-43-04 | [Tool]属性 | エディタ内でスクリプト実行を許可 | エディタツール開発時 |
| BR-43-05 | [GlobalClass]属性 | クラスをエディタのクラス一覧に登録 | グローバルクラス登録時 |

### 計算ロジック

- GCハンドル管理: MonoGCHandleDataでマネージドオブジェクト参照を保持
- 参照カウント: RefCountedを継承するオブジェクトは特別な参照管理

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CS0001〜 | コンパイルエラー | C#構文/型エラー | コード修正 |
| RUNTIME_ERROR | 実行時エラー | NullReferenceException等 | デバッガーで調査 |
| ASSEMBLY_LOAD_ERROR | アセンブリロードエラー | DLL不整合 | リビルド |
| GC_HANDLE_ERROR | GCハンドルエラー | メモリ管理問題 | コード見直し |

### リトライ仕様

ホットリロード時は自動リトライ（project_load_failure_countで管理）

## トランザクション仕様

該当なし

## パフォーマンス要件

- JITコンパイル: 初回実行時のウォームアップ
- AOTコンパイル: エクスポート時の事前コンパイルオプション
- ガベージコレクション: 世代別GCによる効率的なメモリ管理

## セキュリティ考慮事項

- アセンブリの署名検証
- サンドボックス実行（エクスポート時の制限）
- APIハッシュ検証（api_core_hash, api_editor_hash）

## 備考

- Godot 4.0以降は.NET 6+（CoreCLR）を使用
- Mono（旧ランタイム）はGodot 3.x系で使用
- iOS/WebではAOTコンパイルが必要

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、C#スクリプトの核となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | csharp_script.h | `modules/mono/csharp_script.h` | CSharpScript, CSharpInstance, CSharpLanguageクラス |
| 1-2 | mono_gc_handle.h | `modules/mono/mono_gc_handle.h` | MonoGCHandleData構造体 |
| 1-3 | gd_mono.h | `modules/mono/mono_gd/gd_mono.h` | GDMono、ランタイム管理 |

**読解のコツ**: CSharpScriptはScriptを継承し、GodotのスクリプトシステムとC#を橋渡しする。TypeInfo構造体がC#クラスのメタデータを保持。

#### Step 2: ランタイム初期化を理解する

.NETランタイムの起動プロセスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gd_mono.h | `modules/mono/mono_gd/gd_mono.h` | GDMonoクラス定義 |
| 2-2 | gd_mono.cpp | `modules/mono/mono_gd/gd_mono.cpp` | initialize()メソッド |

**主要処理フロー**:
- **60-66行目**: hostfxr/coreclr DLLハンドル
- **68-72行目**: プロジェクトアセンブリ管理
- **156-158行目**: should_initialize(), initialize()

#### Step 3: スクリプトバインディングを理解する

C#クラスとGodotノードの連携機構。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | csharp_script.h | `modules/mono/csharp_script.h` | TypeInfo構造体 |
| 3-2 | csharp_script.cpp | `modules/mono/csharp_script.cpp` | update_script_class_info() |

**主要処理フロー**:
- **65-126行目（TypeInfo）**: C#クラス情報（class_name, is_tool, is_global_class, is_abstract, ジェネリクス対応）
- **132-144行目**: valid, reload_invalidatedフラグ
- **177行目**: rpc_configでRPC設定
- **179-190行目**: event_signals, methodsベクター

#### Step 4: インスタンス管理を理解する

C#オブジェクトのライフサイクル管理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | csharp_script.h | `modules/mono/csharp_script.h` | CSharpInstanceクラス（307-386行目） |
| 4-2 | mono_gc_handle.h | `modules/mono/mono_gc_handle.h` | GCハンドル管理 |

**主要処理フロー**:
- **311-316行目**: owner, base_ref_counted, ref_dyingフラグ
- **319行目**: MonoGCHandleData gchandle
- **359行目**: mono_object_disposed()
- **365行目**: mono_object_disposed_baseref()

#### Step 5: 言語統合を理解する

CSharpLanguageによるGodotスクリプトシステムとの統合。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | csharp_script.h | `modules/mono/csharp_script.h` | CSharpLanguageクラス（401-592行目） |
| 5-2 | csharp_script.cpp | `modules/mono/csharp_script.cpp` | 各種メソッド実装 |

**主要処理フロー**:
- **410行目**: GDMono *gdmono
- **488-491行目**: ホットリロード関連メソッド
- **568-570行目**: reload_all_scripts(), reload_scripts()

### プログラム呼び出し階層図

```
GDMono::initialize()
    │
    ├─ hostfxr DLLロード
    │      └─ CoreCLRランタイム起動
    │
    ├─ _load_project_assembly()
    │      ├─ GodotSharp.dll ロード
    │      └─ プロジェクト.dll ロード
    │
    └─ CSharpLanguage::init()
           └─ スクリプトシステム登録

CSharpScript::reload()
    │
    ├─ update_script_class_info()
    │      ├─ C#リフレクションでクラス情報取得
    │      ├─ _add_property_info_list_callback()
    │      └─ _add_property_default_values_callback()
    │
    └─ TypeInfo更新
           ├─ class_name
           ├─ is_tool / is_abstract
           └─ is_global_class

CSharpScript::instance_create()
    │
    ├─ _create_instance()
    │      ├─ C#コンストラクタ呼び出し
    │      └─ GCハンドル取得
    │
    └─ CSharpInstance作成
           └─ Godotオブジェクトにバインド

CSharpInstance::callp()
    │
    ├─ マネージドメソッド呼び出し
    │      └─ P/Invoke相互運用
    │
    └─ 戻り値変換
```

### データフロー図

```
[入力]                      [処理]                         [出力]

.cs ソースファイル ───▶ MSBuild/dotnet CLI ───▶ .dll アセンブリ
                              │
                              ▼
                        GDMono ───▶ ランタイム初期化
                              │
                              ▼
                   CSharpLanguage ───▶ 言語登録
                              │
                              ▼
                    CSharpScript ───▶ TypeInfo抽出
                              │
                              ▼
                   CSharpInstance ───▶ オブジェクト生成
                              │
                              ▼
                       GCHandle ───▶ メモリ管理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| csharp_script.h | `modules/mono/csharp_script.h` | ヘッダー | CSharpScript/Instance/Languageクラス定義 |
| csharp_script.cpp | `modules/mono/csharp_script.cpp` | ソース | スクリプトクラス実装 |
| gd_mono.h | `modules/mono/mono_gd/gd_mono.h` | ヘッダー | .NETランタイム管理クラス |
| gd_mono.cpp | `modules/mono/mono_gd/gd_mono.cpp` | ソース | ランタイム初期化実装 |
| mono_gc_handle.h | `modules/mono/mono_gc_handle.h` | ヘッダー | GCハンドル管理 |
| mono_gc_handle.cpp | `modules/mono/mono_gc_handle.cpp` | ソース | GCハンドル実装 |
| godotsharp_defs.h | `modules/mono/godotsharp_defs.h` | ヘッダー | 定義・定数 |
| register_types.cpp | `modules/mono/register_types.cpp` | ソース | モジュール登録 |
| glue/ | `modules/mono/glue/` | ディレクトリ | C#-C++グルーコード |
| managed/ | `modules/mono/glue/GodotSharp/` | ディレクトリ | C#側のGodotSharpライブラリ |
| editor/ | `modules/mono/editor/` | ディレクトリ | エディタ統合機能 |
