# 機能設計書 41-ENet

## 概要

本ドキュメントは、Godot Engineにおける高性能UDPネットワークライブラリ「ENet」の統合機能について、設計仕様を記載する。

### 本機能の処理概要

ENetは、信頼性のあるUDP通信を実現する高性能ネットワークライブラリであり、Godot Engineのマルチプレイヤーゲーム開発を支援する。TCPの信頼性とUDPの低レイテンシを組み合わせたハイブリッド通信を提供し、リアルタイムネットワークゲームに最適な通信基盤を構築する。

**業務上の目的・背景**：ゲーム開発において、プレイヤー間のリアルタイム同期は不可欠である。従来のTCP通信は信頼性が高いが遅延が大きく、UDP通信は高速だが信頼性が低い。ENetはこの課題を解決し、信頼性のある高速UDP通信を実現する。これにより、FPS、格闘ゲーム、MMORPGなど、低遅延が求められるマルチプレイヤーゲームの開発が可能となる。

**機能の利用シーン**：
- オンラインマルチプレイヤーゲームのサーバー/クライアント構成
- P2P（ピアツーピア）ゲームネットワーク
- リアルタイム協力・対戦ゲーム
- ロビーシステムやマッチメイキングサーバー

**主要な処理内容**：
1. ENetホストの作成と初期化（サーバー/クライアント/メッシュ構成）
2. ピア接続の確立と管理
3. パケットの送受信（信頼性モード選択可能）
4. 接続イベントの処理（接続/切断/受信）
5. 帯域幅制御とパケット圧縮
6. DTLS暗号化による安全な通信

**関連システム・外部連携**：MultiplayerPeerシステム、SceneMultiplayer、RPCシステムと連携し、高レベルなマルチプレイヤー機能を提供する。

**権限による制御**：サーバーモードとクライアントモードで異なる権限を持ち、サーバーは新規接続の拒否やピアの強制切断が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | 実行インスタンスダイアログ | 参照画面 | マルチプレイヤーテスト用の複数インスタンス実行設定 |

## 機能種別

データ連携 / ネットワーク通信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| port | int | Yes (server) | サーバーのリッスンポート | 0-65535の範囲 |
| max_clients | int | No | 最大接続クライアント数 | 1-4095（デフォルト32） |
| max_channels | int | No | 最大チャンネル数 | 0-255（0は最大値255） |
| in_bandwidth | int | No | 受信帯域幅制限 | 0以上（0で無制限） |
| out_bandwidth | int | No | 送信帯域幅制限 | 0以上（0で無制限） |
| address | String | Yes (client) | 接続先サーバーアドレス | 有効なIPまたはドメイン名 |
| bind_ip | IPAddress | No | バインドIPアドレス | 有効なIPまたはワイルドカード |

### 入力データソース

- GDScript/C#からのAPI呼び出し
- プロジェクト設定からのネットワーク設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Error | int | 操作結果（OK, ERR_ALREADY_IN_USE, ERR_CANT_CREATE等） |
| connection_status | ConnectionStatus | 接続状態（DISCONNECTED, CONNECTING, CONNECTED） |
| unique_id | int | ピアの一意識別子 |
| packet_data | PackedByteArray | 受信パケットデータ |
| peer_id | int | パケット送信元のピアID |

### 出力先

- ゲームロジックへのイベント通知（シグナル）
- 受信パケットバッファ

## 処理フロー

### 処理シーケンス

