blitz3d-decomp について
Blitz3D ゲームの調査と動作移植に使うスキルで、B3DDecomp が復元した Blitz ソースを参照します。逆アセンブル、システムの追跡、移植、実測による検証を案内し、保護されたビルドや再配布の制限も示します。
主な機能
- 01B3DDecomp のビルドと実行
- 02モジュールの逆アセンブルと Blitz ソース復元
- 03文字列とデータからゲームシステムを追跡
- 04ランタイム資料に基づく動作の移植
- 05実測値による移植結果の検証
- 06逆コンパイルとライセンス上の制約の遵守
活用シーン
- 01対象となる Blitz3D ゲームの調査
- 02移植実装前の値の追跡
- 03元のゲームとの比較による移植動作の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rehan-remade/ universal-modder --skill blitz3d-decompインストール後、Claude Code で/blitz3d-decompを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/b3d-to-roblox.mdb3ddecomp-skip-failures.patchblitz-runtime.mdscripts/roblox/b3d_skin.pyvm_anim_data.pyvm_build.pyvm_render.py詳細
Blitz3D のデコンパイルと移植
Blitz3D のゲームは 1 つの exe として配布されます。ランタイムは .text に、コンパイル済みのゲームはリソースモジュールに格納され、ランタイムは読み込み時にそのモジュールをリンクします。exe を Ghidra で見ると、ランタイムしか表示されません。有効な手順は次のとおりです。
B3DDecomp でモジュールを逆アセンブルし、Blitz ソースにデコンパイルします。 その後、ソースを移植の仕様として使い、元のゲームを照合元にします。
逆アセンブルとデコンパイルの出力はすべて、どのリポジトリにも含まれない場所(慣例では ~/<game>-decomp/)に置き、決して公開しないでください。ここにあるスクリプトは保持してかまいません。デコンパイルを禁じる独自 DLL には手を加えないでください。exe にあるエクスポート名で十分です。MOD の MODLOG.md に記録してください。
ソースがある場合はそちらを読んでください。SCP: Containment Breach(Regalis11/scpcb)とその Ultimate Edition Reborn フォーク(Jabka666/scpcb-ue-my)は、CC BY-SA 3.0 のオープンソースです。
移植で使用できるもの。 ゲームのロジックを再現する移植や、モデル、キーフレーム、テクスチャ、サウンドを変換する移植は、公開またはアップロード(Roblox へのアップロードも含む)すると、そのゲームを再配布することになります。ユーザーが権利を持つものだけを移植してください。自作ゲーム、またはライセンス条件に従って使用できるオープンライセンスのゲームが対象です(SCP: Containment Breach の場合はクレジットを記載し、移植版も CC BY-SA 3.0 に準拠させてください。また、ファンゲームではライセンスが混在するため、各アセットのクレジットも確認してください)。それ以外は個人的な調査にとどめ、そこから何もアップロードまたは公開しないでください。
1. ツール
- B3DDecomp(juanjp600/B3DDecomp、C#、GPL-3):リポジトリの外にクローンし、
dotnet build Blitz3DDecomp.sln -c Releaseを実行します。.NET 8 SDK が必要です。ユーザーのローカル環境にインストールでき、管理者権限は不要です(dotnet-install.ps1 -Channel 8.0 -InstallDir <dir>)。DOTNET_ROLL_FORWARD=Majorを設定し、bin/Release/net8.0をPATHに追加して実行します。デコンパイラーは名前を指定してBlitz3DDisasmを起動します。 - 1 つの関数が原因で実行全体が中断する場合は、references/b3ddecomp-skip-failures.patch を適用します(
git apply。コミット 2b3148b で作成)。これにより、デコンパイラーは処理を完了できない関数をスキップし、停止する代わりにstep5 failedの行を出力します。
Blitz3DDecomp.exe と Blitz3DDisasm.exe がビルドできれば完了です。
2. 逆アセンブルとデコンパイル
Blitz3DDecomp.exe <copy of game.exe> を実行すると、<game>_disasm/(関数ごとの Code/、Type/、Strings.txt、BuiltIn/、Libs/、BuiltInSymbols.txt)が出力され、その後 <game>_decomp/ にデコンパイルされます。SCP: Containment Breach のコードを基にしたゲームでは、2 番目の引数としてゲームの fmod.decls が必要です(B3DDecomp の README によると、配布されている decls では FSOUND_Stream_Open のパラメーターが 1 つ省かれています)。
それでも中断する場合、例外に原因となる構文が示されます。処理を先に進めるために、型セッターが書き込みを黙って無視するようにしてはいけません。型の伝播が出力のないまま無限ループに陥ります。
保護されたビルドの場合は中止してください。 この手順を防ぐために保護されたビルドもあります。改変されたコンパイラーとランタイムが、すべての関数、型、組み込み名をハッシュ化します(B3DDecomp は Unrecognized function: @_builtIn_f<garbled> と表示して停止します。SCP: Containment Breach 2 のクライアントはこの方式でビルドされています)。または、モジュールが暗号化されています。これらは開発者がデコンパイルを防ぐために追加した保護です。解除しないでください。ユーザーに伝えて中止してください(skills/mod-any-game/references/safety.md)。現在の B3DDecomp は、これらの保護の 1 つを説明なしに自動で解除します。.b3dmod セクションに対する XOR です。まず exe のセクションを一覧表示し(objdump -h または任意の PE ビューアーを使用)、該当するセクションがあれば中止してください。
<game>_decomp/ に Main.bb、Functions/、Types/、Decls/ があり、実行時の step5 failed の行が数行程度以下なら完了です。
3. システムを特定する
- まず文字列を確認します。システムが読み込むアセットパスまたはサウンドを探します(
grep -l StringConstant_<n> Code/*)。 - データ駆動型のテンプレート:初期化関数がアイテムごとのテンプレートに定数を格納します。ゲームにアドオン/JSON ローダーがあれば、すべてのフィールド名がわかります。
移植で使用するすべての数値について、設定する行と読み取る行を特定できれば完了です。
4. 移植
移植コードを書く前に、references/blitz-runtime.mdを読んでください。Blitz3D のクロック、Animate、CurveValue、オイラー角、Rnd、エンティティの呼び出しは、単純に書き写すと誤った結果になります。
アニメーション付きの.b3dモデル(ビューモデル、リグ、キーフレーム)を Roblox に移植する場合は、references/b3d-to-roblox.mdに従ってください。スクリプトは scripts/roblox/にあります。
手順どおりに移植してください。順序、定数、ティックを同じにします。変更箇所には、その理由をコメントで必ず記載してください。上記の権利に関するルールは、モデルだけでなくコードにも適用されます。
5. オラクルと照合する
見た目ではなく、エンジン内で逆コンパイルした数値と移植版を比較して測定してください。発射レート(固定ティックでの毎秒の発射数)、継続時間(フレーム数/速度/毎秒のティック数)、照準(画面中央にあるサイトのドット)、サーバー上の弾薬数を確認します。各確認項目と結果をジャーナルに記録してください。
移植したすべての動作について、逆コンパイルした値と並べて測定値が記録されていれば完了です。