
2026/02/19 21:24
**C64ゲーム「Seawolves」(2025)に使用されたコーディングテクニック**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
(以下は英語原文の内容を日本語に訳したものです。技術用語はそのまま保持しています。)
Summary
Seawolves、2025年7月15日にリリースされた作品は、著者初の商業的コンモドール64ゲームです。その卓越した品質は、6502プロセッサを効率的に稼働させる低レベル最適化セットに由来します。
- Raster timing – NMIsとIRQsを同期させることでネストされた割り込みを減らし、ラスタースタール(遅延)を防止します。
- Torpedo rendering – 「splites」(8つのスプライトを3つの7ピクセル横断スライスに分割)により、垂直軌跡と波紋効果付きのリアルタイムターボが実現します。
- Explosion animation – 高解像度モードでビットシフトを行い、潜水艦のグラフィックを死亡時に分解します。
- Ocean waves – 右回転ビットで遠方波を生成し、$D016 が水平リップリングを駆動;この手法は Ecco the Dolphin の「get ready」スクリーンからインスパイアされています。
- Water distortion – 垂直バンドがスプライトに y‑expand を有効化し揺れさせます。完全な y‑expand は性能上の理由で除外されました。
- Sprite timing – FLD シュートは不良ラインを停止させ、$D011 で1ライン分上方向 Y スクロールしてシフトを修正します。
- Memory savings – GFX stream‑ins はスプライト全体の定義を置き換え、変更された部分(例:レーダーターン、ハイドロフォイルスプレー)だけをロードします。
- CPU optimisation – ORA を用いた条件結合で分岐命令を削減し、BCC などの条件付きジャンプで全体 JMP より1バイト節約しています。
ゲームは「sea mist」レベルでパララックススクロールを採用し、Parallaxian audio 用にカスタム SFX プレイヤーを搭載しています。
Seawolves は £4.99 で販売され、著者は購入または PayPal 寄付を推奨しています。隠れたトリックの収集は将来のデモや拡張機能でさらなる最適化を示す可能性があります。
このバージョンはリストから全ての主要ポイントを取り込み、元文に含まれていない推測内容を削除し、読者にとって明確かつ簡潔な概要を提供しています。
本文
2025年7月15日更新
はじめに
Commodore 64で初めて商業ゲームをリリースした際、Seawolves を制作する過程を共有したいと考えました。
最初から「コードがほぼない」手法(デモシーンの狂気とも言える奇抜なやり方)に備えてください。
主な特徴
- NMIs + IRQs が同期して動作
- Splites を使ったリアルタイム魚雷
- リアルタイムで進化する爆破アニメーション
- リアルタイム海面波
- リアルタイム水の歪み効果
- FLD シフト + 上方向補正
- GFX ストリームイン
- 迅速なロジック
- ブランチジャンプ
それぞれ見ていきましょう。
#1 NMIs + IRQs の同期実行
最初に Parallaxian、次に The Wild Wood で NMIs と IRQs を組み合わせました。メリットは以下の通りです。
| メリット | 説明 |
|---|---|
| 割込み柔軟性 | ラスタIRQを短時間・スキャンライン正確なタスク用にNMIで中断でき、IRQの入れ子が不要になります。 |
| 安全網 | 特定のIRQが停止した場合(稀に発生する負荷条件など)でも、最終的なNMIハンドラがトップオブスクリーンIRQへのポインタをリセットし、停止が拡散しないようにします。 |
| タイミング精度 | NMIsは任意のスキャンライン上で発火するタイマー割込みで、NOP配置が必要なラスタIRQよりも細かい制御が可能です。 |
実装ノート
- NMIはCIA #2 タイマ(
は Timer A、$DD04/$DD05
は Timer B)で制御します。$DD06/$DD07 - 16ビット周期カウントはこれらのレジスタに格納されます。正しい値を計算するためにはスプレッドシートが便利です。
- ゲーム初期化時には同じスキャンライン上で一貫した開始サイクルが不可欠です。
詳細については、NMI の設定ガイドをご覧ください。
#2 “Splites” を使ったリアルタイム魚雷
魚雷はマルチプレクスされたキャンバス上にリアルタイムで描画されるスプライトです:
- 構成 – 8縦スプライト × 3横切片(splite)=24 splite、各7ピクセル高(合計高さ21ピクセル)。
- 配置 – 割込みが毎7ラインで発生し、各 splite はユニークな X 座標と MSB 値を持ちます。
- 描画制約 – 魚雷が次の splite に移動する際にアーティファクトを防ぐため、魚雷間に最低7スキャンラインの縦スペースを確保します。
- 連続性 – 移動中は影響を受ける splite が同じ X 座標を共有します。
魚雷を1ピクセル上へ移動させた後、最後のラインのグラフィックデータをそのままにしておくと、垂直な軌跡が徐々に薄くなる「ワッケイエフェクト」が得られます。魚雷はキャラクターデータ前後でちらつき、泡立ったような見た目になります。
#3 リアルタイム爆破アニメーション
プレイヤーの潜水艦が死亡すると、圧力により分解します:
- Hi‑Res モードへ切り替え。
- ビットシフト命令を使って、表示中の潜水艦グラフィックデータをリアルタイムで破壊します。
#4 リアルタイム海面波エフェクト
同じビットローテーション手法で遠距離の波と前景の乱れ(Ecco the Dolphin からインスパイア)をアニメートします。水平方向成分は
$D016 を左右に振動させ、変化率を調整して追加します。シンプルですが効果的です。
#5 リアルタイム水の歪みエフェクト
初期の水の歪みは縦バンドで Y 拡張を有効にし、上下揺らすものでした。完全な Y ストレッチ(>2×)も試しましたが、最終ゲームではリソースが高すぎました。
#6 FLD シフト + 上方向 Y スクロール補正
多くのスプライトを中盤で移動させる際、「バッドライン」が CPU を消費することがあります。解決策は:
- 影響を受けたスプライトの Y 位置で FLD を実行し、バッドラインを止めます。
- バッドラインが次のスキャンラインに移動し、スプライト(例:splite 列)を描画する時間を確保します。
でキャラクターをもう一度上方向へシフトして補正します。$D011
#7 GFX ストリームイン
各アニメーションフレームごとに別々のスプライト定義を割り当てる代わりに:
- 回転するレーダー、ハイドロフォイル噴射、ヘリコプター回転翼など、変更されたグラフィックデータだけをストリームインします。
- プレイヤー潜水艦が方向を変えると、即座に鏡像(照明保持のため完全なミラーではない)で再描画されます。
#8 クイックロジック
複数の「論理ゲート」がサブルーチンを制御する場合、複数の
LDA とブランチ命令よりも:
LDA CONDITION_0 ORA CONDITION_1 ... BNE <branch_target>
と書くことで CPU 時間と RAM を節約できます。
「OR A: ブランチテストにおける特殊使用法」 というブログ記事でさらに詳しく解説しています。
#9 ブランチジャンプ
JMP $xxxx の代わりに、フラグ状態が既知かつジャンプ距離がブランチ範囲内なら BCC などのブランチ命令を使って1バイト節約できます。
閉じるコメント
これらは Seawolves に使用した技術の一部です。海霧レベルでのパララックススクロールや、Parallaxian を念頭に開発した独自 SFX プレイヤーの詳細は省略しています。見た目はシンプルですが、内部構造はデモシーン風プログラミングの典型的な高度技術です。
さらに隠れたトリックがあるので、ぜひ探ってみてください。
この記事を楽しんだ方は、ゲーム(価格 £4.99)や小額の PayPal 寄付で応援していただけると幸いです。