```
1. ホスト作成
   └─ create_server/create_client/create_meshの呼び出し
   └─ ENetConnectionの初期化
   └─ 接続状態の設定

2. 接続処理
   └─ (サーバー) ポートバインドと接続待機
   └─ (クライアント) サーバーへの接続試行
   └─ 接続イベントの発生

3. 通信ループ
   └─ poll()による定期的なイベント処理
   └─ パケット受信とキューイング
   └─ パケット送信（転送モード選択）

4. 切断処理
   └─ disconnect_peer()またはclose()
   └─ リソース解放
   └─ 切断イベントの通知
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{モード選択}
    B -->|Server| C[create_server]
    B -->|Client| D[create_client]
    B -->|Mesh| E[create_mesh]
    C --> F[ポートバインド]
    D --> G[サーバー接続試行]
    E --> H[メッシュID設定]
    F --> I[接続待機]
    G --> J{接続成功?}
    H --> K[ピア追加待機]
    J -->|Yes| L[CONNECTION_CONNECTED]
    J -->|No| M[エラー処理]
    I --> N[poll処理]
    L --> N
    K --> N
    N --> O{イベント種別}
    O -->|CONNECT| P[peer_connected通知]
    O -->|RECEIVE| Q[パケット受信]
    O -->|DISCONNECT| R[peer_disconnected通知]
    O -->|NONE| N
    P --> N
    Q --> N
    R --> S{全切断?}
    S -->|Yes| T[close]
    S -->|No| N
    T --> U[終了]
    M --> U
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | 一意ID検証 | クライアントIDは2以上かつ未使用であること | サーバー接続受付時 |
| BR-41-02 | サーバーID固定 | サーバーのunique_idは常に1 | サーバーモード時 |
| BR-41-03 | チャンネル予約 | システムチャンネル2個（RELIABLE/UNRELIABLE）は予約済み | パケット送信時 |
| BR-41-04 | 接続拒否 | is_refusing_new_connectionsがtrueの場合、新規接続をリセット | サーバー接続イベント時 |

### 計算ロジック

- ユーザーチャンネル番号 = 実チャンネル番号 - SYSCH_MAX + 1
- パケット最大サイズ = 2^24 バイト (約16MB)

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

本機能はデータベース操作を行わない（メモリ内データ構造のみ使用）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_ALREADY_IN_USE | 設定エラー | 既にアクティブな状態でcreate呼び出し | close()してから再作成 |
| ERR_CANT_CREATE | 作成エラー | ホスト作成失敗（ポート使用中等） | 別ポートで再試行 |
| ERR_INVALID_PARAMETER | パラメータエラー | 無効なピアIDやチャンネル番号 | パラメータ確認 |
| ERR_UNCONFIGURED | 状態エラー | 未接続状態でのパケット送信 | 接続完了後に送信 |

### リトライ仕様

ENetは内部で自動リトライを行う。タイムアウト設定（set_timeout）で制御可能。

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

該当なし（ネットワーク通信のため、パケット単位での送受信）

## パフォーマンス要件

- 同時接続: 最大4095クライアント
- パケット処理: poll()呼び出しごとに複数イベント処理可能
- 圧縮サポート: Range Coder, FastLZ, zlib, Zstd

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

- DTLS暗号化サポート（dtls_server_setup/dtls_client_setup）
- 不正クライアントID検証（ID < 2 または重複IDはリセット）
- 接続拒否機能（refuse_new_connections）

## 備考

- Godot独自のENet拡張（GODOT_ENET）でIPv6およびDTLSをサポート
- バニラENetではIPv4のみサポート

---

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

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

### 推奨読解順序

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

まず、ENetモジュールの主要なデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | enet_packet_peer.h | `modules/enet/enet_packet_peer.h` | ENetPacketPeerクラスの定義、PeerState/PeerStatistic列挙型 |
| 1-2 | enet_connection.h | `modules/enet/enet_connection.h` | ENetConnectionクラス、CompressionMode/EventType列挙型、Event構造体 |
| 1-3 | enet_multiplayer_peer.h | `modules/enet/enet_multiplayer_peer.h` | ENetMultiplayerPeerクラス、Mode列挙型、Packet構造体 |

**読解のコツ**: ENetはC言語ライブラリをラップしているため、`ENet*`型はC言語のenet構造体を内部で保持している。`peer->data`はGodot側のオブジェクトポインタを格納するために使用される。

#### Step 2: エントリーポイントを理解する

ENetMultiplayerPeerが主要なエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | enet_multiplayer_peer.cpp | `modules/enet/enet_multiplayer_peer.cpp` | create_server/create_client/create_meshメソッド |

**主要処理フロー**:
1. **60-75行目**: create_server - サーバーホスト作成、unique_id=1設定
2. **77-107行目**: create_client - クライアントホスト作成、接続試行
3. **109-128行目**: create_mesh - メッシュネットワーク初期化
4. **164-259行目**: poll - イベントループ処理（MODE_SERVER/CLIENT/MESH別）

#### Step 3: 接続管理を理解する

ENetConnectionが低レベルの接続管理を担当。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | enet_connection.cpp | `modules/enet/enet_connection.cpp` | ホスト作成とイベント処理 |

**主要処理フロー**:
- **45-67行目**: create_host_bound - アドレスバインド付きホスト作成
- **83-119行目**: connect_to_host - ピア接続処理
- **121-160行目**: _parse_event - ENetイベントのパース
- **162-186行目**: service - イベントサービス処理

#### Step 4: パケット送受信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | enet_multiplayer_peer.cpp | `modules/enet/enet_multiplayer_peer.cpp` | パケット送受信処理 |
| 4-2 | enet_packet_peer.cpp | `modules/enet/enet_packet_peer.cpp` | 低レベルパケット操作 |

**主要処理フロー**:
- **320-332行目**: get_packet - パケット受信
- **334-415行目**: put_packet - パケット送信（転送モード別処理）
- **130-144行目**: _store_packet - 受信パケットの格納

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

```
ENetMultiplayerPeer (高レベルAPI)
    │
    ├─ create_server() / create_client() / create_mesh()
    │      └─ ENetConnection::create_host_bound()
    │              └─ enet_host_create() [C API]
    │
    ├─ poll()
    │      └─ ENetConnection::service()
    │              ├─ enet_host_service() [C API]
    │              └─ _parse_event()
    │                      └─ ENetPacketPeer::_on_disconnect()
    │
    ├─ put_packet()
    │      ├─ enet_packet_create() [C API]
    │      ├─ ENetPacketPeer::send()
    │      │      └─ enet_peer_send() [C API]
    │      └─ ENetConnection::broadcast()
    │              └─ enet_host_broadcast() [C API]
    │
    └─ disconnect_peer() / close()
           ├─ ENetPacketPeer::peer_disconnect()
           │      └─ enet_peer_disconnect() [C API]
           └─ ENetConnection::destroy()
                  └─ enet_host_destroy() [C API]
