トップ «前の日記(04/08) 最新 次の日記(04/21)» 編集

hossy online - といぼっくす

ゲームの感想日記、たまにIT・プログラミングの話


04/19

_ [商用ゲーム] 「続・ゲームにおけるスクリプト言語の現状」レポートと感想 その1

4/18に、IGDA日本ゲームテクノロジー研究会(SIG-GT)第13回研究会「続・ゲームにおけるスクリプト言語の現状」に行ってきました。以下4タイトルの、50分ずつの講演会。

タイトル講演者所属資料
ごく簡単な並列処理スクリプトシステムの設計と実装小久保啓三氏HAL東京、元スクウェア24P
『サクラ大戦Ⅴ』でのスクリプト運用事例秋葉晴樹氏セガ50P
汎用スクリプト言語Xtal 設計と実装石橋立宣氏バンダイナムコゲームス39P
Squirrelスクリプトを使った実装と活用神尾隆司氏、北出智氏スクウェア・エニックス90P

順番としては、最初2つが古いシステムの設計、次が新しいシステムの設計、最後が新しいシステムの利用。

以下、その時に取ったメモを見ながら書いています。勝手に解釈している所もあり、間違ったことが混じっている可能性ありです。また、とても長いエントリになりそうなため、後半部は別にしました。

ごく簡単な並列処理スクリプトシステムの設計と実装

当時スクウェアで使われていた、ACTORモデル (wikipedia:アクターモデル) を扱う言語、ATEL (Active Time Event Language, エーテル) について。前回 IGDA SIG-GT 12「ゲームにおけるスクリプト言語の現状」に引き続き、クロノトリガーっぽいイベントをサンプルに使用。

Final Fantasy 4, 5の頃は、上から順番に処理が流れる形式だった。その頃は同時にキャラを動かそうとすると、

MES 「さあ、しゅっぱつだ
MES 「エイ、エイ、おー
MMOVE
  海賊-A  10,20
  海賊-B  15,25
  海賊-B  20,30
MEND

このように Multi Move 処理文で囲って、直列処理中でなんとか動かしていた。しかし、たとえばクロノトリガーの戦闘シーン直前、何体もの敵がマップの外側からそれぞれ個性をもって動いてくる処理を行うときに、このような記述方法では大変。そのため、アクターモデルを採用した。

[クロノ]
  bind user character
[マール]
  bind character 2
*talk turn to クロノ
        mes "急ぎましょ"
      req カエル 急がせる
      move to クロノ
[カエル]
  bind character 3
*急がせる  move to クロノ

ここで、カエルに「急がせる」というリクエストを送った後にもマールのイベントは次に進むため、マールとカエルが同時にクロノのもとに集まるイベントになる。また、マール・カエルとそれぞれの処理を独立して細かく指定できるようになり、派手な動きをしやすくなった。

Virtual Machine実装については、当時の SFC のハード的な制約がかなりあったとの事。無制限のキューやスタックは厳しいため、8段階の優先度を持つプログラムカウンタを使うようにしたり、1フレーム毎の垂直同期を見て、描画系で優先度の低い処理が溢れそうになるとそれは打ち切るような工夫を入れた。これは PlayStation になると不要になった。

スクリプターからの意見として、ACTORモデルでは今までと考え方が違って、一連のイベントを書きにくいという話が出た。この対処として「ディレクター」という仮想アクターを作って、それに制御を任せることで従来と同じような記述を続けられる。しかしAボタンを連打するようなイベントでなければ、アクターモデルの普通の書き方で十分行える。ユーザコントロールが奪われる時間を短くするよう、時間を測定して神経質に行っていた。それでも残念ながらFFのイベントシーンは長いと言われていた。

並列処理につきもののデッドロック (wikipedia:デッドロック) は、やはりここでも悩まされた。FF7 で懲りて、テレビ画面上でなにが待ち状態になっているのかが分かるようなデバッグの仕組みを入れたり、様々な工夫を行った。しかしそれでも起こってしまうものについては、「長時間のリクエスト待ちを自動解除する」という最終手段を入れることによって解決した。完全に固まってしまうとセーブすらできなく、プレイヤーから苦情が来るため。しかし、本来処理すべきものが無かったことになるというのは大きな副作用で、これは決してお勧めできる方法ではない。

QA。

シナリオの圧縮について?
容量の厳しいハードでは圧縮が大事。コードは1バイト (講演中では拡張命令は2バイトと言っていた気が)。メッセージは一般的な圧縮のみで、もともとAボタン連打にならないようテキスト量を削ったり、漢字については出現頻度や必要性からどれを使うかを選んだりした。
ウィンドウからはみ出す文字の改行は誰が指定する?
企画者が入れる。多国語対応では困ったとの事。日本語の1単語が1行になることもあったり。コンパイル時にウィンドウから溢れるときのwarningを入れていたと。
FF1〜4では行っていなかったスクリプトの採用動機は?
クロノでバトルとフィールドをシームレスにつなぐこと。

