node.jsで作る非同期型ネットゲームのプロトタイプやあshi3zだ。さっきはあまりに簡単にチャットを書くことができたので、感動のあまりすぐ公開しちゃったけど、node.jsとenchant.jsを使って簡単なネットゲームのプロトタイプを作ってみたぞ。荒削りだけど、ネットゲームのプロトタイプとしてはこんなもんだろう。どんな構造になっているか解説しようこのゲームは週刊アスキーの連載「私立9leap高校ゲーム開発部」で掲載した「育ててポン!」というゲームをもとにして作っている。これはドロイドちゃんを操作して、木を育て、最後にフルーツを収穫する、というタイムアタックのアクションゲームだ。今回はこれをネットゲーム化してみる。サンプルコードは以下のURLからダウンロード可能だ。http://junk.wise9.jp/sodapon.zipまずはサーバーだ。前回のチャットではサーバはサンプルそのままだったけど、今回はサーバも少し違う。サーバの中身はapp.jsというコードに入っている。切断log('disconnected');});});サーバとクライアントのやりとりする決まり事をプロトコルと呼ぶ。socket.ioの面白いところは、プロトコルをjavascriptの関数としてガリガリ書ける事だ。「育ててポン!」本体のソースコードは長いので、ちょっと関係のありそうなところだけ抜粋する。msg.y;});});sockei.ioでは、JSONで通信するため、任意のJavaScriptオブジェクトをそのまま他のクライアントに渡す事が出来る。これが非常に便利なんだよね。このゲームの場合、木はそれぞれのクライアントがランダムに生成して、「うちで(x,y)に木を生成したよ」というメッセージを他のクライアントに投げると他のクライアントでも木が生えてくるというワケ。//新しい木を生成}});毎フレームサーバーに送信するとサーバーの通信を圧迫して輻輳(ふくそう)が発生する。通信パケットが渋滞するわけだ。そこで5フレームに一回だけ現在位置を送信することとし、それぞれのクライアントでは5フレームごとに受け取った位置を補完しながら表示する。this.frame=0;}}各ドロイドちゃんはこんな感じで位置を補完する。目標とする位置から現在位置を引いて方位ベクトル(vx,vy)を出し、それを長さ(len)で割る事で正規化して長さ1のベクトルを作り、そこに3を乗じている。これはどういうことかというと、他のクライアントは常に5フレーム遅れて座標を受け取るが、さらに数フレーム遅れて動くということになる。こんな処理を入れてわざわざ遅くするのかというと、人間というのは一見して滑らかに見えるほうが、正確に動くよりもより自然であると認識するからだ。このゲームは木を育てて実がついた状態で触ると、パーンとフルーツが弾けて出てくるが、この部分はランダムであり同期しないようになっている。プレイヤーごとに見えている世界には食い違いが出来るようになっている。これはインターネットという遅延の激しい環境でゲームを実現するために必要なある種の「割り切り」だ。して、Aというプレイヤーが見ている世界とBというプレイヤーが見ている世界は微妙に食い違うことになる。ゲーム全体を通してみると、この食い違いはほぼ許容される、というのがこの非同期的な通信ゲームの落としどころだ。LAN環境やゲームセンターなどであれば、通信速度や遅延(レイテンシ)の問題はかなり解決されるため、完全に画面を同期させる事も可能だ。インターネット経由で遊ばせるにはかなり難しくなる。ネットゲーム開発の面白さは、この「食い違い」をいかに違和感なく見せるか、ということだ。「どの部分は厳密に同期が必要」で、「どの部分はどうでもいい」のか、という切り分けが、ネットゲームの面白さを決定してしまう。このことはプラットフォームがプレステになろうがxboxになろうが本質的には同じだ。今回、enchant.jsとnode.jsの組み合わせでこのプロトタイプを作るまでの時間はわずか1時間。JavaScriptがいかに生産性の高い言語なのか、改めて驚かされる。