土曜。関係者を召喚して開発会議。某システムは、基本的にすべてバイトコードに変換して動かす方式をとっていたわけなのですが、この方式は敗北であるとの結論に至り、方針変更が決定しました(苦笑)
プログラマは、とりあえずテキストベースでの作業をしてもらうスタイルで、一気にスクリプティング→コンバート→エラーつぶし→再生→再修正、という作業ループを想定していたのでした。
と・こ・ろ・が、スクリプタの沢村さんはこういったスクリプティングは行わなかったのです。
一行にスクリプティング→再生→修正→再生→修正………→次の一行。
ぐはっ
そ、そんなことをしてたらむちゃくちゃ時間が……。「3kb こえたらたいへんなんですよー」ってのはそういうことだったのか(汗)。とりあえず、急遽データ構造とシステムに細工をつっこんで、コンバータを裏でよんで該当行までスキップ処理、という処理をくみこんで、少しは楽になったはずですが、いろいろ効率が悪いままなのです。
というわけで、やはり、ADVの演出部用に、その状態からの早送り、巻き戻し、動的更新を可能にする専用データ構造は必要ですわ……という結論に至ったのでした。まる。あと、基本的には、デフォルトの状態で、「音声」「テキスト」「表情」の全同期が可能なものを希望されている模様。ということでこれも可能にしつつ、かつ、同時にすっとばしもスムーズにできるデータ構造になるように頭を絞る。
「スクリプタに優しいシステム」を目指す以上、高度なツール化はさけられない運命だだ。がんばれ俺(苦笑)。完成した姿がどうなるかはまて次号!(はいつか不明
そしてカレー。ちなみにうちのカレーはいつも具はあんなもんです(笑)。さくらとかカトちゃんケンちゃんとかハレグゥとかいろいろ見ておひらき。
神頼みして謎そふとをふにふにと書いていただく。ありがたや(-人-)。展開された状態のテキストがあると、対談するときに検索していろいろ検証できるので超便利なのです(^^;
せんせー、 MS が Visual C++ コンパイラの無償配布をはじめてます(Yossyさん情報)。C# は SDK 同梱で既に配布してたわけですが、VC++ の中身まで配るとは。これも時代か。
Tablet PC で作業するのはちとつらくなってきたってことで、マシンのりかえー。 Tablet PC はお絵かき&ゲームマシンとして活用される見通し。お絵かき最近全然してないけど(ぉ。三上君に頼んでさくさくとマシンをくんでもらう。うお、むちゃくちゃ速くなった……。あの重い夏音のぼかし多用シーンだってさくさくさー(苦笑)
EULA みるかぎり、特に困るような制限はなさそうです。
1.1 General License Grant. Microsoft grants to you as an individual, a personal, nonexclusive license to make and use copies of the Software (i) for your internal use; (ii) for designing, developing, testing and demonstrating your software product(s); and (iii) for evaluation of the Software.
IDEは無し。あと nmake とかも入ってないっす(^^; コンパイラは VS.Net2003 Pro と同じものだそうなので、最適化ありですね。ライブラリとしては Cランタイム、C++標準ライブラリ(SLTコミ) の static link 版のみが付属。 MFC と ATL は入ってません。このあたりがほしい人はすなおに製品買いましょう。
windows.h とかも無いわけですが、これは Windows Platform SDK に入ってますので、それをインストールすればOK。
.NET は、SDK のサブセット版が入ります。ドキュメントとかも必要な人はフルの .NET Framework SDK をいれればOK。
あと Direct X をさわるには DirectX SDK ですね。
ということで、基本的な Win32/.NET C++ プログラミングの環境は一式無料で MS 純正品がそろうということにあいなりましたとさ。
昨日、ちょっと洗い物しててコップが割れて、左手のひとさし指の先をちょびっときってバンドエイドをまいてたのですが、これが違和感ありまくり。
もともと私は左利きだったのを矯正してあって、箸や鉛筆とかは右手で扱うし、コップとかも右手で持つのですが、どうもおおざっぱな処理の場合には、ほとんど左手をつかってるようです(^^;
なんやかやで一段落っぽ。システム開発は第三期突入〜ということでいろいろ思案中。
システム第二期でもいろいろと問題点が噴出してしまいました
理論上、低レベルの機能をたくさんつくっておけば、それの組み合わせなんでもできるわけですが、やはり効率がよろしくありません。目的に応じたデータ構造と専用機能をもたせるの重要。
世代 | 第一期システム | 第二期システム | 第三期システム |
---|---|---|---|
主要オブジェクト | レイヤ/トラック | 環境/キャラクタ | 「トーク」モジュール |
データ構造 | 名前、即値データ | 名前、即値データ | 構造化データ |
第一期システムでは「レイヤ」とか「サウンドトラック」といった単位での制御で、これでひととおりのことはたしかにできるのですが、直感的に優れず、スクリプト修正が非常に困難でした。たとえば、あるシーンにおいて「左レイヤ」にバインドしていたあるキャラクタの立ち絵を全部右側に変更したくなった場合、その間に指定されていて指定をすべて修正する必要がありました。世の多くのこの種のエンジンは、これと同じ愚をおかしているかと思います。 NScripterしかり、吉里吉里しかり。
第二期システムでは「キャラクタ」と「環境」というステートフルなオブジェクトが導入されたことにより、こういった問題点は一気に改善されました。ある一連のシーンで「左」に立っていたキャラを「右」に変更したくなった場合、シーン先頭での「左」という指定を「右」にするだけの変更で完了するようになりました。
キャラクタの配置状態や、周囲の状態などは「環境」オブジェクトの管轄下にあるため、これらに対する一斉制御なども容易になりました。
さて、オブジェクトの粒度としては、これで十分問題なかったのですが、スクリプティングが楽になる → スクリプタが演出にむちゃくちゃ凝りはじめる、という想定外の事態(笑)が発生し、結果として「データ構造の粒度が悪い」という問題が吹き出してきました。
一例を。現行の「キャラクタオブジェクト」は「会話」機能と「ボイス再生」機能を個別で持っています。たとえば、
鈴菜:[怒2]いわゆるひとつの匠のワザよ!!!というスクリプトは、内部的には、
鈴菜.voice(); # ボイス再生。指定無しなので自動的に「次のボイス」がなる 鈴菜.set(怒2); 鈴菜.change(); 鈴菜.talk("いわゆるひとつの匠のワザよ!!!"); 鈴菜.waitVoice(); # ボイス完了まち 鈴菜.waitPage(); # 改ページまちといったように展開されて想定通り妥当に動いてたわけです。
ところが、こーんなスクリプト記述ががしがしでてきました……
鈴菜:詩子も来るでしょ? [環境 待ち 1000][がっかり]と言うか来い。付き合え
きゃー。「環境」の持つ「待ち」命令はクリックでとばされるとはいえ、タイミングがずれてきたときにいろいろ気持悪いことになります。あと、複数いれてしまうと、何度もクリックしないとその会話文をとばすことができなくなります。
adhoc な対案として、キャラクタの「声待ち」命令の拡張を行いました。キャラクタオブジェクトが再生している音声が、指定した時刻に達するまで待ちます。未指定時には従来通り、声が終了するまでまちます。
鈴菜:詩子も来るでしょ? [声待ち 3000][がっかり]と言うか来い。付き合え
これで文字表示速度設定にかかわりなく、ボイスとテキスト表示タイミングを合致させることができます。あと、「声待ち」はキャラクタの機能なので、キャラクタがステート管理できるため、再生途中でクリックがあったときに、複数入っている「声待ち」を全部キャンセルさせる、といった挙動が可能です。
では、これで問題なくなったかというと……
鈴菜.voice(); 鈴菜.talk("詩子も来るでしょ?"); 鈴菜.waitVoice(3000) 鈴菜.set(がっかり); 鈴菜.change(); 鈴菜.talk("と言うか来い。付き合え"); 鈴菜.waitVoice() 鈴菜.waitPage()
……ぶっちゃけ美しくないです。実のところ、この問題は、別に「待ち」だけでなく、表情変更などにともなっておこるもので、以前からあったのですが、それが極端に目立つようになってしまいました(^^; ボイスはタイミング指定をキャラクタに制御させるようにしたことで「スキップ」を適切に制御できるので良いのですが、ほかのオブジェクトに対する操作や、画面全体に対する演出を会話中にがしがしつっこむと、いろいろとタイミングに対する違和感が生じる原因になってきます。
そのまま普通にながめてるだけならば、それはそれでだいじょうぶなのですが、クリックでさくさくすすめたい、という要求も別にあるわけで、そういった操作をしても極力違和感が無いように処理したいわけです。
さらに、そもそも同期演出を意図するならば、こういった音節単位でのタイミング制御をおこなうのなら、それに応じて文字の表示速度自体が変わってほしい、という考えが出てくることは容易に想像されます。あらゆる演出が同期的に制御可能で、かつ、非同期的にも駆動可能で、かつ、違和感がないものにできるのが理想です。
しかし、それを現行のシステムで対応することは不可能です。
結局のところ、「ボイス」「テキスト」「タイミング」「演出」の4要素を統合的に扱うデータ構造が必要なわけです。こういったデータ構造を採用した場合、スクリプトがコンバートされた結果は次のようになります。
テキスト情報DB: 0001 文節1;詩子も来るでしょ? 文節2:と言うか来い。付き合え 演出情報DB: 0001がっかり トーク情報DB: 0001テキスト:0001, タイミング:文節2/3000, 演出:文節2/0001 スクリプト本体 ---------------------- 鈴菜.talk(0001); # トーク情報を指定 鈴菜.waitPage(); ----------------------
現在考えているデータ構造は次の通り。
これでだいたいいけるかなーと思ってるのですがどんなもんでしょね(^^; テキストを別に独立して分離することにより、誤字脱字修正をスクリプトと独立して行えるようになるのと、既読管理がより厳密に行えるようになる、というメリットもでてきます。
こういった構造化されたデータについては、ほかのところでもいろいろ必要な面がふえていたります。現システムは、オブジェクトが高度化したせいで、それの初期化処理のために大量のメソッド呼び出しを必要としています。こういった情報も、きちんと分離した上で「初期化」メソッド一発で処理できるべきです。
問題点その2に続く。