動的言語を併用しよう

C/C++/ObjectiveC(以下C族言語)を使うときは、LuaやRuby,Pythonなどの動的言語を併用しましょう。

ゲームプログラミングは「変えて、試しに遊び、また変える」という作業の連続です。動的言語は、これを速く行うのに有利な特徴を備えています。

動的言語の極めて重要な特徴は、スクリプトの読み込みがとても速いことです。LuaやJavaScriptでは、毎秒数十万行以上を読み込み、実行できます。C族言語では、コードを1文字でも修正するとコンパイルとリンクが必要で、場合によっては耐え難い時間がかかります。

また、動的言語ではコードを速く書くことができます。

メモリの管理をGCに任せられる、クラスのメンバの宣言を書かずに直接代入できる、関数の型宣言を書かずに非同期のコールバック関数を駆使できることがあります。C族言語におけるコールバック関数の宣言や型の修正はひどく大変です。

C族言語への組み込み可能な動的言語の中でも、特にLuaはゲーム開発に最適です。Luaは実行速度が速く、文法などの仕様もクリーンで、co-routineなど便利な機能も備えているのですが、そうした「スペック表」からは見えにくいLuaのよい点を紹介します。

まず、C族言語で以下のように4行ほど書けば、Luaの処理系を組みこめます:

lua_State*l; l=lua_open(); lua_dofile(l,”yourscript.lua”); lua_close();

lua_Stateが、Luaの処理系です。当然ながら、「Lua/CからLua/Cの関数を呼ぶ」ことも、数行の単純なコードで実現できます。

そして、Luaの処理系は数十KB程度におさまります。初期化も極めて速く、1万行のスクリプトでも数ミリ秒で読み込んで実行できるので、ゲームで敵が出現するごとに処理系を生成したり破棄したりといったことも可能です。このため、データをメモリに保持したまま、処理のロジックだけを入れ替えてプレイを試せます。これによって、音声や画像データが多いゲームや、毎回の起動が遅いモバイル環境での開発効率が改善されます。

Luaの処理系がここまで小さく軽いのは、機能が最小限だからです。例えば、Luaには正規表現が含まれていません。組み込み用のRubyであるmrubyですら、ソースコード7万行のうち、何と60%程度が正規表現のために割り当てられています。また、LuaのパーザはCで1,600行しかありません。mrubyでは、yaccで100KB、Cに変換すると1万行もあります。複雑な文法規約と、強力な文字列処理を含む必要があるため、どうしても大きくなってしまうのです。

次はJavaScriptエンジンと比較してみましょう。最近のものは、GmailのようにJavaScriptのみで書かれた大きいアプリケーションを高速に動作させるために高度な最適化JITコンパイラを装備しています。例えばV8の場合、20万行以上あるソースの大部分がJITで占められています。Luaの場合、高速性が必要な処理はC族で書くことができるので、JITは不要です。

技術以外の面はどうでしょうか。Luaは、AngryBirdsからWorldofWarcraftまで、多くのゲームで実際に使われていて、米国の大手のゲーム会社が開発のスポンサーになっています(会社名は非公開)。書籍やウェブ上の記事も多く、非常に大きな利用者規模をもちます。

このように現時点では、フルオープンソースで、十分に動的で、小さく、軽く、組み込みに適し、十分な利用者規模を持つ軽量言語はLua以外にはありません。

C族言語を使っているならば、一度はLuaを試し、特性を把握しておくべきです。