« 2007年12月 | メイン | 2008年2月 »

2008年1月 アーカイブ

2008年1月 2日

謹賀新年&冬コミ雑感

新年あけましておめでとうございます。
冬コミおつかれさまでした。


■TWilight refrAIN 体験版について
冬コミでは結構な量を用意したのですが、お昼前に無料配布分が終わってしまいました。無料恐るべし。ゲームの中身は、分岐シナリオゲームなのに一面しかないという不思議な体験版。いろいろとごめんなさい。今回はチップキャラも精一杯頑張って描いてみました。我ながら、少しは絵が上達したと思ってますががががががが。

立ち絵については、 真白さん の絵が色っぽくて相変わらず素敵なので、ぜひみなさんも拝んでください。


■サークルについて
永久る~ぷの代表者が俺だと思っている人が案外多いですよね。今回、あらためてそう思いました。せっかくなので役割分担を書いておきます。

風深音:サークル代表。企画・音楽担当。MagicalSnow/TWINS/TWAIN監督。同人ショップとの渉外担当。
Heppoko:プログラム、グラフィック担当。CloverWing/委員ちょ(略)監督。同人サークルとの飲み会担当。

このとおり中心メンバーは二名ですが、友人たちが敵配置の手伝い・テストプレイ・CD-R 焼き・売り子などをやってくれてます。


■同人ソフト配置について
コミケ準備会の同人ソフト担当の方とお話できました。やはり配置には苦労しているらしいですね。いろんな意見が聞きたいそうなので、みなさんも配置について準備会にアンケートを書いたり、ブログとかに書いたりするといいのかもしれません。というか、カタログ下部の「配置担当者より一言」コーナーを読んでない人が少ないんじゃないかなと思います。バックナンバーは こちらから オンラインで読めるので、サークルのみなさんは読むと面白いかもしれません。

今回の冬コミ配置については、実家に帰省中につき、手元に資料がないので後日コメントを。


■今年の抱負
・夏コミで TWilight refrAIN 完成版頒布
・次々回作のプロトタイプ作成。非STGの予定。2009年の夏には体験版を配りたいです。


では、今年も宜しくお願いします。

2008年1月25日

リプレイバグを潰すための七つの方法

アクションゲームのリプレイ機能について語るのが流行らしいので、自分もちょっとだけ。

リプレイバグフリーは実現可能か (ABA の日誌)
リプレイ機能 (PlatineDispositif さんの雑記)


うちのサークルの前作の TWilight INSanity 開発中に報告された 144 個のバグのうち、11 個がリプレイに関するバグでした。それ以前の作品である CloverWing や委員ちょ(略)にもリプレイ機能があって、だいぶバグを潰したつもりでしたがそれでもまだバグが出てくるのです。大変ですね。それら過去に作ったゲームからのリプレイずれのバグ潰しのノウハウをまとめました。基本的に DirectX と C++ の話ですが、他の開発環境でも役に立つかもしれません。


■ No.1 : オブジェクトの初期化は徹底的に
コンストラクタや初期化メソッドで全てのメンバ変数を初期化するのは当然。placement new を使って、new 演算子に渡すメモリをあらかじめ ZeroMemory() などでゼロクリアしておくと、手動での初期化を忘れてもなんとかなるかもしれません。


■ No.2 : ゲームオブジェクトからグローバル変数を参照することは禁止しよう
ゲーム中のオブジェクトが参照する変数は一つの構造体・クラスにまとめておくのです。グローバル変数とかを直接読みに行ってはいけません。また、それらの変数の読み書きは必ず setter/getter 経由で行います。これにより、バグが発生したときの追跡が楽になります。要は GameInfo クラスを作り、ゲームオブジェクトが自分のメンバ変数以外を参照・変更するときは gameinfo->getHoge() やgameinfo->setHoge() のみを使うということです。


■ No.3 : 乱数なんか使わない
本当の意味での乱数なんか不要です。プレイヤーオブジェクトの座標、スコア、ゲーム開始からのフレーム数を足したり掛けたりして素数で割れば十分乱数っぽくなります。弾幕ゲーであればこれで十分安全地帯潰しになります。標準ライブラリの rand() の線形合同法から得られる乱数の精度も似たようなもんです。(ただし、カードゲームとかだと Mersenne-Twister 法などの手法を使わないとカ○ドセプトみたいな事態に陥るかもしれないですね。あくまで推測ですが)


■ No.4 : 描画処理で更新処理を行わない
Draw 処理でゲームオブジェクトの状態を変更しちゃだめです。そうじゃないとフレームスキップ時に挙動の違いが出てきます。もしそれが難しいなら、「表示スキップは Present() をスキップするだけ」というのが(裏技的な)最終手段としてはアリかもしれません。


■ No.5 : 浮動小数点演算の誤差を無くせ
通常の浮動小数点演算の丸め誤差については、誤差の蓄積をリセットするためにステージ開始時などにインラインアセンブラでFINIT 命令を呼んでおくことである程度対処できます。Direct3D の浮動小数点演算の誤差については MS 開発環境に詳しいことで有名な NyaRuRu さんが 01step さんの掲示板に書き込んだ内容が一番きれいにまとまってます。http://www.01step.net/tobitsuki/bbs/test/read.php/tobi_bbs/1116256631/18


■ No.6 : 非同期処理には気をつけて
バックグラウンドでのスクリプト読み込みなどが、意外とリプレイずれの温床になったりします。そもそも非同期処理しなければいいのですが、NOW LOADING な時間は減らしたいわけですから。このあたりは集中してチェックしましょうということで。


■ No.7 : 徹底したテストプレイを
最後の結論がこれかよ、という気がしないでもないですが。ゲームエンジン側でリプレイずれ対策をしても、ゲームインスタンスごとに微妙に処理は違うわけです。変数一つをとってしても、ゲーム起動時に初期化すればいい変数、ゲーム開始時に初期化すればいい変数、ステージごとに初期化が必要な変数、などなどあります。結局、ひたすらテストプレイを重ねるしかないです。