Akashic Engine を使うと ゲームアツマール や ニコ生ゲーム でマルチプレイゲームを公開できます。
本記事では、Akashic Engineを使ってマルチプレイゲームを初めて作る際に覚えておきたい、一般的なクライアント・サーバモデルとの違いを紹介したいと思います。
クライアント・サーバモデルとAkashic Engineマルチプレイの違い
一般的なクライアント・サーバモデルの場合、クライアントのリクエストを元にサーバ側で処理を行い、結果をクライアントで描画すると思います。クライアント側とサーバ側で両方のコーディングが必要です。
しかし、Akashic Engineマルチプレイはクライアント側のコーディングしかしません。サーバ側ではなくクライアント側で処理します。ではサーバは何をするかというと、クライアントからメッセージを受け取り、全クライアントにメッセージを発信する役割を担います。
サーバサイド固有のロジックは存在しない
Akashic Engineマルチプレイの場合、サーバはクライアントから送られたイベント(g.game#raiseEvent
)を全クライアントに発信(g.Scene#onMessage
)します。そのため、何かデータを加工したりデータを元に判定する処理はすべてクライアント側で実装する必要があります。
ランダムな動きは同じシードを持つ乱数生成器で同じ状態を作り出す
プレイヤー以外にCPU、モブ、NPCがいる場合、ランダムな動きをさせる必要があると思います。一般的なクライアント・サーバモデルの場合、これらの座標やアクションはサーバ側で計算して結果をクライアントに返すことになると思いますが、Akashic Engineマルチプレイの場合は異なります。
理論的には初期状態から同じシードを使って乱数を生成し、同じ時間経過処理を回せば全く同じ状況が作り出せるはずです。拙作の例で恐縮ですが、「出勤のお時間です!【対戦版】」では住宅付近のランダムな位置に出現した通勤客が経路探索して会社に向かいます。出現位置はシード値を共有する乱数生成器を使うことで全クライアントで同じにすることができます。経路探索処理もクライアント側で実行しますが、同じロジックを使うので同じ時間経過すれば同じ経路をたどるはずです。
途中参加プレイヤはゲーム開始から早送りすることで同期する
ゲームは始まってから参加したプレイヤにどう現在の状態を伝えるかですが、一般的な場合、スナップショット情報(どのエンティティがどこにいるかなど)を送ると思います。
Akashic Engineマルチプレイの場合、初期状態から経過時間早送りすることで追いつきます。途中参加プレイヤには何tick目にどのイベントが発生したかという情報が送られます。クライアント側で高速でtickを回し、イベントを消化していけば同じ状況になるはずです。
Akashic Engine 入門(v3 版) マルチプレイの基礎
同じゲームスクリプトに、同じ経過フレーム数で同じイベントを与えれば、同じ実行状態に至るはずだ 、というのが、Akashic Engine のマルチプレイの基本的なデザインです。後から参加したプレイヤーに、早送りで最新状態に追いつく動作が発生するのはこのためです。
したがって、途中参加プレイヤ向けに現在のスナップショットを通知する必要はありません。
まとめ
Akashic Engineでマルチプレイゲームを作る際、一般的なクライアント・サーバモデルと異なる点に注意しましょう。
- サーバはクライアントからのイベントを中継します。イベントを受けたロジックはすべてクライアント側で実装しましょう
- モブなどのNPCは乱数生成器のシードを共有することで同じ状態を再現します。イベントで送る必要はありません。
- 途中参加プレイヤは早送りして追いつきます。したがってスナップショット情報は送る必要がありません。