感想。多分RPGツクールを使った事のある方には馴染みがある話。古いシステムをベースとして紹介し、あとの発表に繋げるという位置づけとすると、まぁ。HAL東京の先生ということで、話し方がとても巧いと感じました。

RPGにおけるAボタンの連打をいかに減らすかというこだわりが印象的。このあとに秋葉氏の講演が続くのがまた。

クロノトリガーにはまっていた人としても楽しめました。公演中にトリガーを知っている人の挙手がありました。半分以上? さすがに多かったです。

『サクラ大戦Ⅴ』でのスクリプト運用事例

今はNintendo DSの作品を開発している秋葉氏が、2005年にリリースされたギャルゲー サクラ大戦Ⅴ の、会話パートと移動マップについて講演。

今回対象になったスクリプト+その周辺は、主にこれら。

サクラスクリプト
イベントやシナリオなど、ゲーム全般を制御するもの。C言語ライク。サクラ大戦3で原型を作成し、それから継続的に拡張・メンテナンスを行っている
マクロ形式
シナリオ担当者向けに、メッセージ部分の記述が簡単にできる、日本語で書かれた形式。NScripterっぽい。サクラスクリプトに自動変換できる
イベントリスト
移動マップの管理。データの整合性を確認しやすいよう、Excelシートで管理。入力を支援するためのVBAあり
HSL
ゲーム機向けの軽量なデータフォーマット。XML風で、テキスト形式とバイナリ形式を相互変換でき、どちらも同じAPIで扱える。HLSLとは全くの別物

サクラスクリプトのサンプル。

module SCENE0101
{
  Bg (2004)
  Face( 60 )
  
  Face( 18, 1, 1 )
  Print("……大神司令、//大河新次郎少尉を//お連れいたしました。", 15010)
  
  Nc( 17, 1, 1, 0 )
  Face( 17, 1, 1 )
  Print("大河少尉、良く来たな。//さくらくんもご苦労だった。", 15011 )
}

変数領域の新規割り当てはなく、固定長配列の32bit整数、浮動小数、文字列を扱えるのみ。

大域1: システムフラグ s000〜255
永続的に値が保存されるフラグ。ゲームクリアフラグなど
大域2: ゲームフラグ g000〜255
ゲーム開始時に初期化される
大域3: ワークフラグ w000〜127
スクリプト終了時に初期化される
ローカル1: テンポラリフラグ t000〜015
引数やローカル変数として
ローカル2: リザルトフラグ r000〜015
複数の返値

このように寿命によって変数名を変えることにより、フラグ操作ミスによる深刻なエラーを防ぐことができた。

この数値と意味のマッピングは、Excelで管理している。また、スクリプト中に生の s016 という値を書かなくても、以下のよう #define を使うことができる。

#define flag_SAKURA5_CLEARED  s16  ;ゲームクリアフラグ
#define flag_CLEAR_HEROINE    s17  ;ヒロインクリアデータ

フラグの暗号化は、詳細はセキュリティーの関係で言えないが、しっかり行っている。チートは最後までされなかった。

マルチスレッドについて。「Thread( SubThread )」のようにスレッド作成命令を使ったり、「Print("はじめまして。//<!Face(30,2)>わたし、真宮寺さくらです。<*>")」のようにメッセージに埋め込むこともできる。イベント演出で背景やキャラクタなどのアニメーションを同期させるときに、このスレッドの仕組みを使えば理論上は行えるが、製作には熟練を要し、実際サクラ3では一人しか演出をできなかった。そこで他のシステムを用意したところ、一番エフェクトに凝ることができる戦闘パートのシステムが戦闘以外でも使われるようになった。

スクリプト先読み。背景画像や立ち絵を読み込むのには時間がかかりひっかかってしまうため、Print文のようにカーソル待ち状態がある間に、先の行を実行する仕組みがある。フラグ操作や画像読み込み等の「内部状態のみ変わる」ものは自動的に数ステップ先まで進め、フェード演出やSE再生のように「画面、音声に影響する」ものについてはそこまでで先読みを自動的に止める。ちなみにこの仕組みでは、実行中のスクリプト位置が複数になり、中断セーブ時にどの状態を取るのが良いのか分からなくなるとか。そのためにサクラ対戦では、Print命令のたびにシリアライズ用のスナップショットを作るという処理を行っていた。

マクロ形式。日本語ライクなテキストをサクラテキストに変える、大きな文字列変換システム。

マクロ:
■BG 支配人室
 
サクラスクリプト:
Bg( 1001 )     ; 支配人室
fade()

基本的な置換ルール、■BG を Bg() に変換し、それが引数は最大いくつまでで、といった所まではプログラマが担当。「多少の誤字脱字も受け付けて欲しい」「未定のIDでも変換して欲しい」という無茶な要求にも対応する必要があり、このID置換定義 (支配人室→1001) はシナリオ・スクリプター管理にして柔軟に変更してもらう事で解決した。

