2016年6月27日月曜日

PxtoneJS

GitHubで何気なく「pxtone」で検索してみたら、PxtoneJSなるものを見つけた。

WebAudioで鳴らせるものなのかー
まだ、動かして確認はしていませんが。
VGSのmmlもWebで再生できないかと思っていたりします。

Flashとか使うなどの手段を採れれば技術的には出来なくもないというより、ニコニコ大百科のピコカキコで使われているFIMML等の先駆者が居るので、作ろうと思えば100%実現可能ですが、Flashは今後消えゆくのでナシです。

しかし、WebAudioはまだまだ発展途上という感が否めない。というか、以前Invader Block 5みたいなものを作ってデバックしてみたら、Chrome以外のブラウザではまともに動かないという有様でした。

WebAssemblyが動くサンドボックス環境にOSSやALSAぐらいシンプルなローレベル音声システムが実装されれば良いなと思っていたりするのですが、どうなるか分からないので、WebAudio版を作り進めておくのも悪くはないかも。

とは思いつつ、当面手を付けれそうにないですが

2016年6月5日日曜日

東方VGSの更新が止まっていますが、私は元気です

いや、色々とありまして...

まず、一番大きなところで、VGS mk-III の開発を本格的に始めたから時間がありません。

mk-IIIは、大まかにはこんな感じにするつもりです。

音源システム周りは mk-II と全く同じ。
vgs-bgm-decoder, vgs-mml-compiler, vgs-spu をそのまま使います。
若干の改良点としては、効果音関連で今まで音源ソースは .wav ファイル限定でしたが、ogg/vorbis もサポートしたり、周波数とかを自動変換できるようにしたりする予定(ROMDATA.BINの内部構造は変更しないつもりです)。
そこまでやるなら mp3 とか aac も...と言いたくなるところですが、それらは大人の事情(特許関連)により使えません。
グラフィックス面は、ソースとしてpngも使えるようにしようと考えていますが、それ以外にも同時発色数を8bitカラー(256色)から16bitカラー(65536色)にするかも。αブレンド(半透明)を使えるようにしたいかもと思っているので。
あとは、(これはまだ構想段階ですが)VGSのゲームプレイ内容を動画に録画して、ニコニコ動画やYouTubeなどに簡単にプレイ動画をアップできるようにしてみようかとか、考えたり、考えていなかったり。

色々と変わる予定ですが、一番大きな変更点は CPUの自前化 です。

vgs-cpuという独自の仮想CPUを搭載します。
https://github.com/suzukiplan/vgs-cpu

これは完全に暴挙ですね。
CPU自体は32bitですが、フルアセンブリ言語でも 6502 並にコーディングし易いCPUとして設計中です。オールマシン語でゲームプログラムを作るのは、8bit時代は結構普通だった(というよりBASICなどの入門言語を除けばそれが標準的だった)のですが、16bitで少し難しくなり、32bitで完全に無理になりました。ただ、32bit CPUだったとしてもオールマシン語で作る前提でCPUを再設計すれば、結構いい感じになるんじゃないかと。

mk-IIまでのVGSは、cocos2dやUnityなどと同じ 単なるSDK ですが、私はSDKを作ろうという気は初めからサラサラ無く、作ろうとしたのはVGSという私の脳内に実機があるコンソールゲーム機のエミュレータです。なので、これでようやくVGSが青写真通りの形になる訳です。

完全に誰得だということは確定的に明らかですが、それはさておき。

しかし、この作業の合間の時間にでも東方VGSの更新はできなくもないのですが、今はSteamのNuclear Throneというゲームをプレイするのに忙しかったりとか...(このゲームはやばい)

「テスト書け」が馬の耳に念仏になる原因

vgs-cpuをgithub上でモリモリ設計中。
https://github.com/suzukiplan/vgs-cpu

この記事執筆時点のcommit
https://github.com/suzukiplan/vgs-cpu/commit/29f8cbe684dd1489fcb3a8b3cfffbbc52a6757cd

CPUのコードを書くのって完全なる単純作業です。
こういう単純作業だと割りとバグを作りこみ易いです。
なので、こういう場合はテストを書くのが重要。

という訳で、このリポジトリを git clone して make を叩けばテストを流すようにしました。(※Mac or Linux限定で、Windowsには対応していませんが...)

プログラムを書いたことがあれば、「テスト書け」なんて耳にタコができるほど言われることで、馬の耳に念仏状態かもしれませんが。

テストを書く目的は、
1. バグの早期摘出
2. エンハンス時のデグレード防止
の2つしかありません。

1の理由は、後工程で見つけると原因を特定するのに掛かる時間(摘出コスト)が指数的に増加するためです。これは古典的なウォータフォールだろうが、アジャイルだろうが同じことです。

