見出し画像

ゲームエンジンはアートである - 8 年以上自作ゲームエンジンをメンテし続けている話

自分は Ebiten という 2D ゲームエンジン (ゲームライブラリ) を趣味で開発しています。使用しているプログラミング言語は Go です。 2013 年 6 月に最初のコミットを行ったので、現在 8 周年の 9 年目です。 Ebiten は「くまのレストラン」などのモバイル及び Nintendo Switch 向けゲームで使われており、一定の実績があります。

ゲームエンジンの開発は一朝一夕では終わりません。Unity や RPG ツクールといった既製品がある中、ゲームエンジンをわざわざ自作することは酔狂かもしれません。ではなぜそのようなことをしたのでしょうか。端的に言うと「ミニマムな API で実用的な 2D ゲームが作れるかどうか」ということを証明したかったのです。自分の美的感覚の追求です。この目的に気づいたのは割と最近のことです。やっていくうちに「自分がやりたかったのはこういうことだったんだ」というのに後から気づいた、もしくは変化していったのだと思います。

Ebiten のグラフィックス機能として、「矩形画像から矩形画像へ描画する」という機能しか基本的にありません。画像や画面はすべて同じ Image という矩形画像オブジェクトで表されます。描画の際に位置、拡大率、回転角度、色味、合成方法などがオプションとして指定できます。よりローレベルな三角形描画 API は一応ありますが、 Ebiten のグラフィックスの機能といえばだいたいこの「矩形画像描画」しかありません。 この画像描画 API だけでちゃんとゲームが作れるのかどうかを実証実験するために Ebiten が作られている、と言えるでしょう。

画像1

Ebiten はアートです。自分の理念が先にあって、それを表現するためにエンジンを作っているという点ではそうだと思っています。絵描きが絵を描き、作曲家が作曲して自己表現するように、自分にとってはゲームエンジン開発が自己表現なのです。

Ebiten はアートですが、ゲームエンジンである以上、実用性も当然大切です。実際に使えないエンジンは絵に描いた餅です。実際に使われたゲームからフィードバックを得て実装を改善し続けています。 API を単純に保ちつつも、パフォーマンスを出すために Ebiten 内部で泥臭いことをやっています。自分の知る限り、この水準のミニマムさを哲学として貫いている実用的なゲームエンジンは他にはありません。

幸運にも、モチベーションが全く落ちずに Ebiten を 8 年間以上メンテナンスし続けることができました。今後も何十年もやっていくことになると思います。美的感覚の追求は人間の根源的な欲求のように思えます。また実際に使ってくださる人がいるというのもあると思います。この記事では、自分の小学生のころの原体験から、自作ゲームエンジン開発者になってしまった現在に至るまでの半生振り返っていきます。

スーパーファミコン

なぜゲームエンジンを作りたいのかという話は、自分の小学生時代にまでさかのぼります。自分が小学生の頃はスーパーファミコン全盛期でした。「ゼルダの伝説 神々のトライフォース」「シムシティ」「ファイナルファンタジー (4、 5、 6)」「マザー 2」が好きでした。ゲームを楽しんでいたのはもちろんなんですが、ゲームを作りたいとも思っていました。ゼルダの伝説のダンジョンを紙に書いて自作したりして遊んでいました。生意気にも、スーパーファミコンのゲームは「自分でも頑張れば作れそう」という感触がありました。実際に作るのはとても大変なんですが。

画像2

その後のプレイステーション以降の 3D のゲームを見ても「自分で作れそう」感はあまりありませんでした。子供の頃の思い出によるバイアスが強いとは思いますが、 2D ゲームに対するこだわりはこの頃からあったと思います。

他、スーパーファミコンで遊んだゲームとして「RPG ツクール SUPER DANTE」があります。ゲームというよりは、その名の通り RPG を作るツールです。大喜びでやりました。もちろん碌なゲームが作れたわけではありません。町を出るといきなり魔王が現れて決戦して終わるゲームとかを作っていた記憶があります。 RPG ツクールはコマンドを組み合わせてゲームを作り上げていくのですが、これがある種のプログラミングと言えます。自分が作ったロジックがそのとおりに動くという体験はこれがほぼ初めてで、自分にとってのプログラミングおよびゲーム制作の原体験でした。

RPG ツクール 2000