移動マップについて。アドベンチャーシーンで同じキャラクタが同じ時間に複数の場所にいるという事を防ぎたかった。サクラⅤ以前ではイベントの自由度を重視して全てスクリプトで書いていたが、これは後から非常に確認しづらかった。書いた本人しか内容を判別できなかったり、仕様書と異なるスクリプト実装でリリースされてしまった事もあった。この乖離は、リリース後にも攻略本作成などで問題になってしまう。

これ解決するために、サクラⅤではExcelのイベントリストに一元化して、これを見ればすべて分かるようにした。条件分岐入力はExcel VBAで支援。この結果を HSL 形式で export し、ゲームに組み込んだ。スクリプトの知識が全く不要で、イベントの確認も容易。印刷すればそのまま仕様書にもなる。ただ、VBAの扱いにくさだけが難。

HSL。XMLより軽量だが、DOM風のAPIを介してアクセスするのは構造体に比べると一手間増えるなどの難点もある。扱えるデータの種類については、サクラ大戦後に改善した。

Triangles (numTriangle=2, name="Sample")
{
  Triangle (color="RED")
  {
    0.0,
    3.0,
    2.0
  },
  Triangle (color="GREEN")
  {
    2.0,
    1.0,
    4.0
  },
}

ここまでがスクリプトの話。最後に、海外版について。

メッセージが5万弱もあると、翻訳作業は数ヶ月に及ぶ。翻訳家はゲーム開発者ではなく、スクリプト内に埋め込まれている日本語をそのまま置換する、というのは難しい。そこで、海外版作成のためにExcelを使い翻訳資料作成ツールを作成した。Excelで日本語メッセージと翻訳先のメッセージを並べて書き、頻出する「………」のような言葉は他の所にもあることを示すマークを付けている。これにより、翻訳メッセージ数を圧縮している。そして、ウィンドウテキスト中におさまることを確認するために、翻訳済みメッセージの長さをpixel単位で自動計算する列も用意している。文字数でないのは、欧米向けのプロポーショナルフォントを考慮しているため。

まとめとしては、スクリプトだけで全て行わず、適材適所でツールを組み合わせていこうということ。

QA。

誤字脱字の対応方法について
手作業で対応しています
VBAは誰が担当?
新人さんをスペシャリストとして。移動マップは専属の人が
サクラ対戦はフルボイスだったと思うが、その台本は?
スクリプトから台本を作成するツールがある。ただ誤字脱字修正等で、収録がぎりぎりになったり、撮り直しになったりする事もある
海外版の仕組みは後付けという印象を受けたがどうか? また、今仕組みを作り直すならどうするか?
確かに後付け。
5MBものテキストになると、Excelで受け渡すのは限界になる。仕組みはソフトとのケースバイケースになる。
Excelを編集する担当者は何名くらいか
2名くらい。(複数人で作業の干渉はしない、という事だと思う)
スクリプターの立場は?
プランナー。プログラマはゲーム内容には関わらず、あくまでゲームを作るためのツールを提供することが仕事となっている。
プランナーもSE出身だったり同人ゲーム出身だったりで、プログラマとしてのスキルはある。

感想。ある意味ATEL以上に古さの感じられる講演でした。別の場所にあるリストで名前とのマッピングって、FORTRAN時代という印象が... 置換後のコメントが (多分) 60文字目からとか。Excel依存度が多少高いかも。仕様書と実装を乖離させないとかの工夫はいいなと思いつつ、何かプログラマが周りにあわせすぎてしまっている印象を持ちました。

HSLはいかにもYAML (wikipedia:YAML) な印象。

ちなみに前回 ブレイザードライブ の宣伝をしたものの、今回の参加者の中には残念ながら購入者がいなかったとか。販促イベントにはならないようです。

他の方のレポート

速く充実したレポートを書いている方を適当にリンク。ノートPCでレポートを書いていた方が会場にたくさんいましたし、多分もっとたくさんのサイトに書かれていると思います。
本日のツッコミ(全1件) [ツッコミを入れる]
_ TrackBack (04/21 13:12)

http://d.hatena.ne.jp/darc0113/20090421/1240283652<br>d’Arcのはてなダイアリー<br>[イベント]IGDA日本ゲームテクノロジー研究会(SIG-GT)第13回研究会「続・ゲームにおけるスクリプト言語の現状」に行ってきました<br> 4月18日に開催された、IGDA日本ゲームテクノロジー研究会(SIG-GT)第13回研究会「続・ゲームにおけるスクリプト言語の現状」に行ってきました。そのときのメモです。 今回はメモ取りはFreeMind、清書はXMindで行ないました。(それでも似非マインドマップですが……) 配布資料