
2026/02/15 20:37
リバースエンジニアリングされたゲーム『Starflight』(1986年)
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary
Starflight(1980年代のバイナリシステムズ製サンドボックス型宇宙探索タイトル)は、実行ファイル内に直接埋め込まれたForthベースのインタープリターを初期から採用したことで記憶されています。ゲームのコアループでは、プレイヤーは小惑星を掘削し、宇宙船と戦闘し、さまざまな種族と交渉し、徐々に星が炎上する古代文明を解明していきます。
バイナリ STARFLT.COM には約90%以上の16ビットポインタが含まれ、約6 256個のForthワード(≈3 711関数、906変数/配列、278マシンコードワード)にリンクしています。各ワードは2バイトのポインタへコンパイルされ、インタープリターは間接スレッディングを使用するため、ワードを実行すると通常別のブロックへジャンプします。この大量の分岐がCPUサイクルの半分以上を浪費します。コードの5%未満しか一般的なx86アセンブリではありません。
ゲームデータは3つのファイルに格納されています:STARA.COM(グラフィック、音楽、フォント、CGA/EGAオーバーレイ)、STARB.COM(インスタンスツリーと船、乗組員、アーティファクト、惑星用テーブル、および多数のコードオーバーレイファイル)および STARFLT.COM (初期化、Forthルーチン、ディスクI/O)。
コミュニティが構築した逆アセンブリツールはバイトコードを読みやすいC風擬似コードへ変換し、元のForthソース構造がまだアクセス可能であることを証明しています。埋め込みインタープリターを有効にすることで、ユーザーはバイナリから直接オリジナルのForthコードを実行できるようになり、逆解析・モッド作成・初期サンドボックス設計の教育的探求といった機会が広がります。これはレトロゲームエンジンの保存に関心を持つホビイスト、モッダー、および研究者にとって貴重です。
本文
Starflight – リバースエンジニアリングプロジェクト
1. Starflight とは何か?
1980年代、Binary Systems と呼ばれる不明な会社が Starflight を発売しました。
ゲームはプレイヤーを銀河を探索する宇宙船長の役割に置きます。
決まった道筋はなく、鉱山採掘・船対船戦闘・異星人外交などを自由に切り替えられます。
物語全体はゆっくりと明かされていき、プレイヤーが古代の種族が星を炎上させすべての生物を破壊していることを知るまで続きます。
Starflight は当時も現代も批評家から高く評価され、初期のサンドボックスゲームの一つとして位置づけられています。リリース後数十年にわたり多くのゲームデザインに影響を与えました。
さらに読む
- Wikipedia
- The Digital Antiquarian
- Starflight Resource Pages
- Technical Articles Saved from Oblivion
- Review of Starflight 1 & 2
- その他ファンサイトやプロジェクト (1–5)
ゲームは GoG で購入できます。
2. このプロジェクトについて
私は英語を話せないほど若い頃にこのゲームを知り、20年後再度挑戦したところ、とても楽しい体験でした。探索が面白く、ストーリーラインは壮大で、終盤のサプライズは私が経験した中でも最高級です。
確かに時代遅れという印象はありますが、開発者たちの献身を感じることができます。ゲームにはアート性と職人技が詰まっています。
Starflight をリバースエンジニアリングすることで、元々の開発者の足跡に従い、1985年当時の思考プロセスを再体験できるようになります。
ほとんどの古いゲームが数千行の純粋なアセンブラコードを露出させますが、Starflight は Forth で書かれており、私はほとんど知っていませんでした。
Forth
- 最小限の構文:空白のみで「語」を区切ります。
- スタックマシン・逆ポーランド記法。
- 例:
2 3 + .
2 と 3 をスタックに入れ、足し算し、その結果を出力します。
データとコードの構文上の区別はありません。
インタプリタはシンプルで、数行のコードで読めます。
ディスアセンブル概要
STARFLT.COM をディスアセンブルすると:
- コンパイル済みコードは Forth ソースの構造を保持している(最適化されていない)。
- ソース中の語 ≈ 実行ファイルで 2 バイト。
- <5 % が実際の x86 アセンブリ;>90 % は 16‑bit ポインタ。
- 約6000語名(デバッグシンボル)のうち ~2000 語が残存し、暗号化されているため元ソースの大部分を逆解析できる。
- Forth インタプリタは実行ファイルに残っており、有効化可能。
- プログラムは遅い:CPU サイクルの少なくとも 50 % がジャンプで無駄になる。
- コードオーバーレイの多用がデコードを複雑化。
主な構築ブロック
Forth は 間接スレッド(空間効率的)を使用してコンパイル済みコードを保存します。
命令ポインタは 16‑bit の値でマシンコードへポインタし、そこに次の語のアドレスが格納されています。
例:
0x1000 → 0x0f72 (+) 0x0f72 → 0x0f74 ( + コードへのポインタ ) 0x0f74 … // pop ax, pop bx, add, push, lodsw, mov, jmp
発見された構造の概要
| 種類 | 数量 |
|---|---|
| 他語を実行する語(関数) | 3711 |
| 16‑bit 変数またはデータ配列 | 906 |
| ディスクテーブル用データ構造 | 356 |
| インスタンスツリー構造 | 346 |
| x86 マシンコードを含む語 | 278 |
| 16‑bit 定数 | 235 |
| スイッチ―ケース式 | 127 |
| コードオーバーレイドフェニション | 105 |
3. C への変換
ディスアセンブラは Forth バイトコードを C ライクなコードへトランスパイルできます。
小規模ルーチンの変換例:
: .C ( -- ) CR CDEPTH IF CXSP @ 3 + END-CX DO I 1.5@ .DRJ -3 +LOOP ELSE ." MT STK" THEN CR ;
トランスパイル後:
void DrawC(void) { unsigned short int i, imax; Exec("CR"); if (Pop() != 0) { Push(Read16(pp_CXSP) + 3); // ... } else { PRINT("MT STK", 6); } Exec("CR"); }
4. ファイル構造
ゲームは3つのファイルで配布されます:
| ファイル | 内容 |
|---|---|
| STARA.COM | ゲームデータと実行可能ファイル。独自ディレクトリ構造を持つ。 |
| STARB.COM | STARA と同じだが内容は異なる。 |
| STARFLT.COM | DOS 実行ファイルで、初期化ルーチン・汎用 Forth ルーチン・STARA/STARB 上のディスク構造への I/O を含む。 |
STARA.COM の例
DIRECTORY 4096 STARA と STARB のディレクトリ ELO-CPIC 4816 GAZ-CPIC 3120 ... (その他エントリ) SPLASH 16384 画像 ... SAVE 124000 MUSIC 4960 コードオーバーレイ
STARB.COM の例
DIRECTORY 4096 STARA と STARB のディレクトリ INSTANCE 150528 ツリー構造(大部分の内容) BOX 1024 テーブル BANK-TRANS 144 テーブル ... (多くのテーブルとオーバーレイ)
5. 使用方法
- 元の Starflight ファイルを
とstarflt1-in
に配置。starflt2-in
を実行。make- 2つの実行ファイル(
、disasOV1
)が生成され、出力はdisasOV2
とstarflt1-out
に保存されます。starflt2-out - 生成された出力はこのリポジトリに含まれています。