RPG ツクールシリーズの PC 版は RPG ツクール 95 の頃から最新版の RPG ツクール MZ に至るまで買い続けています。特に、自分が高校生の頃の RPG ツクールである「RPG ツクール 2000」は思い出深いツクールです。 2000 年に発売されました。

画像8

RPG ツクール 2000 のオフ会で知り合った人とは今でも交流があります。後に協力する Daigo 氏ともこのタイミングで知り合いました。 Daigo 氏は Ebiten が使われたゲーム「くまのレストラン」の作者です。当時はまさか 20 年近くの長い付き合いになるとは思いませんでした。

RPG ツクール 2000 はソフトウェアとして大変出来が良く、プログラマーを目指していた自分にとっては衝撃的でした。言語化するのが難しいのですが、ツールを触っていて、何か強い一貫性というか、美学のようなものを感じました。ゲームを作りたいという欲求が、ゲームを作るツールを作りたいという欲求にシフトしていったのもこの頃です。実際、自分が RPG ツクール 2000 で作ったゲームもアブストラクトな迷路ゲームなど碌なゲームがありませんでした。自分はストーリーものを作るより、エンジニアとしてゲームの基盤を作ったほうが向いているようです。なんかストーリーやキャラを考えるのが恥ずかしくなってしまうんですよね…。こればかりは才能や環境の問題だと思います。

いずれ RPG ツクール 2000 のような素晴らしいツールを作りたいと思いましたし、今でも思っています。Daigo 氏にもしょっちゅう「RPG ツクールを作りてえ」とボヤき続けたりしました。そういうこともあり、 Daigo 氏からの「じゃあなんか作ろっか」という提案もあって今も協業を続けています。それについては後述します。

ちなみに RPG ツクール 2000 の作者の尾島陽児さんは、 2000 からの PC 版 RPG ツクールシリーズを手掛けている人です。最新版の RPG ツクール MZ に至るまで、ほぼワンマンでツクールを作ったそうです。 RPG ツクール 2000 の一貫性の高さも、凄腕エンジニアがほぼ一人で作っているから、というのが理由としてあると思います。尾島さんは自分の憧れのエンジニアの一人です。

RPG ツクール XP と RGSS

RPG ツクール XP は RPG ツクール 2000 およびその後の RPG ツクール 2003 の後継です。自分が大学生のときの 2004 年に発売されました。

画像8

RPG ツクール XP の目玉機能は RGSS (Ruby Game Scripting System) です。何と、ゲームのロジックほぼすべてが Ruby で記述されており、開発者はそれを改造することが出来ました。 RGSS は、 Ruby を拡張した言語ということになっていますが、実態としては Ruby そのままにゲーム用のライブラリを加えたものでした。

自分が Ruby に触れたのはその時が初めてでしたが、特に問題なく学べました。敵に回復アイテムをぶつけて回復させる改造ができたときは感動したものです。前作の RPG ツクール 2000 までだとそういったことは不可能でした。当時の RPG ツクールの戦闘方式はドラクエに近く、回復アイテムの対象を敵にするといったことができませんでした。

RGSS は Ruby + ゲーム用のライブラリですが、ゲーム用のライブラリとしては以下のようなモジュール及びクラスが定義されていました (例外クラスを除く)。

  • Audio

  • Graphics

  • Input

  • RPG

  • RPG::Cache

  • Bitmap

  • Color

  • Font

  • Plane

  • Rect

  • RPG::Sprite

  • RPG::Weather

  • Sprite

  • Table

  • Tilemap

  • Tone

  • Viewport

  • Window

当時の感想は「ゲームを作る基盤部分は、この程度の数のモジュール及びクラスでできるんだ」でした。 RPG ツクール 2000 に引き続き、これも衝撃的でした。こう振り返ると、自分は RPG ツクールに衝撃を受けてばかりですね。 Daigo 氏とよく「俺たちは RPG ツクールに人生を狂わされた」と言っています。

RGSS は画像の描画について、 Bitmap と Sprite という 2 つのクラスがあります。 Bitmap が画像、 Sprite が画像を配置する何かという役割分担があります。オフスクリーンレンダリング (画面以外のバッファに対する描画) の機能はありません。 RGSS の API を眺めながら「画像を表すものを一つに出来ないか、またオフスクリーンレンダリングの機能は実現できないか」と考えました。「矩形画像から矩形画像への描画でゲームを表現できるはず」というアイデアはここから生まれました。このアイデアを実現したくなり、ゲームエンジンを開発するようになってしまったというわけです。

