はじめに
『プログラムを物語を語るように記述する』のに欠かせないのが、ステート関数です。
➡※参照「ステート処理はナァラティブに」
ここニ年程、【ステート関数を自動生成出来る】&【プログラム言語を選ばない】&【ステートマシンGUI】のビジュアルプログラミングツールの開発に没頭してきました。
本投稿はそのツール開発の経緯と基本技術についての話です。
題目は以下の通りです。
- ツール開発の発端・業界特有の宿命的な問題
- 短期間の仕様変更を可能にする開発基盤への2つのアプローチ
- 未踏のビジュアルプログラミング
- 汎用のビジュアルプログラミングツール開発
- まとめ
- 最後に
- ツールの入手方法
なにより現物を…という方は次のURLを参照下さい。
ツール開発の発端・業界特有の宿命的な問題
###『面白くなければボツ』
私の属するゲーム業界では、どんなに努力して作ったものでも、きちんと作り上げてきたものであっても、それが面白くなければ仕様を変更し、場合によっては【機能単位】または【場面単位】で削除します。場合によってはゲーム自体がお蔵入りすることもあります。
ゲーム作りはそれほどに厳しいのです。
苦労して思い入れのあるものが【正しく動作するか】、ではなく【面白いか】という曖昧な基準で削除される…
悲しい話ですが、私たちゲーム開発者はそれを当然として受け入れる必要があります。
プロの世界にいる以上、覚悟しなくてはならない事です。
開発の最後に始まる本当のゲーム作り
ゲームが面白いか?…ゲーム開発の終盤に差し掛からないと判らないのが現実です。
ゲームの良し悪しは、絵ができ、動きが入り、サウンドが入り、プレイが出来て、初めてわかるのです。
人気のある作品のリメイク作品であれば、問題はそれ程多くはありません。
しかし大抵の場合、『同種のゲームとの違いはあるのか』、『オリジナル性はあるのか』、そして当然ながら『面白いのか?』、他にも『実行速度に問題ないか』…等の様々な問題が発生します。
繰り返しますが、どんなに気を付けていても、これらが分かるのは終盤なのです。
開発者である我々が天才であれば、企画段階から素晴らしいと分かっているものが作れるのかもしれません。少なくとも終盤になるまで面白いかどうかも分からない、というようなことは無いでしょう。しかし現実は厳しいものです。そんな夢物語のようなことは起こりえません。
そして、ゲームの終盤こそがゲーム作りの本当の勝負となります。
結果として半年または数年かけて実装してきた仕様がバッサリ切られてしまう。
最初で説明した事が起こるのが終盤なのです。
仕様変更を迫られても、リリースまでにはいくばくも時間がありません。
その短い時間に仕様を変更して問題を解決しなくてはなりません。
変更箇所によっては、今までの開発工程を再度繰り返す…それもさらに短い時間で行うという場合もあります。
この終盤で重要なのが、短期間で仕様変更を可能にする開発基盤なのです。
短期間の仕様変更を可能にする開発基盤への2つのアプローチ
アプローチ1.イテレーションを最適化する(時間短縮と回数UP)
よいゲーム開発を示す指標としてイテレーションという言葉があります。
イテレーションは、変更を加えてビルドが出来上がるまでを指し、その時間が短いほど良いといわれています。
通常のゲームプロジェクトであれば、ビルドマシンが用意され、各自のPCよりリクエストを送り、実機用のビルドが出来上がります…この一連がイテレーションです。
例えば、デザイナが絵を変えたとして、それを実機上で確認できるまでに何分かかるか?
デザイナは、自PCのエミュレータで確認を行ったとしても、実機上では表示位置・圧縮方法・ファイルサイズ・透明割り当て、先行処理の影響等々でデザイナの想定した通りになるとは限りません。
それをデザイナ自身で短時間に実機上で確認できることは大変有意義なことです。
ここでイテレーション回数が大きくかかわります。
【1日に1回】と【1日に10回】とでは大きく結果の精度が異なります。
アプリケーションのベース機能、およびエンジンが用意する機能をデザイナ自身が積極的に使うことはゲームの面白さに直接関係することが多く、積極的に使うためにもイテレーション時間短縮と回数UPは必須です。
デザイナの例をあげましたが、メンバ全員が各々のパートで、実機で何度も繰り返せる環境を持てば、アプリやエンジンの機能を使いこなすことができ、さらに面白い作品を作る可能性が高まるのです。
その指標がイテレーションです。
このイテレーションの【時間短縮】と【回数UP】することが、開発終盤の仕様変更に強くなるカギとなります。
プロジェクト管理者がこれを理解しているかどうかで、プロジェクトの成否が決まるといっても過言ではありません。
アプローチ2.ツールを視覚化する
ビルド工程のオートメーション化は当たり前に実施される時代になりました。
リポジトリ上の様々なデータを加工してビルドに組みこむコマンドラインツールは、ビルド工程で大きく貢献しています。
その上で、変更に強い開発基盤のもう一つのカギがツールの視覚化にあります。
ビジュアル化されたツールの作成を、「難しい」と感じている方が以外と多くて驚かされるのですが、近年ではそれは意外なほど簡単に作成できます。
多くのゲーム開発者が Visual Studioの C#を推奨しています。
一つ精通したプログラム環境を知っていれば、ラーニングコストも少なく、数日でビギナーを卒業でき、一か月もあればマスターできます。
全く素晴らしいIDEです。
また、Unityという近年最高のエンジンがあります。Unity Editor用のGUI環境が揃えられており、十分なビジュアルツールとして利用することが可能です。ただ、バージョン更新による機能変更が多い事とライセンス料が発生することに注意する必要があります。
###『なぜツールの視覚化が重要か?』
理由にゲーム業界特有の事情があります。
ゲーム開発のプロジェクトでは、多才で全く異なるスキルを持ったメンバが集まります。
例えば、アーティスト指向が強い方々(グラフィックデザイナ・モデルデザイナ・モーションデザイナ・サウンドデザイナ)やゲーム自体への興味が強い方々(ゲームプランナ・テスタ)等です。
プロジェクト内でプログラマが占める割合が僅か2割…などと言うこともあります。
プログラムが読めないメンバにとって、直感的に操作できるビジュアル化されたツールはゲームへ直接関与できる貴重なインターフェースになるのです。
開発終盤の仕様変更時にそのインターフェース=ツールを用意しておくことがどれほど重要かわかって頂けるかと思います。もし用意してないのであれば、プログラマのデスマーチが続く最悪のプロジェクトになることは間違いありません。
これがビジネス系のIT業界であれば、メンバ全員がソースコードが読め、かつ同種の知識基盤を持つ…というのが視覚化を重要視しない理由かと思います。
未踏のビジュアルプログラミング
ゲーム進行、メニュー遷移、カットシーン、キャラ制御、アルゴリズム等々、開発メンバからのツール視覚化の要求は山積みです。
プログラマは、終盤の仕様変更に耐えられるようにゲーム開発初期からツール作成に努めていきます。
特に実現が難しいのが、処理の流れを視覚化する部分のツール、つまりビジュアルプログラミングツールです。
エンジンまたはミドルウェアで提供される場合もありますが、多くは専用スクリプトによる(テキスト)開発が関の山で、さらにビジュアル化された処理の流れ専用ツールとなるとかなりのビッグバジェットタイトルでなければ手の届くものではないのが現状です。
(まさにCEDECで紹介される大手のツールです)
現実的に、処理の流れに関する部分のほとんどの解決策はプログラマによるプログラミングなのです。
ですが、この部分こそが終盤の仕様変更要求が高い部分であり、実装難易度の高い部分です。
ゲーム終盤での仕様変更を強くする未踏のカギ、それが処理の流れを視覚化を可能にするビジュアルプログラミングでした。
ビッグバジェットを掛けることなく、ビジュアルプログラミングができる環境があれば…
これが私の長年の課題でした。
汎用のビジュアルプログラミングツール開発
2007年、ビジュアルプログラミングを断る
2007年、とあるビッグバジェットのゲーム開発に参加した時、次のように尋ねられました。
『ゲーム進行用のビジュアルプログラミングツールを半年で作ってほしい』
私の返事は「NO」。即答でした。
ツール作成の基盤がなく、時間が不十分であること、ツールの保守人員を考えると途中で断念することが簡単に予想できたからです。
そして代わりに提示したのが独自スクリプトの開発でした。作業者のスキルに合わせる形でエクセルの補完機能でコマンドを選択する工夫を加え、1ヵ月でスクリプトのランタイムとデバッグ環境を作成し、残りをゲーム仕様の基本実装に当てる。最後に保守をプログラマの誰でも行えるようにして実際の人員を割かない…このように解決したのでした。
###『あの時(2007年)は強くNOと言えたが、今(2017年)はどうだろう』
すでにあれから10年も経ち、シンギュラリティの予兆が騒がれる時代になっています。
そろそろビジュアルプログラミングツールができるのでは…
過去の心残りとともに何とかしたいという気持ちが動きました。
GUIへのリーチは短い
まず取り掛かったのはグラフィック基盤の調査でした。
とにかく手を動かしてみようと作成したのが、Unityの矢印コンポーネントでした。
[※参照:RADツールを作りたいから矢印から作ったよ]
(https://qiita.com/tohmas/items/20a3ee3517740f056999)
正直のところ矢印だけで結構苦労しました。
『これでは目的の達成は遠いな』
本部分を自力で解決するのは諦めて、作図関連のツールをGithubで調べてみることとしました。
その結果、C#自体に矢印描画および線形補間の機能があることを知りました。
本当に良い時代になりました。
そうして実現可能な確信を得ることが出来たのでした。
ステートマシンを設計するツールを作ろう
『ゲームはステートのカタマリ』
以前の記事で私はそう説明しました。参考:ステート処理はナァラティブに
ステートを制すればゲーム開発は楽なのだ。
『ステートマシンを設計し、ソースへコンバートするツール』
これが目標になりました。
ステート関数を如何に変換するか?
GUI部分は多数のサンプルのおかげでメドが立ち、残る課題が…
『ステート関数を如何に組み込むか?』
でした。
これまでの経験から生み出した、【評価付きテンプレート】 という手法を使いました。
この【評価付きテンプレート】を説明する前に、まずは、ステート関数のテンプレート化を試みてみましょう。
ステート関数のテンプレート
以前の記事でステート関数を以下のように表現しました。 (C#の場合)
void S_HOGE(bool bFirst) // ステートHOGEの関数
{
if (bFirst)
{
//初期処理
}
else
{
//更新処理
if (終了?)
{
//終了処理
Goto(次のステート);
}
}
}
ビジュアル化用のテンプレートとして若干変更を加え、以下のように表すこととしました。
void [[state]](bool bFirst) //ステート名
{
if (bFirst)
{
[[init]] //初期化コード
}
[[update]] //更新コード
if ([[wait]]) return; //待機条件
[[postwait]] //後処理
[[branch]] //分岐処理
}
二重鍵括弧に囲まれた部分にパラメータが挿入されます。その該当パラメータにソースコードを記入すればよいわけです。
たとえば、各パラメータに以下のように値が指定されているとします。
パラメータ名 | ソース | コメント |
---|---|---|
state | S_HOGE | ステート関数名 S_HOGE |
init | play_anim("HOGE"); | アニメーション HOGEの再生開始 |
update | update_anim(); | アニメーション更新 |
wait | is_anim_done()==false | アニメーション終了検知 |
postwait | finish_anim(); | アニメーション完了処理 |
branch | goto(S_NEXT); | S_NEXTへ遷移 |
テンプレートに合わせると以下のようになります。
void S_HOGE(bool bFirst)
{
if (bFirsT)
{
play_anim("HOGE");
}
update_anim();
if (is_anim_done()==false) return;
finish_anim();
goto(S_NEXT);
}
評価付きテンプレート
利用者の都合がありますからパラメータに、値が何もない場合があります。
例えば waitに値が無かったら・・
if () return;
これは明らかに文法エラーとなります。
これを回避するのが評価付きテンプレートです。
評価付きテンプレートのフォーマットは以下の通りです。
<<<?パラメータ名
コード部
>>>
パラメータの値が存在する場合にコード部が有効化されます。
先のテンプレートを次のように変更します。
void [[state]](bool bFirst) //ステート名
{
if (bFirst)
{
[[init]] //初期化コード
}
[[update]] //更新コード
<<<?wait <--- 追加
if ([[wait]]) return; //待機条件
>>> <--- 追加
[[postwait]] //後処理
[[branch]] //分岐処理
}
追加部分により、waitの値があるかを評価して、ある場合のみテンプレートを展開する指示が可能になるのです。
次のような指定がある場合
パラメータ名 | ソース | コメント |
---|---|---|
state | S_HOGE | ステート関数名 S_HOGE |
init | (なし) | |
update | print("Hello world!"); | 表示 |
wait | (なし) | |
postwait | (なし) | |
branch | goto(S_NEXT); | S_NEXTへ遷移 |
以下のように展開されます。
void S_HOGE(bool bFirst)
{
if (bFirst)
{
}
print("Hello world!");
goto(S_NEXT);
}
文法エラーは発生しません。
これにより、ステートのパラメータ部分に必要最小限のコードを埋め込むだけで、ステートマシンのステートをステート関数へ変換できるようになったのです。
この『評価付きテンプレート』は、多種のパターンを一つのテンプレートおよび一つのデータテーブルで管理ができ、そして正確にコードを出力できる素晴らしい方法です。
複数プログラム言語対応で汎用化
仕事の道具としてビジュアルプログラミングを使うには、様々な言語が利用可能ではなくてはなりません。
ステート関数の移植は簡単です。
それぞれの言語別のステートマシンマネージャと、予約語に対する変換方法を用意すれば、どの言語にも対応が可能です。
現在(2019/4/28)、以下の15プログラム言語に対応しています。
- Angular typescript
- Bash
- C
- C++
- C#
- Delphi
- Excel VBA
- Java
- Javascript
- PHP
- Python
- Swift
- Tyranoscript
- Visual Basic
- Windows Batch
まとめ
ゲーム業界の宿命的問題は、ゲーム開発の終盤にならないと面白さが分からず終盤から開始される仕様変更こそがゲーム開発の本番となる事です。
問題解決へのアプローチは、イテレーションの最適化とツールの可視化です。
そして、ツールの可視化のなかでも難易度が高いのが "処理フロー"の部分です。
それを解決すべく取り組んだのが汎用のビジュアルプログラミングツール開発です。
汎用のビジュアルプログラミングツールは、発達したGUI基盤・ステート関数・評価付きテンプレートにより成立しています。
そして、現在15言語のビジュアルプログラミング化に成功しています。
可視化による恩恵
可視化による恩恵は、計り知れないものがあります。
実際に動作している処理を図として俯瞰できること、それに直接修正を加えられること、この恩恵は計り知れません。
ステート管理クラスという汎用手法を全体で採用していることで、デバッグも簡単に進めることができます。
また、リテラル記述が増えるためデバッグ効率が上がるという嬉しい効果もあります。
実績
本職のゲーム開発においても、通常のプログラム作業の代用に加えて、RPG作成用、キャラクタ制御用で使われており、既にリリースしたタイトルもあります。
最後に
3Dグラフィッカーが扱うノードツールをカッコいいなーと思っていました。
テキストエディタもどんどん進化していますが、あのカッコよさには敵いません。
ぼくらプログラマも、カッコよくやりたい。
21世紀らしいプログラム作成をしたい
…こんな気持ちも根底にありました。
プログラマのみなさん、カッコよく仕事しましょう。
そして何より、ゲーム開発の皆さんの面白さ追求の一助になれば幸いです。
ツールの入手方法
ツールは以下より入手可能です。