続・ゲームにおけるスクリプト言語の現状 メモ
4/18 に行われた 研究会のメモ。
すでに何人もの方がレポートを書いて下さっているので、興味がある部分があればリンク先を参照してください。
基本的に軽く記述してあるだけですが、他の記事であまり触れてない Squirrel に関しては、ある程度記述してあります。
感想
今回は、第1回(前回)のパネルディスカッションの面々が個々の事例を掘り下げるという、事例ベースのセッションとなっていた。
間に15分休憩があるだけの4連続だったのでけっこう疲れたけど、充実した内容にかなり満足。
前回がっかりした人ほど、今回は満足できたんじゃないかな。
ごく簡単な並列処理スクリプトシステムの設計と実装
『サクラ大戦Ⅴ』でのスクリプト運用事例
- サクラ3,4,5 での事例
- イベント画面演出
- マルチスレッド記述
- スクリプタにはしきいが高かった(実際1人しか使えなかった)ので、次の2つを用意
- アニメーションをタイムテーブルで記述するアクションシステム
- 2D画面にエフェクトを重ねて表示するエフェクトシステム
- 見た目が派手なので、エフェクトシステムが最も使われた
- マルチスレッド記述
- 中断セーブ
- マクロ形式
ここまで前半戦。
どちらも、プランナーがいかに書きやすいか、いかにバグを出さないかを念頭に置いて開発している印象。
プログラマがいかに気配りできるかが大切だと感じると共に、もしかしてゲーム業界的にプログラマはそんな数要らない?とも思った。
汎用スクリプト言語Xtal 設計と実装
講演者の人柄か、終止笑いが堪えない良い感じのセッションだった。
Squirrelスクリプトを使った実装と活用
他のセッションと異なり、過去のことではなくここ1,2年の状況を惜しみなく提供していた。
ちょっとしたテクニック
- グローバルシンボルは、getroottable() で、ルートテーブルを探せばすべて見つかる
foreach(key, val in getroottable() ) print("key=" + key + ", val=" + val + "\n");
- これを活用して、#ifdef のようなことが可能
if( "hogehoge" in getroottable() ) { print("hogehoge 発見!値は=" + ::hogehoge + "\n"); }
- roottableを使って、class の名前を取得
// instance か getclass の値を入れたら、クラス名が返る function getClassName( classDef ) { if( typeof(classdef) != "class" ) { return "*NotClass*" } foreach( name, item int getroottable() { if( item == classdef ) { return name; } } return "*UnknownClass"; } }}} class Foo {} local ci = Foo(); print( getClassName( ci.getclass() ) + "\n" ); print( "ci=" + getClassName( ci.getclass() ) + "\n" );
- 定義済みのFunction, classを解放
delete getroottable()["関数名/クラス名"];
- ごく簡単なprintf実装
function printf( msg, ... ) { local arg = array(7); local i = 0: while( i < 7) { if( i < vargc ) { arg[i] = vargv[i]; } i += 1; } print( format(msg, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6] ) ); } local i = 10; local f = 0.1; printf("%s", %d, %f, %s\n, str, i, f, "aaa"); [実行結果] str, 10, 0.100000, aaa
実装
- 組み込みにはSQPlus を使用。
- import は、比較的簡単に実装可能。これがあるとソースを分けて管理できる
- FileLoad() → CompileBuffer() → RunScript()
- importしたファイルをプログラムで管理し、タイムスタンプをチェックしながら再読み込み出来るようにしておくと、エラーの回復がし易くなる
- C++で生成したクラスのポインタをそのままSquirrelに見せる場合、try 〜 catch を使って Squirrel のスタックダンプを呼び出せるようにしておくのがオススメ
- コードとデータ例
// 敵データ例 ::gameData enemyDataArray <- { { label = "worm", vitality = 4; strength = 3; }, { label = "moo", vitality = 3, strength = 4, }, }; // 敵クラス例 class Enemy { _enemyData = null; constructor( id ) { _enemyData = ::gameData.enemyDataArray[ id ]; } function GetVitalityMax() { return _enemyData.vitality; } }
- 以下のような変更にも、柔軟に対応できる
// 敵データ例 ::gameData enemyDataArray <- { { label = "worm", vitality = 4; strength = 3; }, { label = "moo", vitality = 3, strength = 4, abilityArray = [ ::ALIBITY_BITE ]; // 追加 }, }; // Ability に対応する処理を追加する if( "abilityArray" in _enemyData ) { // アビリティありデータ } else { // アビリティなしデータ }
制作
- プランナーとの連携のために、.xml などから .nut へのコンバータを用意しておくと便利。
- C++のヘッダファイル情報から、バインドコードを自動生成するツールを作った(Rubyで作ったぽい?)
- .nut をデバック用に出力
- foreach, typeof などを使って、比較的簡単に Squirrel 上のデータを .nut に出力することが出来る
- 実機上でデバックメニューなどで調整したデータを、ファイルに書き出せると調整等がやりやすくなる。
- デバック
- Squirrel を使った開発では、エラーの多くがランタイム上で起こる
- 対策
- スタックダンプ
void ScriptManager::PrintCallStack()
{
sqstd_printcallstack( SquirrelVM::GetVMPtr() );
}
- デバッガ
- eclipse / SQDev
- 最近、アルベルト氏がVS用デバッガを公開したらしい
- エラーの回復
- スクリプトエラーが発生した場合は、スクリプトの呼び出しを一時中止し、その間に問題のソースを修正
- 空回りでもいいし、埋め込みのブレークポイントなどでもよい
- タイムスタンプが更新されたスクリプトファイルを読み込み直して、処理を続行
- ただし、class インスタンスのような場合、これだけでは回復できない
- 最も簡単な方法は、その class を保持しているプログラムが、Squirrel 上で try 〜 catch して、再読み込みを行った後で再度インスタンス化すること。
- 例えば、Enemy の中で止まった場合、EnemyManager が再読み込みを発行し、問題の敵を除外し、敵セット情報を元に Enemy を再生成する。
- スクリプトエラーが発生した場合は、スクリプトの呼び出しを一時中止し、その間に問題のソースを修正
- 最適化
- 気をつけるべき重い処理
- 文字列の加工
- realloc が頻発する。フレームレートに影響するほど。
- コピーの発生する引数や戻り値の受け渡し。(String など)
- 文字列の加工
- GC
- 毎フレーム実行するには重い
- GC実行タイミング
- 往復を減らす
// これを local player = SQPlayer(); local vec = player.GetPos(); // retval SQVector vec.y += speed; player.SetPos( vec ); // こうする local player = SQPlayer(); player.AddPosY( speed ): // C++ 側で posVec.y += speed される
会場の雰囲気を見る限り、これから 国内では Squirrel が流行っていくかもしれないという印象。
現在 Lua を使っているところも結構多いが、やっぱり文法などに不満を持っている人もかなりいるようで。
Xtal は、やっぱ実績がないと厳しいんじゃないだろうか。
Squirrei は国内でスクエニが導入して、情報を惜しまず公開してきたから流行っている側面もあるし。
Squirrel にとってのスクエニのような企業が出てくればあるいは。
他サイトのレポート
- INSIDE
- 第1回のレポート
- 公式?のまとめ
- この辺は、行ってない人には分かりづらいかも?