🦕

ゲームエンジンとしてのDenoの可能性

2023/12/15に公開

この記事は、 ドワンゴアドベントカレンダー 2023 の 15 日目の記事です。

普段はWeb開発やちょっとした便利ツールに使うことが多いと思われるDenoですが、今回はちょっと違う視点でのユースケースを提案してみます。

そのユースケースとは、まさに表題の通りゲームエンジンとしての活用です。

そこで、まずは昨今のゲームエンジンで求められている機能について触れていきます。

ゲームエンジンに求められる機能

ゲームエンジンはその名の通り、ゲームを開発するところから、幅広い動作プラットフォームを対象にして、実際にプレイ可能な状態のアセットを生成するまでの一連の役割を担います。
昨今のゲームの品質向上に伴って、ゲームエンジンには描画、物理シミュレーション、音声や通信などの機能を高いレベルで提供することを求められる場面も増えていることでしょう。

また、商用利用可能なゲームエンジンは「比較的習得が容易なスクリプトを用いて開発が可能」という機能も提供していることがあります。
昨今のゲームが要求する品質に応えるためには、少ない手数で多くの機能を実装する必要があり、まさにその効率化の手段としてゲームエンジンが用いられていることになります。

ゲームエンジンにおけるプログラミング言語

先ほど紹介したような機能を実現するために、ゲームエンジンは高い性能を求められます。
そのような要求のために、エンジン本体はC/C++で開発していることが多いと観測しています。
具体的にはUnreal EngineGodot EnigneRE ENGINEなどがあります。
(UnityもおそらくC/C++だとは思いますが、公開情報ではないようなので言及しません。)

また、これらのゲームエンジンは本体の開発言語とは別に、ゲームを実装するためのスクリプト言語もサポートしています。

Denoの技術的な構成

ここまではゲームエンジンに要求されるものについて紹介してきました。
ここからはようやく本題ということで、Denoの技術的な構成を紹介します。

DenoはJavaScriptエンジンのV8をベースにMITライセンスで開発されているJavaScriptランタイムです。
GitHubのdenoland Organizationには多数のリポジトリが存在していますが、その中でもV8にJavaScript APIを実装するためのdeno_coreではRustおよびJavaScript(一部TypeScript)が用いられています。

Rustは今日ではOS、デバイスドライバやWeb開発など様々な場面でソフトウェア開発に用いられており、その性能は高く評価されて広く普及している、と言えるような状況にあると言えます。

また、JavaScript(TypeScript)に関しては今日のWeb開発には欠かせない存在になっています。

RustとJavaScriptでDenoにJavaScript APIを実装する

ところで、Denoの公式ブログでは以下のような記事が執筆されています。

https://deno.com/blog/roll-your-own-javascript-runtime

内容としては、「Rustとdeno_coreを使ってオレオレJavaScriptランタイム」を実装するチュートリアルとなっています。
ここまで来ればなんとなくピンと来た方もいらっしゃるのではないでしょうか、これぞまさに先ほどから触れてきた、ゲームエンジンの本体とスクリプト言語の関係になります。

Rustとバインディング用のJavaScriptを用いて、ゲームエンジンのAPIをJavaScriptランタイムに実装し、JavaScriptから実装したAPIを扱えるようになります。
実際には、パフォーマンスを最適化するにあたって、マーシャリングコストによってはJavaScriptの実装の方が速いというようなケースもあるはずなので、一様にRustでJavaScript APIを実装すれば正解とも限らないと思います。

この手法による特徴は以下の通りです。

Denoに関して

  • deno_coreTypeScriptのトランスパイル機能があるので、スクリプト言語にTypeScriptを利用できる
  • 前述のdeno_coreに直接APIを実装する以外に、FFIの仕組みを利用することでもまたAPIを提供することが可能
  • ゲームエンジンを用いてゲームを制作する開発者(以下、ゲーム制作者)は、deno compileコマンドを用いて主要なプラットフォームを対象にビルド済みのバイナリを配布できる
  • ゲーム制作者は、ゲームエンジンのライセンスによってはエンジンのコードを直接改変することもできる
  • グラフィックスAPIに関して、Deno1.8で実験的に導入されたWebGPUサポートがあり、その後Deno 1.32で一度削除されるものの、Deno 1.39で再度利用可能になった
    • これによりゼロからRustでグラフィックスAPIを実装する手間が省ける可能性がある
      (どちらにせよ、最終的にゲーム制作者が利用することを考えると、WebGPUおよび何かしらのグラフィックスAPIを高度に抽象化する必要はあると考えます)
  • クライアントだけではなくサーバーで動くプログラムが必要な場合、用途次第ではCDNでプログラムを実行できるDeno Deployや簡易なデータベースとしてDeno KVなどを利用できる

Rustに関して

  • 高速かつ高いメモリ安全性と堅牢な型システム
  • cargoを始めとした強力なRustのエコシステムを享受できる
    • ゲームエンジンの開発者はcargoのサポートするbuild targetにビルド済みのバイナリを配布できる
  • 今日ではRust製のゲームエンジンも名前を見かける機会が少しずつ多くなっており、実装の参考になる

JavaScriptに関して

Denoは豊富なcliツールを提供しており、deno compiledeno checkをゲームエンジンから提供するには、それらのcliツールが含まれるDeno本体を配布する必要があります。

この手法の難しいところ

先ほどはポジティブな側面を紹介してきましたが、当然そうでない点もあります。

例えば、ゲームエンジンの開発者はパフォーマンスを突き詰めるためにRustとJavaScript(およびそのエンジンであるV8)どちらの言語にも深い理解が要求されます。
また、スクリプト言語としてTypeScriptの型を提供する場合、地道に型定義ファイルを書く必要がありそうです。

まとめ

ある程度モノになるゲームエンジンを作ること自体が著しく困難な作業であることは言うまでもありません。
Unreal EngineやUnityなどは日々進歩するグラフィックス、モーションやサウンドなど高度な表現を支えるための道具がこれでもかと詰め込まれており、今日ではゲーム分野以外でも幅広く用いられるようになっています。
これらのゲームエンジンの機能に肉薄しようとするのは傍目から見ても実現不可能ではと思えるほどです。

一方で、エンジン部分およびスクリプトとしてGoを用いるEbitengineなどは用途を明確にし、シンプルな機能およびAPI、高いポータビリティを提供することに尽力しているなど、ゲームエンジン制作の幅広い可能性を感じることができるものもあります。

https://zenn.dev/hajimehoshi/articles/2426c6dca8b3b3

ゲームエンジン制作という修羅の道を行く技術のベースとして、開発者体験を尊重し、様々な機能を提供しているDenoの構成は一つの選択肢になるかもしれません。

Discussion