ゲームエンジン自作の旅

前述のアイデアを実現すべく、 Ruby、 C#、 D、 C++ などで似たようなコンセプトでゲームエンジンを作りました。いずれも、とても成功したとは言えないものばかりでした。自分のエンジニア能力不足が原因です。ゲームエンジンのちゃんとしたお作法について自分がわかっていなかったというのもあります。とはいえゲームエンジンを作りたい一心で様々な言語を学ぶことが出来ました。結局 Ebiten に至るまでは 10 個くらい作り直したと思います。ゲームエンジンを何度も作り直していく過程で、徐々に完成度は高くなっていったとは思いますが、いずれも長く続くことはありませんでした。

その中でも一番長く続いたのが StarRuby という Ruby と C で書かれたエンジンです。 Daigo 氏が RPG ツクール 2000 で「償いの時計」というゲームを作っていたのですが、それの Ruby 移植版 (?) として使ってくれました。自分はそのことをすっかり忘れていましたが、 Daigo 氏は覚えてくれていたようです。とはいえこれも 2、 3 年くらいで開発が止まってしまいました。

ここで得られた数々の知見が最終的に Ebiten に生かされたので、やってよかったと思います。

Go

2009 年頃に Google からプログラミング言語 Go が発表されました。自分は Go に一目惚れしたわけではありません。 エラーハンドリングやジェネリクスなど、他の言語にある機能が Go にはなく、失礼ながら奇異な言語であると当時は思っていました。 Gopher くんはとてもかわいいですね。

画像6

実際書いてみると「冗長で書きにくいかもしれないが、コードの挙動が非常に明示的で読みやすい」という感触が得られました。例えばシンタックスシュガーが全くといっていいほどありません。 Go では代入に見えるものは代入です。  C++ の演算子オーバーロードや C# のプロパティのように、代入に見えて隠れた副作用がある文が、他言語だとよくあります。 Go にはそういうことが一切ありません。 Go のエラーハンドリングの冗長さも議論がよく紛糾するトピックです。読む側からするとどこで脱出するのかが明示的な点が自分は好きです。もちろん Go が冗長すぎて嫌だという意見もわかります。これは好みの問題ですね。

Go はよくシンプルな言語であると言われます。 Go はモダンな言語にしては珍しく、「新機能を入れるのに極めて慎重な言語」です。正確な出典は分からないのですが、オープンソース開発について「No is temporary, Yes is forever」という有名なフレーズがあります。新機能要求について No と断るコストは一時的なものであるが、 Yes と言ってしまうと (互換性を守る限りは) 保守するコストを永遠に払い続けなければならない、と自分は解釈しています。 Go の姿勢がまさにそうです。機能だけでなく文法についても Go 1.0 がリリースされてからほぼ変化がありません。

Go と Ebiten は似ている点があります。機能セットをミニマムにするという点がそうです。哲学を意識して Go を選んだわけではないのですが、結果的にそうなっているのが面白いですね。

Ebiten 誕生

Go は言語及びツールなどの環境含め、大変気に入りました。試しに Go でゲームエンジンを作ってみようと思い立ちました。そこで出来たのが Ebiten です。 2013 年頃の出来事です。当時はそんなに長くメンテし続けることになるとは思ってもいませんでした。

画像9

Ebiten という名前は、当時 RPG ツクールシリーズを発売していた「エンターブレイン」が、 2ch (現 5ch) で「海老」と呼ばれていたからです。まあ正直、名前はユニークであれば何でも良かったんですね。和食の名前をつけるのは被りにくいのでおすすめです。

画像7

一旦 macOS で動くものができて満足して、その後半年くらい放置していました。その間 TypeScript と戯れていたと思います。その後何か些細なバグを修正するか何かで再開したところ「なぜか無性に楽しかった」ので、開発を続行することにしました。もはや自分の人生にはこれ以外ないようです。

Gomobile

2015 年頃に Gomobile というツールが出現し、Go がスマートフォンに対応しました。 このツールを使って早速 Ebiten のモバイル対応を始めました。動機は「ともかく対応プラットフォームを増やしたい」だけでした。対応するだけしておくという、下準備の段階です。この下準備が後の「償いの時計」につながるので、結果的には成功でした。

