ドラゴンクエストみたいなオンライン仕様等のページ

ここではみたいなオンラインに関する仕様について書いていこうと思います。今まで得た知識等を記録として残していけたらなと。かなり字が多いページになるかと思います。

サーバースペック
みたいなオンラインサーバーを動かしているサーバーのスペックは以下のような感じです。
余りパーツで作ったケースのない基盤まるだしの自作PCで運用していたりします。サーバーPCはこんな感じ。

CPU:PentiumV866MHz
MEMORY:256MByte(PC133)
OS:Windows2000ProSP4
回線はフレッツADSLモア12M。実測は、いい時で↑750Kbps↓4Mbpsくらいです。あまり恵まれているとは言えないような環境ですね。
 という事で、現在100人くらいしかログインできないように規制しています。100人きた事は1度(しかも一瞬)しかありませんので、規制自体意味がないかもしれませんが・・・

 

 

 

作成開始にいたる経緯
 構想は2002年に作成した「ドラゴンクエストみたいなオンライン」が終わった頃からありました。前回は流れるパケットの事を余り意識せず実装した為、インターネット経由でやるとかなり無駄に帯域を使ってしまいまともに動作できませんでした。
 それから数ヶ月間別のゲームやアプリを作りながら、いつかインターネット経由で遊べるネットゲームを作ってみたいなと思っていた頃に、同じように個人でネットゲームを作っている話を聞き、見て、「あぁ、できそうだ。」と思い、決意。それから数ヵ月後の2003年
4月29日に実装を開始しました。

ソースコード
 いろいろ考えた結果、ソースコードを一部を除いて公開します。
 なぜ一部といはいえソース公開するか?というと、「インターネット経由で遊べるものを作ってみたい」という最初の課題はクリアできたので、同じような考えを持っている人の手助けになればいいなぁと。
 公開したから終わりなんて事はなく、今後も自分のペースで開発は続けます。まだまだ問題は多いですし。
 また、いろいろな人からのつっこみがあればうれしいなと。「ここはこうした方がいいよ。」とか。人に見せる事で自分のスキルアップにもなりますし。
 と、いう事でこのソースがゲーム作成を目指す人にとって何らかの手助けになってもらえればうれしく思います。
 ソースはこちら(更新:03/11/23)。転載等はご遠慮ください(そんな大したものではありませんが・・・)。

DirectXについて
 今やゲームを作るには欠かすことができないDirectX。このソフトでも例外なく使用しています。
 DirectMusicとDirectPlayを使っています。なぜDirectX9が必要かというと、DirectPlay9のSendToというメソッドにDPNSEND_COALESCEというフラグが追加され、パケットが結合できるようになったという事で、少しでもラグ軽減につながるかなぁというのが理由です。DirectMusicは8を使っています。描画は完全に自前です。内部的に32ビットのメモリ配列で昔ながらの方法でゴリゴリと書いて最後にBitBltAPIで表示させてます。
03/11/23追記
 通信エンジンを自作に置き換えたという事で、DirectX8でも動作するようです。とはいえ、今さらバージョン落として告知するのもなんなので今まで通り9が必要という事にしておきます。

内部的な構造
管理人と一般プレイヤー
 管理人権限を持っているといろいろな事ができます。簡単にいうと、サーバーで持っている情報を自由に変更する事ができます。今回作成を始める前に思っていた事として、キャラ情報やマップ情報を変更する為にサーバーを再起動させたり、コンパイルし直したりする事がないようにしよう。というのがありましたので、ほぼ全ての情報を操る事ができます。これにより、みんなで画面をみながらマップの拡張をする事ができるようになったわけです。

基本構成
 ごく一般的なサーバー・クライアント接続型のアプリケーションです。通信周りにはDirectPlayを使用しています。8から使い始めたので、それ以前の事は知りませんが、8で前面書き直しされたという事でかなり使いやすいライブラリになっております。
03/11/23追記
 通信周りにDirectPlayを使っていたのですが、数ヶ月間ハンドルリークに悩まされ、結果winsockによる自作エンジンに置き換えをしました。自分の使い方が悪かったのか結局わからなかったのですが、winsockに置き換えてからリークは無くなったので、まぁいいかという事で。

基本関係図 
 クライアント同士は接続を行っておらず、他のクライアントへ何かをする為には全てサーバーを経由する必要があります。この為全ての情報はサーバーに集まってきます。商用MMOなどでは負荷分散を考え、いくつものサーバーに処理が分担されているようですが、今回は数十人規模の小さなものなのでそこまで考えらておらず、全ての処理を1つのアプリケーションで行っています。この為、あらゆる事を並列で処理する形をとっています。また、排他処理を考えて、DirectPlay部分以外は1つのスレッドで処理しています。

 

 

処理イメージ ウィンドウメッセージが無い時はいろいろな処理を行います。各キャラクターの処理、時間が関係するイベント処理等をこなします。ここで処理に時間がかかると、ウィンドウメッセージの処理が溜まってしまう為、1ループにつき1キャラ、イベントも1つとし、順番に処理します。なかなか順番が回ってこないような感じがしますが、実際に1800キャラほどある状態で計測してみると、数ミリ秒しかかかっていなかったので、今の所問題なさそうです。チャットの発言や向き・座標の変更、イベント処理、戦闘の処理などもこの時に行います。回転寿司のようなイメージをすればわかりやすいかもしれません。全てのキャラはお皿の上に乗って回っている状態のような。



キャラの移動
 キャラの移動は、開発初期の段階でかなり悩みました。何か参考にできるものがあればよかったのですが、オンラインゲームの設計方法について書いてあるページは見つからず、かといってMMOサーバーエミュのソースコードを解析するのも大変そう・・・という事で今までの経験をもとに試行錯誤の結果今の形になっております。果たしてこれが一般的なのかどうかは、わかりません。

 商用MMOと違い、一般家庭のADSLでサーバーを運用する為、速度に頼った処理はできません。この為、移動時の背景やキャラとの当たり判定はクライアント側で行っています。移動時に当たり判定を行い、問題がなければ座標をサーバーに通知します。受け取ったサーバーは、その値を信じて同じ画面内にいる他のプレイヤーに座標を広めるわけです。サーバーで処理するのが望ましいのですが、そうしてしまうとサーバーから返答があるまで動く事ができなくなり、1歩歩くだけでもストレスを感じる事になってしまいます。

コマンド送信イメージ移動時の判定
 一歩あるく毎に、画面端にキャラが見えるかどうかの判定を行います。もし見えるなら、見えたキャラの情報をクライアントに通知します。クライアント側では、見えなくなったキャラの判定を行い、不要な情報は削除します。削除せず残していた方が情報のやり取りは少なくなるのですが、画面の描画や当たり判定等を考えると、必要な分だけ持っていた方が処理が速いのでこのようにしています。

戻る