ちは
「スクリプト言語による効率的ゲーム開発 C/C++へのLua組み込み実践」を読んだ感想,レビュー,備忘録です。
Amazon
改訂版です。
自分が読んだのはこっち。
2008年10月7日の初版でした。
読み始めた経緯
就活が終わって暇な時期に,RPGでよく使われるLuaについて知りたくてAmazonで中古で買いました。
買って満足して放置してたけど,本棚の整理と積み本消化を兼ねて読みました。
対象
- RPGを本格的に作りたいけど,会話関係をどうしたいかわからない人。
- ソースコードにゲームのパラメータを直書きしている人。
- LuaとC/C++連携を知りたい人。
- 実践的なゲーム開発スキルを身に着けたい人。
- 開発速度の改善を図りたい人。
- コンシューマゲームを開発することが決まった学生。
- luaを内製エンジンに取り込みたいけどやり方がわからない人。
内容は古く,UnityやUE4などのゲームエンジンが蔓延る現代で必要かと言われると答えづらいですが, コンシューマゲーム開発にはLuaとC/C++連携は今でも必要な知識だと思います。
エンジン開発やスクリプト導入したい人は読んでおいて損はないはず。
後はUnityなどでも利用されているみたいなので,ゲーム開発者でLuaを知らない人は読む価値は十分にあると思いました。
参考
執筆時点(20220717)では,まだCEDEC2022で発表されていませんがソーシャルゲームでも使われていますね。
cedec.cesa.or.jp
DQXやFFXIVでも使われているみたいですね。
atmarkit.itmedia.co.jp
game.watch.impress.co.jp
本書では,WoWやシムシティ,ラグナロクオンライン,ナイツなどが紹介されていました。
2022/12/25: C++とLuaの連携について書きました。
良かったら読んでね。
lambda00.hatenablog.com
注意
サンプルコードの公開は終了していたので,基本的には独学になると思います。
(執筆時点: 20220717)
まあ,C/C++とLua連携の参考として読むのが良いと思います。
www.sbcr.jp
メモ
第1章 ゲームの開発速度は十分ですか?
スクリプト言語の必要性についてがメイン。
・「敵の速度パラメータを5.0fから6.0fにして...」とか「10フレーム以内にウィンドウを出して…」とかをプログラマが逐一修正して,ビルドしてからプランナに確認してもらうのは無駄だよねって話。
ゲームに限った話じゃないけど,細かな修正によって製品の品質は左右されるので修正の繰り返しは仕方がないよね。
でも,プログラマでなくてもこの修正は出来るよねって話かな。
・プログラム修正のサイクルは「コーディング」,「ビルド」,「修正箇所に移動」,「結果確認」の4工程。
ビルドが30秒かかると,細かな修正の度に30秒失うのは馬鹿にはできない。
けど,良ゲーがクソゲーにもなり得るから妥協はしたくない。
・ビルド時間はプログラマが働いていない時間。
これはマジでそう。
大規模になると1つの修正にソースコードの依存関係から1分待つとかザラにある。
C++テンプレートは結構時間かかるよね。
distccやIncrediBuildで並列コンパイルするよねとかも書いてあった。
・ゲームに詳細な仕様書が存在しない。
これもあるあるだよね。
業務システム開発とゲーム開発の決定的な違いは,作ってみるまで面白いかはわからないこと。
つまり,作る前から詳細に仕様書を作成しても没になるかもしれないから作りづらいってことでもあるね。
(なるべく詳細な方がいいけど。。。。)
第2章 ゲーム開発をスピードアップする
スクリプト言語とは。
・ロジックとデータの分離。
move(x, y)て関数を考えるとmove(10, 20)てハードコードするのはダメだよね。
最低でもデータファイルなどにパラメータをまとめて,参照するようにしようね。
・スクリプト言語。
スクリプトを組み込んだプログラムからすれば,スクリプトは「データのように扱えるロジック」に見える。
RPGならイベント制御,SLGなら思考ルーチンとかのロジックをデータ化できるよ考えると凄さがわかるはず。
・オレオレスクリプト言語。
用途: シナリオ面の演出や分岐の表現など。
メリット: 用途に適した実装が可能。
デメリット: 言語処理系の独自開発コスト,公開ツールをそのまま使えないなど。
後は,そのゲーム開発にしか役に立たないとかかね。
・汎用スクリプト言語。
LuaやPythonとか。
メリット: 高度な言語機能が多く,開発効率が高い。豊富なドキュメントなど。
デメリット: 汎用故の速度やリソースが使用用途に合わないなど。
・スクリプト言語による高速化。
スクリプト言語はデータとも考えられるので,プログラム実行中にリロードが出来るよねって話。
・何をスクリプトにすべきか。
・敵キャラのAI部分。
・UI定義や動作調整。
・シーン遷移。
・ゲーム勝敗条件のチェック。
など,たくさんあるけど要は「高速性を要求される以外ほとんど」と言えるかも。
速度が気になるなら後でC/C++で置き換えればいいし,とりあえず開発速度重視でスクリプトで開発するのはいいかも。
第3章 スクリプト言語の選択
スクリプト言語の位置づけなどについて。
・ライセンス。
無視したいけど,無視できない要素だよね。
・動作環境。
ターゲットとするデバイスで動作しないなら意味ないしね。
・メモリ管理機構。
プログラム終了せずにリロード出来るけど,雑に作るとメモリリークするから気を付けようね。
マーク&スウィープ方式とリファレンスカウント方式の2つに大別される。
さらに進化したインクリメンタルGCや世代別GCといった手法もあるよ。
・速度。
C/C++よ比較するとかなり遅いかもよ。
特にメモリ管理速度は重要だよ。
・バインド機能。
C/C++の関数をスクリプトから呼べるようにする作業をバインドすると表現する。
この作業は大変だからなるべく自動化したいね。
・リロード機能。
実行時に動的ロード出来るか。
実行時に関数やクラスを再定義出来るかが焦点。
・メモリ消費や安定性,記述性。
そらそうよって話。
・スクリプト言語の候補。
Lua, Squirrel, Python, PAWN, Ruby, GOAL,
AngelCode Scripting Library "AngelScript", GameMonkey Script,
Xtal, CRI Script, Io, Erlangなど。
詳細は本書に書いてあるから気になったら読んでね。
ゲーム向けではLuaが強い。
第4章 スクリプト言語 Lua
基本的なLua文法の解説がメイン。
気になったとこだけメモ。
・Virtual Machineとは。
他のOSを動かすものではなく,ここではLuaがスクリプトを実行するエンジン部分のこと。
・グローバル変数とローカル変数。
変数前にlocalをつけるとローカル変数。
do~endなどのブロックも意識しようね。
・ブロックコメント。
-- と で挟む。
・三項演算子。
x = a and b or c
・配列に穴があると動作は未定義。
配列の途中でnilがあるなど。
第5章 LuaをC/C++プログラムに組み込む
本書のメイン。
・Lua C API
Lua標準で用意されてる機能。
// LuaのVMを生成。 lua_State *L = lua_open(); // Luaの標準ライブラリを開く。 luaL_opemlibs(L); // Luaスクリプト実行。 luaL_dostring(L, "print('Luaだよ!')");
・スタック。
Lua VM内の値とC/C++の値のやりとりはスタックを使用する。
スタックはLuaの管理する領域の内側ということを意識しようね。
・tolua++
C/C++の各種要素をLuaから使えるようにするためのグルーコードを自動生成するツール。
MITライセンスらしい。
第6章 プログラムを止めない開発環境を作る
リロードするときのエラー処理などのお作法について。
・リロードと言語要素との相性。
関数は◎,変数は△,クラスは〇。
AIは〇,GUI周りは◎,グラフィックエンジンは△。
グラフィックエフェクトは◎,シナリオは◎。
ゲームのコア部分は〇,デバッグ用は◎。
まあ,何となくわかるよね。
・スクリプトでもDRYの原則。
そうだね。
第7章 ゲームシステムを作る
RTSを作りながら実際にLuaとC/C++連携を体感する会。
・描画などのややこしい部分はC/C++がお勧め。
スクリプトはゲーム構成の上位概念を担当するのが良さそう。
ようは,低レイヤーっぽいところはスクリプトはノータッチ(がいいかも)。
・コルーチン。
協調的マルチスレッドを実現する機能。
OSのマルチスレッドと似てるが,適用範囲が結構違う。
比較的簡単で,雑な理解でもどうにかなる気がする(体験談)。
第8章 「ゴチャキャラ」ゲームを作る
前章の続き。
SDLとOpenGL2系の解説もちょいちょいあるが,現代(20220718時点)では流石に古いかな。
でも,ゲーム開発を流れを理解するという点では何も問題ないはず。
第9章 スクリプト採用への疑問に答える
割と本書のメインコンテンツな気がする。
・スクリプトの速度。
C/C++と比較すると遅いのは事実(20220718時点)。
詳細は省くけど,代入から関数呼び出しなどの速度まとめの表がある。
・グローバル変数よりローカル変数のほうが速い。
グローバル変数は1つのテーブルなので,テーブルから検索処理を行うから遅い。
ローカル変数は,VM上の非常に高速に取り出せる領域に置かれるから速い。
・文字列連結は最低限に。
Luaは新しい内容の文字列が扱われると,それを新しいオブジェクトとして扱う。
この時,ハッシュ値をセットして管理するため遅くなる。
・スクリプトのコンパイルはゲームループでは行わない。
まあ,そうだよね。
イベントハンドラ経由がいいかもね。
・スクリプトからC/C++言語への置き換え。
スクリプトで書いて遅いと感じた時にC/C++に置き換える。
UE4とかでも同じ考え方があるよね。
・メモリアロケーション。
スクリプト言語は動的メモリ確保が基本条件の1つ。
ゲーム開発に付き物のフラグメンテーションとの戦い。
プレステとかだと結構気になるよねって書いてあるけど,現代だとそんなに気にしなくても良い気がするね。
・ガベージコレクション。
マーク&スウィープ方式: 循環参照に強いけど,GCが開始するとスクリプトが停止する。
インクリメンタルGC方式: リアルタイム用途に適しているが,制御がやや難しい。
・世代別GC方式。
Luaでは採用されてないらしいけど,比較的有名らしい。
最近確保されたメモリに対して,マーク&スウィープ方式を適用するイメージ。
・リファレンスカウント方式。
オブジェクトに参照カウンタを持たせる方式。
割と一般的な気がする。
付録A Lua C API リファレンス。
付録B tolua++リファレンス。
省略。
感想
既にC/C++とLuaを頻繁に使っているのでメモする箇所が少なかったですが,Luaについて曖昧だった点が明確になった気がします。
購入した学生の時に読んでおけばよかったな~と思う1冊でした。
C/C++とLuaの連携やLuaについて詳しく知りたい人は読むと幸せになれると思います。
所々でプレステ2の話などがあって,時代を感じました。