Ebiten のモバイル対応は一筋縄ではいきませんでした。詳細は省きますが、「コンテキストロスト対応」「パフォーマンス改善」「各種 Android/iOS 機種間の微妙な差異の対応」などが必要でした。実際にゲームをリリースして、多種多様な機種で遊ばれて、はじめて発覚する問題などもありました。

Ebiten のモバイル対応にあたっては、 Omega さんの「いのべーしょん 2007」を移植させていただきました。ありがとうございます。この「いのべーしょん」モバイル版は、後の出来事の非常に重要なきっかけになります。

画像4

償いの時計

先述の通り Daigo 氏とは RPG ツクール 2000 時代、つまり高校時代からの友人です。 Daigo 氏には普段から自分の「RPG ツクール作りたい欲」を語っていました。 Daigo 氏もなにか思うところがあり「じゃあうちらで何か作ろうぜ」と言ってくれました。さすが、持つべきものはツクール友達です。

当初はスマートフォン向けゲームおよびゲームエディタを作ろうという計画でした。当時 Android 上で 30FPS 程度でギリギリ動いていた「いのべーしょん」を Daigo 氏に見せて、「がんばってメンテするから、ぜひ Ebiten を使わせてほしい」と頼み込みました。快諾でした。多分。このときに「いのべーしょん」が Android 上で動いていなかったら、おそらくこの話はなかったでしょう。

後から、 Daigo 氏に「論理的に考えると普通は Unity とか使うよね」と言われました。それはそうですね…。

「RPG ツクールを作りたい」と言ったものの、時間的な問題で自分は Ebiten 及び RPG の基盤部分の担当にとどまりました。この分担は正解だったと思います。 Ebiten でさえ猛烈に時間を取られるのに、さらにエディタにまで手を出すのは現実的ではないからです。 RPG 基盤部分については、比較的短期間で Daigo 氏でもメンテナンス可能な状態になりました。 Go の学習のしやすさのおかげもありますが、 Daigo 氏自身が優秀なゲームデザイナーであると同時に、優秀なエンジニアでもあったからです。

まず、 Daigo 氏が RPG ツクール 2000 で作っていたゲーム「償いの時計」を手始めに移植することにしました。すでに出来上がっているゲームを移植するほうが考えることが少ないし、ツールを洗練させるには近道であると考えたからです。

2017 年、最終的に「償いの時計」は Android および iOS でリリースされ、ファミ通に載りました。 Go 製ゲームでファミ通に載るのは史上初です。 Daigo 氏のゲームにおける大体の出来事は Go 製ゲーム史上初ですが。

画像3

この「償いの時計」リリースは Ebiten の中でもっとも幸運な出来事の一つだったと思います。ゲームエンジンにおいて、「実際に使われないと洗練されない」「洗練されてないと実際に使われない」というニワトリたまご問題があります。この問題を「償いの時計」が打破してくれました。いままでたくさんのゲームエンジンを作っては捨てて来ましたが、この段階でやっと、「ある程度 DL されるゲームで使われるゲームエンジン」が作れたわけです。ありがとう、償いの時計。 ありがとう、 Daigo 氏。

実際にゲームを作るとパフォーマンス的な懸念が生じてくるものです。 Ebiten のミニマムな API を保てるかどうか不安になることもありましたが、内部実装の工夫で乗り切りました。例えば「自動テクスチャアトラス」「自動バッチ」などがそうです。大雑把に言うと「API はそのままに、 Ebiten 側がうまいこと GPU への命令をコンパクトにして、勝手にパフォーマンスを良くする機能」です。予想困難な挙動を生みかねず、普通のゲームエンジンだったら難しい選択肢だったかもしれません。しかし Ebiten はポリシーを貫くことにしました。 Ebiten のアート性を捨てたくありませんでした。

くまのレストラン

「償いの時計」の後も Daigo 氏はモバイルゲームをいくつか出し続けているのですが、引き続き同じ基盤が使われ続けています。 Ebiten 由来のバグで散々迷惑をかけつつも、辛抱強く Ebiten が使われました。ありがたいことです。

その中で一際エポックメイキングだったのが「くまのレストラン」です。 2018 年にリリースされました。「くまのレストラン」は、ゲームとして素晴らしいのはもちろんですが、以下の出来事を達成しました:

Google Play Indie Games Festival で TOP 3 および Avex 賞を受賞
・全世界で 100 万ダウンロード達成