vgs-cpuのレジスタAに対するスタック操作(push/pop)、メモリ移動(load/store)、インクリメント、デクリメント、NOT演算のコード規模はだいたい100ステップぐらいですが、テストを書いてみて摘出できたこの部分のバグは以下の3件です。

bugfix: notの演算結果が不正
https://github.com/suzukiplan/vgs-cpu/commit/9b4f49235a60d63202a0f753d1233768284f4810

bugfix: inc, dec, not で プログラムカウンタ の インクリメント漏れ
https://github.com/suzukiplan/vgs-cpu/commit/f31ddfbf9f355a590e78448c858f905e1c81e47e

bugfix: VGSCPU_OP_POP_A4 (2byte -> 4byte)
https://github.com/suzukiplan/vgs-cpu/commit/53ca01c247086f886758a4bb7dfc3a4931849558

これらを早期に潰すことで、最小のコストで品質を担保できます。

で、スタック操作(push/pop)、メモリ移動(load/store)の命令群には、この後メモリ検査のエンハンスが入る予定ですが、これらのテストを全て自動化しておくことで、エンハンスを入れた時にデグレードが発生しないことを保障する訳です。

ちなみに、「単純作業だと割りとバグを作りこみ易い」と上述しましたが、だいたいの人が1ks(千行)のプログラムを書いた時に作り込むバグの件数というのは、統計的に10〜15件なので、100行で3件(ksあたり30件)という具合に実際多い。

ただし、ある程度作り慣れてくると、バグの作り込みパターン(バグ知見)が脳内に蓄積されることで(主に同件の)バグを作り込む確率が減ります。

プログラムを書く時、面倒臭いから 全部作ってから後でテストすれば良い という考え方の人が結構居ると思います。少し話は飛びますが、プロジェクトの特性として「新規性」というものがありますが、これは要するに「無いものを新たに作る」という事です。既にあるものなら、わざわざ新規に作らなくても既にあるものを使えば良いですからね。で、新規性という特性を持つ以上、バグ知見が十分に足りていない可能性がものすごく高いという事は自明です。(成熟度が低い組織だったり新規性が高い分野のものづくりをすると、似たようなものを作るケースも多々ありますが)

だから、今回のvgs-cpuの開発では、スタック操作(push/pop)、メモリ移動(load/store)、インクリメント、デクリメント、NOT演算のだいたい100ステップぐらいのコードが出来たところで、一旦開発を止めて徹底的にテストすることにしました。バグ知見が十分に溜まったところであれば、テストを省略しても問題無いと思います。バグ知見が十分に溜まったところでもガリガリテストを書くのは過剰品質(テストを作るコストが品質に寄与しない)という感じになります。

「テスト書け」が馬の耳に念仏になる原因はソコにあります。

2016年5月22日日曜日

vgs-cpu

また、変なものを作り始めました。
https://github.com/suzukiplan/vgs-cpu

VGS専用の仮想CPUです。
この記事執筆時点ではまだ作りかけです。
完成するかどうかも分かりません。
ただし、VGSを設計した(2012年)当初から、最終的にCPUまで自前化する青写真を描いていましたが。

恐らく、普通は誰もこんなことを考えないだろうと思います。

CPU依存しないプログラムを書きたければ、Java等のVM持ちの処理系を選べば良いですし、もっとローレイヤーにしたければLLVMを使えば良いので。
Javaはネタですが、しかし、現状最も現実的だと思われるLLVMだとガチ過ぎる(というよりデカ過ぎる)。
実用レベルで耐えうる仮想CPUを作ろうとすると膨れ上がるのは仕方が無いことですが、私としてはVGSのゲームだけ動いてくれれば良い訳です。しかし、そうなると既成品では(LLVMに限らず)どの仮想アーキテクチャもしっくり来ない(8bit, 16bit, 32bitの色々なエミュレータを試食してみましたが断念)。

CPUではなくJSで...と一瞬揺れそうになった時期もありますが。しかし、JSは便利だけどJSだと似たようなものが既にあるんじゃないかと思うので、面白く無いなと。

完全オリジナルなCPUにすることの最大のデメリットはコンパイラの調達です。
コンパイラも全部自前で作る必要があります。
それは流石に面倒くさい。
だから、コンパイラについては一旦無くてもいいやと。

コンパイラが無ければアセンブラで作れば良いじゃない

です。

という訳で、32bit CPUなのに6502並にフルアセでゲームが作り易いCPUみたいなものを作ろうかなと。

2016年5月8日日曜日

ストックを増やす作業

ゲーム開発を再開したのは良いけど、曲のストックが切れているな...

あまり曲作りに時間を掛けたくないから、過去作品をアレンジして使い回そうかと思いつつも、とりあえず新しくストックを貯めとこうと思い、2日で3曲ほど作曲。

