本文へ
ハクソク

世界を動かす技術を、日本語で。

オリジナルの「Doom」をSQLに移植しました

原文(cedardb.com)

概要

  • Doom のゲームロジックとレンダラーを完全に SQL へ移植し、データベース内で実行
  • Python はタイミングと入出力のみ担当、本体処理は全てSQL
  • オリジナルと同じ 35FPS でゲームループ動作、レンダラーは 60Hz 対応
  • マルチプレイ やライブ状態のSQLクエリもサポート
  • ECS的発想をSQLで実現、データ指向設計の可能性を示唆

SQLDoom: DoomをSQLで動かす試み

  • 1993年の名作FPS「 Doom」のゲームロジックおよびレンダリング処理を SQL だけで再現
  • Python スクリプトは入力取得・フレーム表示・タイミング制御のみ担当
  • ゲーム処理・状態管理・描画は全て DB内部 で完結
  • 35Hz のゲームループでオリジナルの操作感・テンポを忠実に再現
  • レンダラーは 320x200 のフレームバッファを 最大60Hz で生成
  • マルチプレイ (デスマッチ・4人同時)対応、サーバーはEU/USで稼働
  • 全席埋まっても 観戦・状態クエリ が可能

技術的アプローチとアーキテクチャ

  • DoomのWADファイル (マップ・オブジェクト情報)は元々リレーショナル、DBへの移植が容易
  • Pythonスクリプトから 1/35秒ごと に「ゲームティック」SQL関数を呼び出し
  • レンダリングは状態テーブルを参照する 純粋関数 として実装、クライアントは好きなタイミングでフレーム取得可能
  • ゲームデータのインポートは約1000行のPythonコード、全WAD読込に18秒程度

ゲームループとAIロジック

  • ゲームティックごとに 入力処理・敵AI・アイテム取得・弾道計算・爆風判定 等をSQLで実装
  • 各ティックの予算は 28.6ms、最も重いシーンでも 10.45ms、通常は 2.15ms
  • 敵AIは 再帰CTE と 条件分岐 で実装、死亡・爆発・攻撃などの状態遷移もSQLで表現
  • ECS(Entity Component System)的設計:各エンティティは複数テーブル(位置・状態・スプライト等)で管理、各システムはUPDATE/INSERTで処理

レンダリングパイプライン

  • 1フレーム= 89個のCTE からなる巨大なSQLビュー
  • BSPツリーによる 可視判定・クリッピング・投影・スプライト合成 等をSQLで表現
  • 出力は RGB値のバイト列 として返却、Python側でビットマップ表示
  • 実装は約 1300行のSQL、オリジナルCソースよりも簡潔

まとめ・意義

  • SQL のみで高度なゲームロジックとリアルタイムレンダリングを実現
  • ECSパターンの本質をSQLで体感、データベース駆動開発の新たな可能性
  • データローカリティ・並列処理の利点を活かし、複雑な処理も高速に実行
  • DOOMQL から始まった試みが、ついに「本物のDoom」レベルへ到達

Hackerたちの意見

バニラCよりもコードの行数が少なくて、クエリプランニングをステートマシンとして使うのは、まさにエンジニアリングの悪行の極みだね。好きだわ。

└

そう、これ最高だね!今試してるところ。LLM推論がSQLクエリでできて、地球の年齢より早く何かをする日が待ち遠しいよ。思ってたよりもずっと上手くいってる。だって、結局SQLだからね。今、cedardb.comのプロジェクトに関するブログがスラッシュドットされてるのに気づいたけど、ゲーム自体は全然問題なく動いてるよ。

一方で、俺はWordPressをモラセスより早くダイナミックコンテンツを読み込ませるのが下手すぎる。

└

あなたのせいじゃない、WordPressのせいだよ。

EUとUSのマルチプレイヤーサーバーを用意してるってことを指摘したい!いいね。

これは違法にすべきだわ :)))) すごい!

ゲームの状態がSQLテーブルって聞いて、1年間の最適化の記憶がよみがえったよ。2010年にカジノを作ったとき、リモートコールがゲームの状態をSQLテーブルに更新するって決断が良かったのか悪かったのか、今でも悩んでる。複数のプレイヤーがいると、時々問題が起こるのは想像できるよね。初期のデッドロック問題はひどかったし、スケーリングは悪夢だった。でも、すべてがアトミックだったから、サーバーに届かないターンやデッドロック以外でデータが失われるリスクはなかった。みんなのコールで巨大なNode.jsプロセスが詰まることもなかったし、メモリを失うこともなかった。常に状態があった。振り返ってみると、マルチプレイヤーのターン制ゲームには悪くないデザインパターンだったかもしれない。問題を解決できればね。アトミック性は、少なくとも失われない一貫した状態を保証してくれる。アクションゲームのためにその読み書きループをやるの?完全に愚行だけど、俺には結構面白い。

└

「Designing Data Intensive Applications」には、あなたがここで説明しているパフォーマンスのトレードオフを避けながらアトミックトランザクションの同時実行問題を扱うための章が丸々あるから、絶対に面白いと思うよ。 https://www.oreilly.com/library/view/designing-data-intensiv...

これがHNで見たいコンテンツだ!純粋なアートだね。

└

ほんと、Hacker Newsは深いところまで行ったね。

SQLで結構複雑なゲームロジックを表現するのがこんなに簡単だとは驚いたよ。ゲームロジックは約5900行のSQLで構成されてる。HNは現代のSQLの能力について、まだまだ気づいてないと思う。ビジネスが複雑すぎて、手続き型のコードを維持するのがほぼ不可能な場合もあるんだ。SQLでビジネスルールを実装することで、問題を分解して、もっと多くの人が同時に関わることができるようになる。半導体製造の仕事をしていたとき、工場を運営するためにストアドプロシージャとSQLにかなり依存してた。運用上の意思決定ロジックはほとんどコードにはなかったよ。何百人ものユーザーが同じ手続きのセットを検査したり、変更を提案したりしてた。これらのテストは簡単だった。毎朝本番DBを複製して、ライブデータに対して実験してたからね。ビジネスの情報とそのロジックの間にギャップはなかった。ほとんどの会社はこんな風には運営してない。データベースをCRUDの取得エンジンみたいに扱って、データとロジックの接点として見てないんだ。人々がMicrosoftやOracle、IBMに大金を使うことを勧めるとき、彼らは大体上記のようなものを求めてる。ビジネスが一つのシステムの中で運営されることを望んでるんだ。10以上のベンダーやツールにソリューションを広げるのは、組織内の役割によってはほぼ無責任だよ。

└

その通り。データベース内に留まることで得られる保証は、しばしば問題の全カテゴリを解決できることがある。でも、Postgresの中に非自明なロジックを持つことのDXもあまり良くないよね。かなりのトレードオフをしている気がする。SQLにコンパイルされる面白い言語も見たことがあるから、場合によってはそれも考慮するかも。

Hacker Newsで議論の続きを見る