```

### データフロー図

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

GDScript/C#
API呼び出し ────▶ ENetMultiplayerPeer ────▶ peer_connected シグナル
                        │                    peer_disconnected シグナル
                        ▼
                 ENetConnection ────────▶ 受信パケットキュー
                        │
                        ▼
                 ENetPacketPeer ────────▶ ネットワーク送信
                        │
                        ▼
                   enet C API ────────▶ UDP ソケット
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| enet_multiplayer_peer.h | `modules/enet/enet_multiplayer_peer.h` | ヘッダー | マルチプレイヤーピア定義 |
| enet_multiplayer_peer.cpp | `modules/enet/enet_multiplayer_peer.cpp` | ソース | マルチプレイヤーピア実装 |
| enet_connection.h | `modules/enet/enet_connection.h` | ヘッダー | 接続管理クラス定義 |
| enet_connection.cpp | `modules/enet/enet_connection.cpp` | ソース | 接続管理実装 |
| enet_packet_peer.h | `modules/enet/enet_packet_peer.h` | ヘッダー | パケットピア定義 |
| enet_packet_peer.cpp | `modules/enet/enet_packet_peer.cpp` | ソース | パケットピア実装 |
| register_types.cpp | `modules/enet/register_types.cpp` | ソース | モジュール登録 |
| register_types.h | `modules/enet/register_types.h` | ヘッダー | モジュール登録定義 |
