Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2009-06-26

[開発][Rails]Passengerに挑戦。あと登録ユーザー数の概算

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

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

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

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

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

2009-06-24

[Ruby]Rubyはそんなに遅くない

ゲーム開発環境としてRubyが遅いと言われるとどうにも納得がいかないので、 下のようなスクリプトで実験。

1000個のスプライトを作成し、スプライトそれぞれを移動、 壁との跳ね返り、自機とのあたり判定を行っている。 秒間60フレームを想定して60回実行する。

$hit_counter = 0

class Sprite
  attr_accessor :x, :y, :vx, :vy
  def initialize(x, y)
    @x, @y = x, y
    @vx, @vy = 1, 1
  end
end

def run(sprites)
  ship = Sprite.new(10, 10)
  60.times do
    sprites.each do |e|
      e.x += e.vx
      e.y += e.vy
      e.vx *= -1 if e.x < 0 or e.x > 100
      e.vy *= -1 if e.y < 0 or e.y > 100
      if ship.x == e.x and ship.y == e.x
        $hit_counter += 1
      end
    end
  end
end

require 'benchmark'
sprites = Array.new(1000) { Sprite.new(0, 0) }
puts Benchmark.realtime { run(sprites) } 

手元のPC(Core2 CPU 6400 @ 2.13Ghz 上の ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin])で動かした結果、かかった時間は、

0.180000066757202

である。1.0だとギリギリ秒間60回まわせると言うことになるので、まだだいぶ余裕がある。

ちなみに別のPCで計測すると、

0.189450025558472    # ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-linux]
0.0885939598083496   # ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux]

という結果に。さすが1.9は速い。

上記処理で負荷の1〜2割程度と言うと、 1000個のキャラクターを凝った動かし方にするのは厳しいと思うけど、 数十から数百個レベルなら問題ないんじゃないかな。 描画ライブラリが十分に速ければ。 ライブラリはCで実装できるから十分な高速化が可能だろうし。 良く知らないのだけど速度的な意味では今時の携帯ゲーム機と同じくらいなんじゃないかな? (いやPSPは圧倒的に速そうだな……)

やっぱり古い環境を知っているからRubyは遅くないって思ってしまうんだろうな。 でも過去の名作ゲームにはもっとずっと厳しい環境で作られてきたものがたくさんあるはず。

(GCで止まるとかはまた別の話。)

2009-06-10

[開発]Javascript+Canvasで実装したMMORPGのクライアント(2)

「3D空間上にキャラと地面を表示して歩かせる」というのをJavascriptとCanvasで実装したもの。 前回のバージョンに少し手を入れた。

world20090610.png

http://dgames.jp/archive/world/client20090610/world.html

  • 動作確認をしてるのはWindows上のChrome、Firefox、Safari、Opera
    • Chrome推奨。Safariも速い
  • Canvasが使えないIEはまともに動かないはず
  • スペースキーで視点回転、地面をクリックするとそこに移動
  • 自キャラはNPCの絵はランダムで決定

細かいバグを修正し、エリア移動の機能を実装した。 エリア移動とはいっても公開しているのはクライアントプログラムのみなので、 サーバーの処理は切ってあるので、たんに黄色い地面を踏むとエリアが切り替わるだけ。

実は内部的にはソースを結構書き換えてはいるのだけど(後々管理しやすいように)、表面上はあんまり変わってないかな。

細かいところだとキャラ画像の表示方法を変えた。前回はCanvasのImageで画像を生成して描画していたのだけど、今回はHTMLのimgタグで表示してる。 というのは、Chromeで動かしたときCanvasのImageだとGIFアニメがうまく動いてくれないため。 imgタグで使用するGIFを画面のどこかに表示しておくと、 Imageのほうもアニメーションしてくれるのだけど、これだと無駄に画像を表示しないといけない。 Firefoxだとそんなことないんだけど……。

今回はキャラクタがチャットウィンドウの上に表示されてしまっている。 わざとこうしているのだけど、その理由はウィンドウの下に描画するとクリックイベントが検出できなくなってしまうため。 まあ上にクリック検出用の透明画像を重ねてやれば、 ウィンドウの下に描画することも可能だと思うのだけど、まだそこまではやっていない。

ただimgタグでキャラクタを表示しちゃうとCanvasに表示したポリゴンとZソートできないんだよなあ……。 CanvasのImageで描画したときにGIFアニメがちゃんと動いてくれるようにする方法があるといいのだけど。

2009-06-10

さくらインターネットにRedmineを入れてみたが……

とにかく重い。CGIで動かしているからしょうがないか。 でも、これはちょっと使えないな。

