旧それなりブログの跡地、画像やスタイルやJSなどが壊れてることがあります。

Dungeons & Parties の開発的な話

2014年1月19日

Dungeons & Parties』というスマホゲームを作ったので、
その技術構成などの開発面の話をしてみようと思います。

ゲームの紹介は、こちらの記事を参照して下さい。

JavaScript/CoffeeScript

クライアントサイドは JavaScript/HTML5、サーバサイドは今のところなし。
サーバサイドを入れる際には、本体と連携出来たほうが良いので Node.js の何かを使います。

AltJS は CoffeeScript を書かないと死ぬ病気に掛かっているぼくに選択肢はありません。
coffee の短く柔軟な記法は、ゲームデータをコードで表現している場合、凄い良かった。
それだけのために使ってもいいくらい。

JS/HTML/CSS ライブラリや素材

使ったライブラリや素材などはクレジットにまとめています。
JSに詳しい人が見るとわかってしまうんですが、超・安定指向です。枯れた技術万歳!

他、そのために作った自前のライブラリがいくつか。
このブログのサイドバーに置いてある jQuery Plugin と npm のライブラリ群がそれです。

JSフレームワーク

Backbone.js のみです。
node で実行できることだけを条件に、あんまり考えないで選定しました。

ゲーム作りのフレームワークとしては、
他のJSフレームワークをたしなむ程度にしか触ったことがないので比較は難しいですが、
無いよりは有ったほうが遥かに良いことだけは確かでした。
この辺は、一言では言えないので、別記事にするかもです。

おそらくですが、Web ページっぽいのを想定して作り込まれている他フレームワーク、
例えば、AngularJS, Knockout.js, Ember.js などよりも余計な機能が無い分、適切だと思います。

今後、もう少し重めのを使うなら、
モデル側の強化は Backbone.js のバリアントから選択して学習コストを下げます。
そして、ビュー側の強化は、別に Cocos2d, enchant.js などのゲームエンジンを入れて連携させようと思っています。

また、CoffeeScript が、クラス継承などの基本的な部分について、統一した書き方を提供してくれています。

テスト環境

テストケースは mocha / expect.js / Sinon.JS などで書きました。
実行は基本 node 内で行い、DOM や localStorage などのブラウザが必要になる所は Testem で行いました。

テストを node だけで実行するメリットはいくつかあって、
1) 圧倒的に実行が早いこと。
2) 黒い画面内で完結するので、オッサンには安心できるということ。
3) 強制的にブラウザ依存の部分が炙り出せることです。
最後のは JS本体を Grunt 内で参照したり、後に必要なサーバサイドとの連携の際などに便利になります。

デメリットは、node 対応していないライブラリが多いことです。
X18n というライブラリはそれで、しょうがないので自分で修正して使いました。

ビューやアニメーションのテストは、基本書いていません。
描画やアニメーションは、
1) モデル側でコンテキストを生成
2) ビュー側はその情報のみで動く
これを厳守すれば、ハマったりバグったりというのは、あまりありませんでした。
バグが見つかった時は、修正ついでに書きました。

というか、最初ビューやアニメーションのテストも書いてたんですが、
修正・調整が多すぎて効率ワロスということで止めました。

テストはゲーム作りに欠かせないと思います。
もう保守性だけがオーバーフローしている Web アプリ界よりも全然大事です。
アーティスト肌のゲーム開発者さんたちも、シンプルな関数のテストだけでいいから書く手段を身に付けて、書く方がいいと思います。

テストが大事な理由は、概ねこれです。
1) ゲームだと最初動くかどうか、意図通りに動いてもそれが正しいのかがわからんので、最初の実装は雑になります。
2) 後でこれでいいと決めた時にリファクタリングが出来ないと、一定規模で破綻します。
3) リファクタリングをするためには、テストはほぼ必須だと思われます。

静的コンテンツの生成

ヘルプなどの静的コンテンツは、Assemble を使っています。

本体との連携が必要になったので、
本体を読み込んで Assemble のコンテキストデータを作る Grunt タスク、を作って行いました。

最初は流行に乗って Ruby の Middleman を使ってたんですが、
本体との連携が必要になったので止めました。
まぁ、普通に考えりゃメインがJSなんだからJS使えって感じですよね。

後、特に書いていませんが、各方面で Grunt さんにド依存しています。

アプリケーションキャッシュ

全てのファイルをアプリケーションキャッシュしています。
なので、一度読み込めばオフラインで遊べます。

一番ハマったことは、iPhone の Mobile Safari だと頻繁に読み込みに失敗することです。
正確には、サーバが弱くて、キャッシュ対象のファイルが多い、と読み込みに時間が掛かって、最終的に失敗します。
なので、最初 150 ファイルくらいあったのを 80 ファイルくらいまで減らすことになりました。

ファイルはそれぞれ軽いので通信量も大したことないし、
そもそも PC ブラウザからだと一瞬で終わるし、
理由が今でもよくわかってません。

時間がかかってもいいから、リクエストを失敗にしないで欲しいですが、どうしたらいいのやら。
Android 端末だと調べていないので、どうなんでしょうか。

なお、ファイル数を減らすための対応のひとつとして、
画像を分割しないでもチップとして取り出せる jQuery.imageIndexer というのを作って使っています。

開発期間

お恥ずかしながら、これだけの期間が掛かりました。
ザ・半年間。

仕事しながら(一部期間してないけど)とか、
オレオレ JS をある程度一般的な開発フローに合わせたりとか、
そういうのが重かったです。
2・3ヶ月で出来るんじゃね?とか思ってた。

ただ、技術面も、ゲーム中身も、整理しながらやったので、今度は使いまわせます。
特に戦闘のルーチンとか、RPG的パラメータの定義とか、割りと綺麗に実装できました。

残タスク

  • テキストを英語化
  • Android で動作確認
  • 広告の調整
  • 宣伝
  • アプリ化してリリース
  • 他に置けそうな場所を探す
  • 効果音ファイルを結合して、部分部分取り出して使える方法を募集中
  • canvas アニメーションがモバイルでも大丈夫そうなので、それで戦闘エフェクトなどを入れてみたい
  • 実は最後の方のステージが少し出来てない

犠牲にしたもの

  • 最近のJSその他技術についての勉強
  • 社会性