なお、まだVGS化はしてなくて、ピスコラで作ったラフ状態です。MML化するのは面倒くさいので、ピスコラで作ったストックの中からイイネと思った曲をチョイスしてMML化します。

まず1曲目(ボス想定)
http://twitsound.jp/musics/tsv8nu1nh

途中まではボスっぽいのですが、ラスト8小節のエスニックっぽい部分は詰まりました。
詰まるとだいたいこんな感じになります。
ボスっぽい曲って作るのが難しい。
ボスにキャラ付けがあれば割りと作り易いのですが、例によって私が作るゲームは基本的にキャラクターやストーリーの類は一切無いので、だから難しいのかもしれません。

2曲目(3面想定 / 明るめのステージ曲)
http://twitsound.jp/musics/tsE9yCZ4q

これも前半は良い感じですが、後半16小節のエスニックっぽい部分はやはり詰まっています。
詰まると手癖で作る→エスニック風(?)になる
というのが定石になりつつある。

3曲目(ステージ曲だと思う / いわゆるズンダラ節)
http://twitsound.jp/musics/ts7SVFMKq

これは完全に手癖だけでほぼ機械的に作曲。
中盤のサブメロディが主旋律よりも高くなっている部分のバランスが若干悪いです。

1面のボス曲だけ出来ればLite版は作れるので、ボスっぽい曲のストックを増やすのを優先したいところですが、何故かステージ曲の方を多く作ってしまってますね。困ったものです。

2016年5月5日木曜日

マイブーム

ここ暫く(4月以降)、東方BGM on VGSの曲追加をしていません。楽しみにお待ち頂いている方が少なからず居るだろうと思うと心苦しいところではありますが、今は私の興味の対象がズレているので仕方がありません。

先日、かなり以前にYouTubeで公開した SHOT05 のデモムービーに海外の方から「新作はよ」というコメントが付いたことがキッカケで少し我に返りました。

で、最初は何故か「よっしゃHTML5で60fpsでヌルヌル動くSTG作ってみっか」というノリで作り始めたのですが、次の公開先はSteamにしたかったので、「よっしゃcocos2dxで作ってみっか」という流れになったものの、cocos2dxは(スマホ版は知りませんが)PC版がかなり微妙だったので、「よっしゃVGSをしっかりPC対応させてPC用STG作ってみっか」という流れになり下図のゲームを今作っているという感じです。
見事なまでの右往左往。
何故、最初っからVGSでやろうとしなかったし...

あぁ、でもJSに寄り道したのはそこそこ実りがありました。
Duktapeなどの小さめのJSエンジンを積んで、VGS+JSでPCネイティブのゲームを作れるようにするのも悪くないかもしれないとか一瞬思ったりしました。

2016年5月4日水曜日

Tiled Map Editor で生成したJSONをC言語で読めるようにする

前回記事で紹介した Tiled Map Editor は、JavaScriptであれば割りと何も考えずに使えますが、これをC言語で扱える構造体形式に変換するツールを作ってみました。

Tiled Map Editor が吐き出せるデータ形式はデフォルトはXMLですが、今時XMLなんか使っている人なんて居るんですかね?JSON形式で吐き出せるので、JSON形式で吐き出したデータを構造体に変換します。

なお、JSONならダイレクトに読んで使っても良いかもしれませんが、C言語でJSONを読むのは少々面倒くさいので、JSONをバイナリ構造体に変換するCLIを(Cで書くのは面倒なのでC++11で)作ってみました。

JSONパーサーにはDropbox社が提供しているjson11を使用。
C++界隈のJSONパーサーというと、国内ではpicojsonとかが推されているようですが、私が使ってみた限り、モダンC++で書くにはかなり野暮ったい気がするし、数値型がdouble限定なのもイケてないという印象でした。「数値なら何でも実数でいいじゃない」という考え方は、実用上問題無ければそれで良いと思いますがFPUの仕様上、実用上の問題(性能云々は今回気にしていないので性能上の問題ではなく正確性の方の問題ですね)があるので、整数で表現すべき箇所は明確に整数で定義しないとダメだということです。なお、性能云々を今回気にしていないのは、性能にシビアな部分ではJSONパース済みのバイナリデータしか使わないからです。
上記CLIのソースをコンパイルする手順:

$ git submodule add https://github.com/dropbox/json11.git
$ g++ -std=c++11 json11/json11.cpp mkstg.cpp -o mkstg

これで、あとは保存したバイナリをVGSのDSLOTに突っ込んでマップを表示するプログラムを書くだけで、C言語でTiled Map Editorで作ったマップが表示できるようになります。簡単ですね。
C言語でマップを表示してみた図(Macで撮影)
マップを表示させただけでかなりゲームっぽくなるのでテンションが上がります。