しかし、Readmine、使いやすい!

画面のレイアウトもいいし、ページ構成も自然に感じられ(シンプルで無駄がない)、 この手のツールを使い慣れていないメンバーもすんなりと受け入れてくれた。

あまりに使い勝手が良いので、こっちの開発にも導入したい。 社内で動かす場合はWEBrickで良いのでとっても楽なんだけど、 こっちはグローバル環境に立てなければならないので、どうしたものかなあ。 自宅サーバーはもう2つもRailsサーバー立てちゃってるから……。 512Mから1Gにメモリを増強したいな。ヤフオクで探してみるか。

以下メモ。

rake db:migrate RAILS_ENV=production

を実行したときに次のようなエラーが出たのだけど、

rake aborted!
no such file to load -- iconv

Rubyをビルドしなおしたら直った。

調べたらconfigureのオプションに以下を追加するといいというのを見かけたのだけど、

--with-iconv-dir=/usr/local

上のオプションなしで、ビルドしなおすだけで大丈夫なような気もする(オプション付きでインストールした後、オプションなしでビルドインストールしたら動いた)。

2009-06-08

「横浜へなちょこプログラミング勉強会」行ってきた

今回は「第4回プログラマの数学読書会」。

40分ほど早めに行って必死に本を読んだ。 あらかじめ決められた範囲を読んでから参加することになっているところが(個人的には)辛い。

始まる前にhkhumanoid君にMacBookでARのデモを見せてもらう。 実物を始めて見ることができた。ありがとうございました。

あとAndroidのデモ(PC上のエミュ)も見せて頂いた。

プログラマの数学

今回は5章と6章。

例によってわからないところは流れを止めてもらって教えてもらう。 今回も疑問点を非常によく理解できた。

毎回純粋に数学の勉強になり、忘れていたことをたくさん思い出せてくれる。

鍋谷さんの問題だけど、今調べたらRubyにはcombinationがあった。

def combi(a, b)
  puts (1..a).to_a.combination(b).map {|e| e.join(' ') }
end

combi 6, 3

でいける。反則だなこりゃ。

ちなみに問題は以下。

問題 正の整数aとbを受け取り、1からaまでの整数から重複なくb個を選ぶ選び方をすべて出力するプログラムを書け。 出力順は問わない。また、不正な入力(範囲外、非整数、負の数など)に対する対応はしなくて良い。

懇親会

MacBook を買おうと思っているので、Macのことについて教えてもらった。 ほとんど何にも知らないくらいだったのだけど、たくさん教えてもらってすごくためになった。

幸運にも知りたかったカメラについての話も教えてもらえた。一眼レフの「ボケ味」とか。 でもデジタル一眼レフは8万とか、安くても5万以上とからしい。うぐぐ、さすがに高くて手を出せない。

2009-06-05

PTAM + AR on an iPhone 3G

http://www.youtube.com/watch?v=pBI5HwitBX4

なんだこれはー

カメラを手で持ってPCのモニタに移すやつは気になっていたけど、 なかなかいいゲームにする方法を思うつかなかった。

でもこれだとiPhoneがそのままコントローラとディスプレイになるので、 つまり同時に入力装置と出力装置になってしまうわけで、すげーお手軽なゲームになるじゃないか。

ぱっと思いつくのは、机の上にでっかいモンスター(恐竜とか)がいて、 それをいろんな方向からのぞきながら倒すアクションゲームとか。 iPhoneの注視点をそのままキャラクタの位置にするとかしてキャラを移動させても面白そうだし、なんか作りたい!

Mac買う!iPhone買う!あ、iPod touchでもいいの?

だれか一緒にやらない!?

2009-06-05

[開発]エリア移動やログインに関するところのメモ

  • ユーザーログインしていない状態
  • ユーザーログインしている状態
    • ワールドにログインしていない状態
    • ワールドにログインしている状態

w

  • ユーザーログインしていない
    • ログインメニューを表示
    • ロビー(エリアしてした場合はそのエリアへ)
    • ゴーストはどこにでも入れる。
    • ただし会話をポストできない。
    • 位置はポストする(もし不要ならあとでカット)
  • ユーザーログインしている
    • → 必ず所属エリアへ

ユーザーログインしていない

  • エリアをパラメタ渡し
  • エリアが指定されていまたは無効であればlobbyへ
    • サーバー側でエリアの存在を確認する

ユーザーログインしている

  • ○必ず所属エリアへ
  • クライアントで出口に触ったら
    • エリアチェンジコマンドをサーバーへ送信
    • サーバーでコマンドの有効性をチェック
    • OKならクライアントはリロード