Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。

Passengerに挑戦。あと登録ユーザー数の概算

RailsのサーバーはずっとWEBrickひとすじだったのだけど、 今開発中のゲームはキャラクターの位置情報がRailsのアクション(というかShootingStarへのアクション)として送られてくるため かなりのサーバー負荷になる予定……。 というわけでPassengerを試してみた。

うん、ずいぶん早くなる気がする。 これなら秒間30回くらい位置情報が送られてきても大丈夫そうだ (VM上のサーバーで試してるからちゃんとしたマシンを用意すればもっといけるかも)。

秒間30回ということは……。 1分間で1800をリクエスト処理できるわけで、 1プレイヤーが1分間に10リクエスト送ってくるとすると、180人が同時接続できる計算だ。

180人が同時接続するとしたらアクティブユーザ数は1000人くらいだろうから(ゲームに参加している全員が同時にプレーするわけじゃないからね)、 一応中期的な目標である1000ユーザーには耐えられそうだ。

ちょっと厳し目に計算しているつもりだし、 強力なサーバーPCを用意することもできるわけだから、 1台のPCでもこの数倍の人数はさばけちゃうかもしれない。

permalink no tweet

Rails 2.0.2を試してるけど

思ったりより変わってるなあ。もう少し使ってみないと、見えてこないな。

permalink
category: Rails(39)
no tweet

デバッグのアイデア

ゲーム業界でデバッグというと、プログラマーではないプロのテストプレイヤーに 実機で動くROMなりを渡してバグを探してもらう作業の事をいう。 ちにみに、このテストプレイヤーのことをデバッガーという。 デバッグ会社というのもいくつかあって、前日の18時までに連絡すれば次の日からプロの人がきてくれます。

というわけでデバッグという言葉から感じるニュアンスが他の人と違うかもしれない。 というのは余談。

Railsアプリのデバッグをするときにこんな機能があったら便利じゃないだろうか。

  • いつでもDBの状態をセーブできる
  • セーブした状態はリストとして表示される
  • いつでも任意のセーブポイントに戻すことができる
  • いつでもDBを初期状態に戻せる
  • これらの操作はすべてWebから行える

DBを使った開発では、なにかこういったことを便利にやるノウハウがあるのかな。

permalink
category: Rails(39)
no tweet

ステージ機能実装方針

ステージ機能というのは、ランキングを集計する期間に区切りを作って、 期が変わればまた気分を一新して頑張れるよ、という仕組み。 他にも上位をキープするプレイヤーのプレッシャーを開放するという作用もある。 で、やっぱりこれがないと、エンドレスなわけでほんと辛いんで、 この機能が入るまでは長期運用はできないと思っている。

前置きはさておき、実装方針。 とにかく少ない修正で実現したい。

  • テーブルgame_environmentsにカラムnum_remainder_gamesを追加
    • ステージの残りゲーム数をカウントダウン
    • num_remainder_gamesが0になったときにステージ切り替え処理を行う
  • 切り替え処理
    • ランキングを計算してDBに突っ込む。1ステージ分のデータ(2次元配列)を1レコードに突っ込む(切り替え処理のときではなく毎
    • ステージ数をインクリメント
    • スケジュール、試合結果データをすべて削除
  • あとは通常のスケジュール作成処理を行えばOK
  • 過去のランキングを見れるようにする
    • そうかステージランキングを毎日更新すればいいわけだ
    • で最新のランキングもDBから引っ張ってくるようにする
    • 新しくrankingsテーブルを作成
  • ステージ切り替えのお知らせメッセージを追加
permalink no tweet

MySQL→SQLite3(解決編)

MySQLのインストールがうまくいかないのは、HDDが一杯だからだったorz。

MySQLを入れてSQLite版と比べたら、 SQLiteでうまく動かない原因もわかった。

models.find(:first, :conditions => "flag = 0")

flagはboolean型。上記の書き方はMySQLに依存している。 SQLiteだとfalseは"f"として登録されるらしい。 アホなバグ。十数か所を修正。 たぶん正しい書き方がわからなくて痛い目を見るのを覚悟で書いたコードだと思う。

次のような書き方が正しい。

models.find(:first, :conditions => ["flag = ?", false])

この調査と修正、確認作業で2時間を失う。 自業自得でくだらなくてやや腹が立つ。

もうひとつ問題があった。 あとmigrationで次のように書いたときに、

t.column "flag", :boolean, :default => true

MySQLだとflagに1が入るけど、SQLite3だと"f"が入る。 つまりSQLite3だとcreateしたときにfalseになる(バージョンは1.1.6)。 とりあえずモデルに以下を追加しおいた。

before_create {|e| e.flag = true }

これでSQLite3でも動くようになったぽい。 もしかしたら他にもなんか違いが出てるかもしれないけど。

permalink no tweet