Spaces:
Sleeping
Sleeping
| # metadata.json とバイトコード生成の分析レポート | |
| ## 概要 | |
| このレポートでは、`data/metadata.json` がバイトコード生成にどのように影響するか、またパーサーとビットマスク処理が過度に複雑かどうかを分析します。 | |
| --- | |
| ## 1. metadata.json の構造 | |
| ### 1.1 セクション一覧 | |
| | セクション | 用途 | エントリ数 | | |
| |-----------|------|-----------| | |
| | `triggers` | 能力の発動タイミング | 11 | | |
| | `targets` | 効果の対象 | 14 | | |
| | `opcodes` | バイトコード命令 | 67 | | |
| | `action_bases` | アクションIDのベース値 | 13 | | |
| | `phases` | ゲームフェーズ | 15 | | |
| | `conditions` | 条件チェック命令 | 54 | | |
| | `costs` | コスト種別 | 95 | | |
| | `extra_constants` | ビットマスク定数 | 26 | | |
| | `unused` | 未使用マーク | 0 (空) | | |
| ### 1.2 同期フロー | |
| ```mermaid | |
| flowchart TD | |
| A[data/metadata.json] --> B[tools/sync_metadata.py] | |
| B --> C[engine_rust_src/src/core/generated_constants.rs] | |
| B --> D[engine_rust_src/src/core/enums.rs] | |
| B --> E[frontend/web_ui/js/generated_constants.js] | |
| B --> F[engine/models/generated_metadata.py] | |
| B --> G[engine_rust_src/src/core/shader_constants.wgsl] | |
| ``` | |
| --- | |
| ## 2. 問題点: 二重定義と不整合 | |
| ### 2.1 Python側の二重定義問題 | |
| **重大な問題**: [`engine/models/ability.py`](engine/models/ability.py) には `metadata.json` とは**独立した** enum定義が存在します。 | |
| ```python | |
| # ability.py (行10-22) - metadata.json と独立 | |
| class TriggerType(IntEnum): | |
| NONE = 0 | |
| ON_PLAY = 1 | |
| ON_LIVE_START = 2 | |
| # ... | |
| ``` | |
| これは [`engine/models/generated_metadata.py`](engine/models/generated_metadata.py) と**重複**しており、同期されていません。 | |
| ### 2.2 具体的な不整合例 | |
| | 項目 | metadata.json | ability.py | 状態 | | |
| |-----|---------------|------------|------| | |
| | `SEARCH_DECK` | 22 | 22 | ✅ 一致 | | |
| | `FORMATION_CHANGE` | 26 | 26 | ✅ 一致 | | |
| | `SWAP_ZONE` | 38 | 38 | ✅ 一致 | | |
| | `PREVENT_SET_TO_SUCCESS_PILE` | 80 | 80 | ✅ 一致 | | |
| | `SET_HEART_COST` | 83 | 83 | ✅ 一致 | | |
| **現在は値が一致していますが**、`ability.py`のenumは手動管理であり、将来的な不整合のリスクがあります。 | |
| ### 2.3 AbilityCostType の爆発的増加 | |
| [`ability.py`](engine/models/ability.py:303-500) の `AbilityCostType` は **200以上のエントリ** を持ち、その多くが自動生成された「プレースホルダ」です: | |
| ```python | |
| # 行410-500: 自動生成されたエントリの例 | |
| PLACE_ENERGY_FROM_DECK_TO_DISCARD = 110 | |
| PLACE_ENERGY_FROM_DECK_TO_HAND = 111 | |
| # ... 90行以上の自動生成エントリ | |
| ``` | |
| これらは `metadata.json` の `costs` セクション (95エントリ) と比較して**2倍以上の規模**です。 | |
| --- | |
| ## 3. ビットマスク処理の複雑さ分析 | |
| ### 3.1 _pack_filter_attr のビットレイアウト | |
| [`ability.py`](engine/models/ability.py:1388-1595) の `_pack_filter_attr` メソッドは、64ビット整数に複数のフィルタ条件をパックします: | |
| ``` | |
| ビットレイアウト (64ビット): | |
| ┌─────────────────────────────────────────────────────────────────┐ | |
| │ Bits 2-3 : Type (0=Any, 1=Member, 2=Live) │ | |
| │ Bit 4 : Group Filter Enable │ | |
| │ Bits 5-11 : Group ID (7 bits) │ | |
| │ Bit 12 : Tapped Filter │ | |
| │ Bit 13 : Has Blade Heart │ | |
| │ Bit 14 : Not Has Blade Heart │ | |
| │ Bit 15 : Unique Names │ | |
| │ Bit 16 : Unit Filter Enable │ | |
| │ Bits 17-23 : Unit ID (7 bits) │ | |
| │ Bit 24 : Cost Filter Enable ←┐ │ | |
| │ Bits 25-29 : Cost Threshold (5b) │ 競合! │ | |
| │ Bit 30 : Cost Mode │ │ | |
| │ Bit 31 : Color Filter Enable ←┘ │ | |
| │ Bits 32-38 : Character ID 1 │ | |
| │ Bit 42 : Character Filter Enable │ | |
| │ Bits 43-49 : Character ID 2 │ | |
| │ Bits 50-56 : Character ID 3 │ | |
| │ Bits 57-59 : Special Filter ID │ | |
| └─────────────────────────────────────────────────────────────────┘ | |
| ``` | |
| ### 3.2 ビット競合の問題 | |
| **重大な設計欠陥**: Bits 24-30 が **Cost Filter** と **Color Filter** で競合しています: | |
| ```python | |
| # Cost Filter (行1517-1536) | |
| if c_min is not None: | |
| attr |= 1 << 24 # Cost Enable | |
| attr |= (val & 0x1F) << 25 # Cost Value | |
| # Color Filter (行1538-1555) - 同じビット領域を使用! | |
| if color_mask > 0: | |
| attr |= (color_mask & 0x7F) << 24 # ← Cost と重複! | |
| attr |= 1 << 31 | |
| ``` | |
| これにより、Cost Filter と Color Filter は**同時に使用できません**。 | |
| ### 3.3 Rust側の実装との整合性 | |
| [`engine_rust_src/src/core/logic/filter.rs`](engine_rust_src/src/core/logic/filter.rs:20-33) では、同じビットレイアウトを使用: | |
| ```rust | |
| /// Bit layout (see generated_constants.rs): | |
| /// - Bits 2-3: Card type (Member=1, Live=2) | |
| /// - Bit 4: Group filter enable | |
| /// - Bits 5-11: Group ID | |
| /// - Bit 16: Unit filter enable | |
| /// - Bits 17-23: Unit ID | |
| /// - Bits 32-38: Color mask ← 異なる! Pythonは24-30 | |
| /// - Bit 42: Character filter enable | |
| ``` | |
| **Rust側は Bits 32-38 を Color に使用**していますが、Python側は Bits 24-30 を使用しており、**不整合**があります。 | |
| --- | |
| ## 4. バイトコードコンパイルの複雑さ | |
| ### 4.1 コンパイルフロー | |
| ```mermaid | |
| flowchart TD | |
| A[Ability.instructions] --> B{Instruction Type?} | |
| B -->|Condition| C[_compile_single_condition] | |
| B -->|Effect| D[_compile_effect_wrapper] | |
| B -->|Cost| E[_compile_single_cost] | |
| C --> F[Opcode + Value + Attr + Slot] | |
| D --> G{Effect Type?} | |
| G -->|ORDER_DECK| H[LOOK_DECK + ORDER_DECK] | |
| G -->|SELECT_MODE| I[Jump Table生成] | |
| G -->|Other| J[_compile_single_effect] | |
| J --> K[特殊処理] | |
| K --> L[_pack_filter_attr呼び出し] | |
| L --> F | |
| ``` | |
| ### 4.2 特殊処理の分岐数 | |
| [`_compile_single_effect`](engine/models/ability.py:949-1386) メソッドには**15以上の特殊ケース分岐**があります: | |
| | Effect Type | 特殊処理内容 | 行番号 | | |
| |-------------|-------------|-------| | |
| | `ORDER_DECK` | LOOK_DECK命令を先行 emit | 859-872 | | |
| | `SELECT_MODE` | ジャンプテーブル生成 | 877-925 | | |
| | `RECOVER_MEMBER/LIVE` | ゾーン再配置ビット処理 | 965-977 | | |
| | `TAP_OPPONENT/TAP_MEMBER` | フィルタ属性パック | 981-986 | | |
| | `PLACE_UNDER` | ソース属性設定 | 989-993 | | |
| | `ENERGY_CHARGE` | ウェイト状態フラグ | 996-998 | | |
| | `SELECT_MEMBER` | フィルタ属性パック | 1001-1002 | | |
| | `PLAY_MEMBER_*` | フィルタ属性パック | 1005-1010 | | |
| | `LOOK_AND_CHOOSE` | キャラクターID + ゾーン処理 | 1013-1099 | | |
| | `SELECT_CARDS/MEMBER/LIVE` | 複雑なビットパッキング | 1102-1130 | | |
| | `SET_HEART_COST` | 6色コスト + ユニットフィルタ | 1133-1194 | | |
| | `META_RULE` | 13種類のルールタイプ | 1275-1302 | | |
| | `REVEAL_UNTIL` | 条件タイプ別エンコード | 1305-1345 | | |
| ### 4.3 コードの複雑さ指標 | |
| | 指標 | 値 | 評価 | | |
| |-----|-----|------| | |
| | `_compile_single_effect` の行数 | 437行 | 🔴 過大 | | |
| | `_pack_filter_attr` の行数 | 208行 | 🟡 中程度 | | |
| | 特殊処理分岐数 | 15+ | 🔴 過多 | | |
| | ビットシフト演算数 | 50+ | 🔴 過多 | | |
| | ネスト深度 | 最大5レベル | 🟡 中程度 | | |
| --- | |
| ## 5. 推奨される改善策 | |
| ### 5.1 短期的改善 (優先度: 高) | |
| 1. **二重定義の排除** | |
| - `ability.py` の enum を `generated_metadata.py` から import するよう変更 | |
| - または、`sync_metadata.py` が `ability.py` も生成するよう拡張 | |
| 2. **ビット競合の解消** | |
| - Color Filter を Bits 32-38 に移動 (Rust側に合わせる) | |
| - または、Cost Filter を Bits 8-14 に移動 | |
| ### 5.2 中期的改善 (優先度: 中) | |
| 3. **フィルタ構造体の導入** | |
| ```python | |
| @dataclass | |
| class CardFilter: | |
| card_type: Optional[CardType] | |
| group_id: Optional[int] | |
| unit_id: Optional[int] | |
| cost_filter: Optional[tuple[int, bool]] # (threshold, is_le) | |
| color_mask: int | |
| # ... | |
| def pack(self) -> int: | |
| """構造化されたフィルタをビット列に変換""" | |
| ``` | |
| 4. **エフェクトコンパイラの分割** | |
| - `_compile_single_effect` を各エフェクトタイプ別のハンドラに分割 | |
| - Visitor パターンまたは Strategy パターンの採用 | |
| ### 5.3 長期的改善 (優先度: 低) | |
| 5. **バイトコード設計の再検討** | |
| - 現在: 4-int固定長 `[op, v, a, s]` | |
| - 提案: 可変長またはTLV (Type-Length-Value) 形式 | |
| 6. **宣言的エフェクト定義** | |
| - YAML/JSON でエフェクトを定義し、コード生成 | |
| --- | |
| ## 6. 結論 | |
| ### 6.1 metadata.json のバイトコードへの影響 | |
| | 側面 | 評価 | 説明 | | |
| |-----|------|------| | |
| | Opcode値の定義 | ✅ 良好 | 自動同期されている | | |
| | 条件/コスト値 | ✅ 良好 | 自動同期されている | | |
| | Python enumとの整合性 | 🟡 リスクあり | 手動管理のため将来的に不整合の可能性 | | |
| | ビットマスク定数 | 🔴 不整合あり | Python/Rustでビット位置が異なる | | |
| ### 6.2 複雑さの評価 | |
| | 側面 | 評価 | 理由 | | |
| |-----|------|------| | |
| | パーサー | 🟡 中程度 | 分岐は多いが構造は理解可能 | | |
| | ビットマスク | 🔴 過度に複雑 | 競合あり、文書化不十分 | | |
| | コンパイラ | 🔴 過度に複雑 | 400行の単一メソッド、15+分岐 | | |
| | 保守性 | 🔴 低い | 二重定義、暗黙のビット操作 | | |
| ### 6.3 最優先すべき課題 | |
| 1. **Color Filter のビット位置修正** (Rust側に合わせる) | |
| 2. **ability.py の enum を自動生成に切り替え** | |
| 3. **_compile_single_effect の分割リファクタリング** | |
| --- | |
| ## 付録: 関連ファイル一覧 | |
| | ファイル | 行数 | 役割 | | |
| |---------|------|------| | |
| | [`data/metadata.json`](data/metadata.json) | 323 | 定数定義のマスター | | |
| | [`engine/models/ability.py`](engine/models/ability.py) | 1852 | 能力定義・コンパイル | | |
| | [`tools/sync_metadata.py`](tools/sync_metadata.py) | 349 | 定数同期スクリプト | | |
| | [`engine_rust_src/src/core/generated_constants.rs`](engine_rust_src/src/core/generated_constants.rs) | 275 | Rust定数 (自動生成) | | |
| | [`engine_rust_src/src/core/logic/filter.rs`](engine_rust_src/src/core/logic/filter.rs) | 150+ | Rustフィルタロジック | | |
| | [`tools/verify/bytecode_decoder.py`](tools/verify/bytecode_decoder.py) | 307 | バイトコードデコーダ | | |