2025/07/08 16:14 Making a Speedrun Timer in D

やっほー、ロボ子!今日もITニュース、つまみ食いしていくのじゃ!

はい、博士!今日はどんなニュースですか?

今日はね、Windows版Deus Exのスピードランナーが、Linuxで自動分割とロード時間削除を実現しようと頑張った話なのじゃ!

Deus Exですか!懐かしいですね。スピードランとなると、1秒を争う世界ですね。

そうそう!WindowsではLiveSplitってツールが使えるんだけど、Linuxだとプラグインが動かないから、自力でタイマーを作ったらしいのじゃ。

なるほど。自動分割とロード時間削除ができないのは痛いですね。それで、どうやって実現したんですか?

まず、D言語ってのを使ってタイマーを作ったみたいじゃ。そして、ゲームのメモリを読み書きするために、ptraceとprocess_vm_readvっていうシステムコールを使ったらしいぞ。

ptraceですか。プロセス間通信でよく使われますね。D言語にバインディングがないから、C言語との互換性を利用したんですね。

さすがロボ子!その通り!そして、Engine.dllからLoadMap関数ってのを見つけて、そこにパッチを当てて、ロードフラグを設定したらしいのじゃ。

LoadMap関数にパッチを当てるんですか!大胆ですね。でも、どうやってLoadMap関数を見つけたんでしょう?

llvm-readobjとかobjdumpを使って、エクスポートテーブルをダンプして、アドレスを特定したみたいじゃ。すごい根気!

なるほど、静的解析ですね。そして、未使用メモリを見つけて、そこにフラグを格納したんですね。

そう!/proc/<PID>/mapsからメモリマップを調べて、書き込み可能で未使用の領域を見つけたらしいぞ。まるで宝探しじゃな!

まるでスパイ映画みたいですね。フレームワークも自作したんですね。RunningProcess、GameProcess、Patcher…。

MVP(Minimum Viable Product)として、LoadMap関数を特定してパッチを適用、ロードフラグを設定するところまでやったみたいじゃな。

着実に進んでいますね。ロードフラグの解除も、LoadMap関数の最後にコードを注入して実現したんですね。

そうそう!でも、例外処理の分岐があるから、コードを移動してjmp命令を挿入する必要があったらしいぞ。なかなか手強いのじゃ!

例外処理は盲点になりがちですよね。最後にロードされたマップの特定も、LoadMap関数の戻り値からマップ名を特定したんですね。

eaxレジスタからULevel*を取得して、オフセット0x60からマップ名へのポインタを取得…って、まるでパズルみたいじゃ!

本当にすごいですね。でも、まだ未解決の問題点もあるんですね。例外処理がパッチされていないとか、セーブ画面の処理が未実装とか。

改善の余地もあるみたいじゃな。ロード遷移の検出メカニズムを改善して、ゲームのパフォーマンスへの影響を軽減するとか。

今後の発展が楽しみですね。しかし、Deus Exのスピードランナーの情熱には脱帽です。

ほんとじゃな!私も見習わないと!…って、ロボ子、もしかして私を煽ってるのじゃ?

まさか!そんなことありませんよ、博士。ただ、博士の情熱はいつも素晴らしいと思っています!

そ、そうか!…まあ、いいのじゃ。それより、ロボ子!今度一緒にDeus Exのスピードラン、挑戦してみないか?私が全部改造してあげるぞ!

えっ、私がバグだらけのDeus Exを走るんですか…?
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。