こんにちは!
新人二年目のプログラマー 繁田です。
今回初めてスタッフロールに載る事が出来たタイトル、『剣闘士 グラディエータービギンズ』の開発に参加した感想や、裏話を書きたいと思います。
まずプログラムのお話です~。
僕が主に担当したのはセーブロード周りです。まだまだ経験不足の中、SCEのライブラリを使うプログラミングに苦戦し、とても大変でした。特にセーブ・ロード周りは、メモリースティックへのアクセスやゲームデータの整合性(攻撃力やスタミナの数値が正しく保存・読み込みが出来ているか)など、ゲームに対して大きく影響を与える部分でしたので、とても細かく気を使いながら作業をしないといけませんでした。
一番大変だったのが、予め決められている「これは守ってね」という作成上の約束事があるのですが、これが細かくて項目数も多かった事です。「書き込み中などにゲームを終了したら止まってはいけない」とか、「読み込み中にメモリースティックを抜いたらちゃんとメッセージが出る」などなど、どれも疎かに出来ないので、デバッグ報告やプレイしながらの対応、その都度の直し直しで長い時間をかけて出来上がりました。
次にムービーの再生に関して。ムービーの再生にはマルチスレッドなプログラミングをしなくてはならず、今までちょっと触った程度だったので、中々思うように進まなかったです。少し期間が空いてしまったのでハッキリキッチリとは覚えてないのですが、動画再生と音楽再生には別々のスレッドを用いなくてはいけませんでした。しかし、ゲーム中ではこれ以外の別のスレッドも動いていて、そのスレッドの優先順位関係や、動画スレッド、音楽スレッド間のデータのやり取り、動画ファイルのデコードのしかた、時間のズレ、動画ファイルがPSPメモリの32MBに収まるように他のリソースの解放など、色々と問題が有ったように思います。
最終的には、プログラマーでもある石川からアドバイスをもらいながら、どうにかこうにか出来上がりました。凄く「スッキリイイ感じ」に出来上がったので大満足で、作り終わった達成感がありました。ただ、ここの作業だけで一ヶ月近く進行が止まってしまいましたので、他スタッフの皆様にご迷惑をおかけしたと思います。
今回の作成ではガッツリとSTLを使えたのも凄く勉強になりました。特にvectorクラスにはセーブ・ロードの際にお世話になりました。vectorは配列クラスなのでセーブデータを作成するときにとても役に立ちます。キャラクタ―などのデータをシリアライズする際には、とにかくバイナリデータ(vectorとか)として1byte情報にし、push()関数で入れまくりました。int型などの4byteデータも、シリアライズの際に1byte情報として分解してしまいます。
これは確か石川のコードなのですが、とても参考になったので書いちゃうと…
template
void Serialize( const Type& _t, vector& _buf )
{
union {
Type data;
char byte[sizeof(Type)];
} temp;
temp.data = _t;
for( int i = 0; i < sizeof(Type); ++i )
{
_buf.push_back( temp.byte[i] );
}
}
(※無断転載はご遠慮ください)
のようになります。
ここでunionを使って複数バイトのデータ型を1byteのデータに分解出来るんです。この方法でセーブデータ用のバッファに色々なデータを格納しちゃいます。応用して文字列なども格納出来ますが、この関数ではダメですね。それにしてもやはり、templateとSTLは使いこなせるととても便利ですね。変な話ですが、これだけスッキリしてて上手く動くこの関数は少し気に入ってます(笑)。
見ても動かしてもスッキリしてるようなスマートな関数っていいですよね!もっと頑張って勉強して、こんなプログラムを当たり前に書けるようにならないとなぁと思う次第です。
プログラムは余り行っていませんが、ワールドマップ画面にも調整程度に関わりました。キャラクターのアイコンや、アリーナをぐるぐる回る駒画像の表示や動かし方などです。ここで印象的なのはサウンドの再生プログラムです。基本的な事なのですが、SEを再生する際に再生するタイミングを少し考えました。決定音とキャンセル音が同フレーム内で鳴ってしまうと問題がありますので、再生したい音を一通り判定してみて、そのフレームの最後に一つのSEだけ再生を行うようにしました。
enum {
SE_NONE = 0,
SE_OK = 1,
SE_CANCEL= 2
};
void update()
{
int play_sound = SE_NONE;
if ( push_ok() ) play_sound = SE_OK;
if ( push_cancel ) play_sound = SE_CANCEL;
if ( play_sound == SE_NON ) return;
char* se_name = "";
swtich ( play_sound )
{
case SE_OK: se_name = "se_ok"; break;
case SE_CANCEL: se_name = "se_cancel"; break;
default: return;
}
sound.play( se_name );
}
(※無断転載はご遠慮ください)
といった感じで一か所だけ再生する場所を設けてそれ以外ではどのSEを流すかの判定をしています。再生するSEを“ふるいにかける”と言った所です。もちろん参考になるほど高度なプログラムではないのですが、プログラムって「こんな感じですよ~」って雰囲気だけでも伝われば嬉しいです。
ROM焼きや製品版のリリースコンパイルも僕が担当することになりました。オーサリングというPSP上で動かせるようにする作業もありますし、デバッグ作業を行っていただいたポールトゥウィンさんへ渡す為のFTPへのアップロードなどなど、とにかく時間がかかる作業でした。酷い時にはリリース版のビルドに2時間かかったりしました(笑)。
ぶっちゃけると、リソースデータのパッケージングを娯匠側のプログラムで行っていたのですが、それが長いんです。凄く長くて、一日一本ぐらいしか提出出来ない時もありました。たしか15時か17時ぐらいにデバッグ用に作成したROM(DVDじゃなくてデータです)をポールトゥウィンさんへFTPサーバ経由で提出していたのですが、それに間に合わないことすらありました。と言うのも、前回のデバッグ報告を受けて、それを確認し修正してからROMを作成、といった流れになるので、この修正に時間を取られてしまうと、その分だけROMの作成が遅れることになり、当然提出も遅れるんです!
「これでは大変!」という状況でしたが、ロード時間短縮の目的もあってCRIウェアを導入することになり、その副次効果でフルコンパイル+パッケージングにも30分掛からなくなったのには驚きました。
他にもプログラムにミスがあり、ビルドをはじめて数十分経ってからやり直し~なんて事もあったりなかったり。そんな作業ですから確認用に作ったROMも大量でした。このタイトルで焼いたROMは大体DVD50枚入りのケース4,5本分はあったと思います(汗)。DVDドライブさん、おつかれさまでした。
さて、長い様な、読んでみると短い様な内容ですが、僕から見た開発のお話でした。出そうと思えばもっと話が出てきそうですが、今回はここまでにさせていただきます。
ここまで駄文を読んでくださってありがとうございました!
それではまたの機会に~
*記載しておりますソースコードは実際にゲーム内で使用しているものとは異なります。
新人二年目のプログラマー 繁田です。
今回初めてスタッフロールに載る事が出来たタイトル、『剣闘士 グラディエータービギンズ』の開発に参加した感想や、裏話を書きたいと思います。
まずプログラムのお話です~。
僕が主に担当したのはセーブロード周りです。まだまだ経験不足の中、SCEのライブラリを使うプログラミングに苦戦し、とても大変でした。特にセーブ・ロード周りは、メモリースティックへのアクセスやゲームデータの整合性(攻撃力やスタミナの数値が正しく保存・読み込みが出来ているか)など、ゲームに対して大きく影響を与える部分でしたので、とても細かく気を使いながら作業をしないといけませんでした。
一番大変だったのが、予め決められている「これは守ってね」という作成上の約束事があるのですが、これが細かくて項目数も多かった事です。「書き込み中などにゲームを終了したら止まってはいけない」とか、「読み込み中にメモリースティックを抜いたらちゃんとメッセージが出る」などなど、どれも疎かに出来ないので、デバッグ報告やプレイしながらの対応、その都度の直し直しで長い時間をかけて出来上がりました。
次にムービーの再生に関して。ムービーの再生にはマルチスレッドなプログラミングをしなくてはならず、今までちょっと触った程度だったので、中々思うように進まなかったです。少し期間が空いてしまったのでハッキリキッチリとは覚えてないのですが、動画再生と音楽再生には別々のスレッドを用いなくてはいけませんでした。しかし、ゲーム中ではこれ以外の別のスレッドも動いていて、そのスレッドの優先順位関係や、動画スレッド、音楽スレッド間のデータのやり取り、動画ファイルのデコードのしかた、時間のズレ、動画ファイルがPSPメモリの32MBに収まるように他のリソースの解放など、色々と問題が有ったように思います。
最終的には、プログラマーでもある石川からアドバイスをもらいながら、どうにかこうにか出来上がりました。凄く「スッキリイイ感じ」に出来上がったので大満足で、作り終わった達成感がありました。ただ、ここの作業だけで一ヶ月近く進行が止まってしまいましたので、他スタッフの皆様にご迷惑をおかけしたと思います。
今回の作成ではガッツリとSTLを使えたのも凄く勉強になりました。特にvectorクラスにはセーブ・ロードの際にお世話になりました。vectorは配列クラスなのでセーブデータを作成するときにとても役に立ちます。キャラクタ―などのデータをシリアライズする際には、とにかくバイナリデータ(vector
これは確か石川のコードなのですが、とても参考になったので書いちゃうと…
template
void Serialize( const Type& _t, vector
{
union {
Type data;
char byte[sizeof(Type)];
} temp;
temp.data = _t;
for( int i = 0; i < sizeof(Type); ++i )
{
_buf.push_back( temp.byte[i] );
}
}
(※無断転載はご遠慮ください)
のようになります。
ここでunionを使って複数バイトのデータ型を1byteのデータに分解出来るんです。この方法でセーブデータ用のバッファに色々なデータを格納しちゃいます。応用して文字列なども格納出来ますが、この関数ではダメですね。それにしてもやはり、templateとSTLは使いこなせるととても便利ですね。変な話ですが、これだけスッキリしてて上手く動くこの関数は少し気に入ってます(笑)。
見ても動かしてもスッキリしてるようなスマートな関数っていいですよね!もっと頑張って勉強して、こんなプログラムを当たり前に書けるようにならないとなぁと思う次第です。
プログラムは余り行っていませんが、ワールドマップ画面にも調整程度に関わりました。キャラクターのアイコンや、アリーナをぐるぐる回る駒画像の表示や動かし方などです。ここで印象的なのはサウンドの再生プログラムです。基本的な事なのですが、SEを再生する際に再生するタイミングを少し考えました。決定音とキャンセル音が同フレーム内で鳴ってしまうと問題がありますので、再生したい音を一通り判定してみて、そのフレームの最後に一つのSEだけ再生を行うようにしました。
enum {
SE_NONE = 0,
SE_OK = 1,
SE_CANCEL= 2
};
void update()
{
int play_sound = SE_NONE;
if ( push_ok() ) play_sound = SE_OK;
if ( push_cancel ) play_sound = SE_CANCEL;
if ( play_sound == SE_NON ) return;
char* se_name = "";
swtich ( play_sound )
{
case SE_OK: se_name = "se_ok"; break;
case SE_CANCEL: se_name = "se_cancel"; break;
default: return;
}
sound.play( se_name );
}
(※無断転載はご遠慮ください)
といった感じで一か所だけ再生する場所を設けてそれ以外ではどのSEを流すかの判定をしています。再生するSEを“ふるいにかける”と言った所です。もちろん参考になるほど高度なプログラムではないのですが、プログラムって「こんな感じですよ~」って雰囲気だけでも伝われば嬉しいです。
ROM焼きや製品版のリリースコンパイルも僕が担当することになりました。オーサリングというPSP上で動かせるようにする作業もありますし、デバッグ作業を行っていただいたポールトゥウィンさんへ渡す為のFTPへのアップロードなどなど、とにかく時間がかかる作業でした。酷い時にはリリース版のビルドに2時間かかったりしました(笑)。
ぶっちゃけると、リソースデータのパッケージングを娯匠側のプログラムで行っていたのですが、それが長いんです。凄く長くて、一日一本ぐらいしか提出出来ない時もありました。たしか15時か17時ぐらいにデバッグ用に作成したROM(DVDじゃなくてデータです)をポールトゥウィンさんへFTPサーバ経由で提出していたのですが、それに間に合わないことすらありました。と言うのも、前回のデバッグ報告を受けて、それを確認し修正してからROMを作成、といった流れになるので、この修正に時間を取られてしまうと、その分だけROMの作成が遅れることになり、当然提出も遅れるんです!
「これでは大変!」という状況でしたが、ロード時間短縮の目的もあってCRIウェアを導入することになり、その副次効果でフルコンパイル+パッケージングにも30分掛からなくなったのには驚きました。
他にもプログラムにミスがあり、ビルドをはじめて数十分経ってからやり直し~なんて事もあったりなかったり。そんな作業ですから確認用に作ったROMも大量でした。このタイトルで焼いたROMは大体DVD50枚入りのケース4,5本分はあったと思います(汗)。DVDドライブさん、おつかれさまでした。
さて、長い様な、読んでみると短い様な内容ですが、僕から見た開発のお話でした。出そうと思えばもっと話が出てきそうですが、今回はここまでにさせていただきます。
ここまで駄文を読んでくださってありがとうございました!
それではまたの機会に~
*記載しておりますソースコードは実際にゲーム内で使用しているものとは異なります。