特に Indie Games Festival において、「くまのレストラン」以外の TOP 20 のゲームすべて Unity または Unreal Engine といった既製のゲームエンジン製でした。その中で、自作ゲームエンジンが成果を出せたことを誇りに思います。

「くまのレストラン」の大成功をもって、当初の目的であった「ミニマムな API で実用的な 2D ゲームは作れるか」という目的はある程度達せられました。おめでとうおめでとう。

Daigo 氏はその後 Odencat 株式会社を設立しました。「くまのレストラン」の成功譚については Daigo 氏のブログ記事を読むと良いと思います。

Odencat 以外の Ebiten の使われ方

Ebiten は Odencat 以外のゲームでも使われています。 OpenDiablo 2 は Ebiten による Diablo 2 のリメイクプロジェクトです。こちらの想定を超えるような激しい Ebiten の使い方をしており、パフォーマンスチューニングに関して多数のフィードバックを頂きました。ありがたいことです。  Jae さんの Give Up the Dupe は Steam でリリースされたパズルゲームです。 Corfe83 さんの Idle Armada はクリッカー系の Android ゲームです。他、ゲームジャムでも時々使っていただいているのを見かけます。自分のゲームエンジンが使われているのをみるのは、最高に嬉しいことですね。

Nintendo Switch

Go でゲームエンジンを作っている懸念の一つとして「家庭用ゲーム機向けに移植できないのではないか」というのがありました。家庭用ゲーム機は大抵 C/C++ の専用コンパイラを使うものですが、 Go は当然そのままでは使えません。 Go ゆえのリスクですね。

2020 年初頭、斉藤大地さん (株式会社ワイソーシリアス社長) と Daigo 氏とでランチ会をやりましたが、そのときにもこの話題になりました。そのときに「Ebiten を Unity に対応させたらいいんじゃないんですか?」と斉藤大地さんに言われました。おそらく何の気もなしに言った言葉だとおもいます。しかし「Ebiten は Go でかかれているが、 Go を C# なりなんなりにコンバートできればいけるんじゃね?」という発想に至ったきっかけになりました。 Unity は Nintendo Switch 含めた家庭用ゲーム機に対応しています。 Ebiten が Unity 上で動くと、 Ebiten の対応プラットフォームが自動的に増えるわけです。コバンザメ戦略ですね。なんだかんだがあって、結局コンバート先は C# ではなく C++ になり、 Unity を介すのをやめたのですが、コンバートするというアイデアはここから得られました。ありがとう、斉藤大地さん。遅刻してたけど。

EDIT (2022-01-07): その後、 Nintendo Switch へのネイティブコンパイルに成功しました

いくつかの実験の後、 Nintendo Switch 対応もいけると確信したのは、 2020 年の年末でした。最大の懸念はパフォーマンスだったのですが、少なくとも「くまのレストラン」を動かすには十分なパフォーマンスが出ました。技術的背景については語れることが結構ありますが、それはまた今度の機会に語りたいと思います。

2021 年、「くまのレストラン」 Nintendo Switch 版がリリースされました。

「くまのレストラン」がきっかけで、とうとう家庭用ゲーム機対応まで達成してしまいました。自作ゲームエンジンとしては十分な成果だと思います。独力では絶対になしえなかった世界です。

さいごに

自分がなぜゲームエンジンを開発し続けているかについて、割と最近まで自分でもよくわかっていませんでした。「ゲームエンジン開発は人間の四大欲求の一つである」ということかもしれませんが、もちろんそんな訳はないですね。最初に述べたとおりこれは自分の美的感覚の追求であり、「ミニマムな API で実用的な 2D ゲームが作れるかどうか」ということを証明したかったのです。こんなモチベーションで続いている自作ゲームエンジン開発ですが、様々なご縁があり、今のような成果に至ることができました。関わってくださった皆様には感謝してもしきれません。

Ebiten はかなり使われるようになってきたとはいえ、使われているゲーム数からして、まだまだ弱小インディーゲームエンジンの一つであることに変わりはありません。今後ともユーザーを増やす努力をしていきたいと思います。アートと実用品を両立させつつ、どこまで世界を広げられるか、今後とも楽しみでなりません。

License

Go Gopher by Renee French is licensed under the Creative Commons Attribution 3.0 License.


この記事が気に入ったらサポートをしてみませんか?