ゲームとフロントエンドの開発は似ています。ここでいうフロントエンドとは、ReactやVue.jsのような最近のフロントエンドを行う際にWebエンジニアによく使われているライブラリでの開発や、スマホアプリでいうFlutterなどを使った開発のことを指します。
具体的に何が似ているかというと、宣言的であるということです。つまりは仮想DOMを含めたstateを宣言しておき、ライブラリ側ではそれを描画するだけという部分です。
なのでそういったフロントエンド開発に慣れている方は慣れていない方に比べてゲーム開発もすんなり入っていけるのではないかという話です。
そもそもゲームはReactやVue.jsといったライブラリが出るだいぶ前から宣言的なものでした。
ゲームにはゲームループというものがあります。ゲームのロジックを動かす処理と、描画を行う処理は独立しています。まずプログラムでゲームの状態を操作します。例えばキー入力があればキャラの位置を動かしたり、タイマーで毎回自動的に呼ばれる処理で敵の位置を動かしたりします。そこで宣言されたステートを元に、描画処理が行われます。
では逆に宣言的でないゲーム開発はどういうものかというと、古くは家庭用PCのBASICなどで簡単なゲームを作る場合、例えば正方形をキー入力に応じて動かそうと思うと、まず正方形を描画し、キー入力されたらその正方形がある部分に黒で塗りつぶして、移動した先に正方形を書く、のような作り方をしたりしていました。
Windowsのゲームでも同様のことができました。画面にキャラを描く関数を呼んで、キー入力があれば背景画像をそこに書いてから移動先にキャラを描く、のような具合です。
想像できるかもしれませんが、一瞬キャラが消えるのでちらつきます。
こういうのWebで同じようなのを見たことがないでしょうか? そうです、jQueryなどもそうでしたし、とにかくDOMを直接いじっていく手法と同じです。ReactやVue.jsなどのライブラリが普及する前はWebもほぼそのような開発でした。
ではなぜゲームは宣言的になっていったのでしょうか? こたえは簡単ですが、ゲームにはDOMが無いからです。
例えばJavaScriptでチェックボタンに応じて要素を表示したり消したりするプログラムを作るとします。これには2通りの作り方ができます。一つはチェックボックスの状態を見る方法です。チェック後、チェックボックスの状態を確認してチェックされていたら要素を表示し、チェックされていなかったら要素を消すというやり方です。
もう一つの方法は、状態を変数で持っておく形です。クリックされたら変数をトグルし、それに合わせて要素の表示、非表示を行います。
JavaScriptだとこのようにどちらの方法でも作ることができます。しかし、ゲームにはDOMなどありません。同じことをやろうとしたらやり方は一つしかありません。状態を変数に必ず持っておく必要があります。この制約があるため、強制的にゲームは宣言的なものとして作られるようになっています。もちろんあるピクセルに描画されている色をみて判断する、のような方法もありますが、何もメリットはないでしょう。昔ならともかく現在はグラデーションで描画されることがほとんどなので色の判断は難しいですし、そもそも色を見るくらいなら0&1の1ビットで状態を保持しておく方が効率的です。
ゲームでは仮想DOM的な位置づけとして、ゲームのシーン、そしてその中に表示される様々なもの、例えばゲームエンジンによって違いますがスプライト、ゲームオブジェクトなどと呼ばれるものを作り出し、それにキャラの座標などの状態をもたせ、それを描画処理の時に描画するという仕組みが古くから使われています。僕がはじめた入った組み込み系の会社でもそのような仕組みが使われていました。最低でも2005年くらいにはそういった仕組みでゲーム的なものをつくることは当たり前だったのではないかと思います。フロントエンドの仮想DOMを用いた開発が普及するよりもだいぶ昔です。
面白い仕組みだな、と思い僕もDirectXやOpenGLで真似てみてWindowsやAndroidのゲームを作ってみたりしていました。そんな感じで当時はどこの開発会社も自前のゲームエンジンなどを作って開発していたのではないかと思います(事実新卒の時にゲーム会社の会社紹介にいったりしましたがそんな感じでした)。
ではなぜJavaScriptによるフロントエンド開発も宣言的になったのかというと、やはり状態の管理がDOMとアプリケーションで2重になってしまうことで複雑になっていた問題を解決するためだったのではないかと思います。DOMとアプリケーションの状態が両方見れてしまうということが問題で、複数人の開発ではそれぞれの思想により作り方がバラけてしまうと何がどうなっているか把握するのが困難です。宣言的な作りにより状態を一つにすることでシンプルにすることができるようになりました。
またDOMはあくまでもブラウザの仕組みですので、テストを自動化しようと思ってもどうしてもブラウザとの連携を考えなくてはならず、e2eやブラウザと連携するソフトウェアを使った方法でしか実現できませんでした。仮想DOMにすることでアプリケーション自体をブラウザと分離することができ、そういった問題もシンプルになります。
とはいえDOMがなんだかんだでいろいろな事ができてしまう便利なものだったので、長らくそこに行き着く発想を阻害していたのかもしれません。
とにかくそういったJavaScript用のライブラリを使ってみたとき、ゲーム的だなと感じました。どちらもステートを持って描画するものなので、たしかにそれはそうかと思いました。
現在はUnity, Unreal Engine, Godotといったいくつかのゲームエンジンがあります。それによって色々と開発者がすべきことは減りました。シーンをひょいっと作ってそこにオブジェクトをヒョイッと入れれば勝手にもう色々と初期化してくれます。
物理エンジンを使うことによって動きすらも自動的に行われるようになりました。いちいち落ちる時の重力を計算して下に座標を動かす必要もありません。他のものに触れたときの設定や、別途処理が必要であればそれだけ書けば動いてしまいます。
もちろんそれらの理解をする最初の負荷はありますし、いろいろな事ができる分逆にやらなければならないことが増えたりもしています。とはいえ昔にくらべてゲーム開発は簡単になりました。自分でゲームエンジンを作る必要もなくなったわけですし。
ゲーム作りやってみたけどな……と思っているフロントエンドエンジニアの方はぜひ一度試してみると面白いと思います。逆にフロントエンド開発に役立つ部分も見えてくる可能性もあるかもしれません。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント