他の回答にリンクされている記事に加えて、Arianne Projectの経験について少し話すことができます。
物事を同期させる方法は?
アクションと認識の概念を中心にフレームワーク„ Marauroa “ を構築しました。アクションはクライアントからサーバーに送信され、ユーザー入力(左を歩く、モンスター#47を攻撃、「hello」など)を送信します。また、サーバーからクライアントに認識が送信され、クライアントの周囲の世界の状態について通知されます。これらの認識は毎ターン送信されます。ゲームに応じて、30ミリ秒から300ミリ秒のターン時間を使用します。
認識には2つのタイプがあります。ログイン時と、プレーヤーが新しいエリア(ゾーン)に入ると、完全な認識が送信されます。その後、変更されたオブジェクトの変更された属性(位置など)だけでなく、もちろん新規および削除されたオブジェクトを含む、異なる認識が送信されます。
遅延の問題を回避する方法は?
「サーバーは常に正しい」と強く信じています。クライアントは、スムーズな歩行、衝突チェックなどの予測を行います。しかし、クライアントとサーバーが何かについて意見が合わない場合、サーバーが勝ちます。サブプロジェクトStendhal(2D RPG)は、デフォルトで300msのターンタイムを使用します(クライアント側で多くのスムージングが行われます)。これにより、スタンダールはラグに対して非常に耐性があります。
注:他の一部のゲームは、ネットワークラグの影響を最小限に抑えるためにクライアントをある程度信頼しています。WoWでは、「Warsong Gulch」と呼ばれる戦場でしばしば悪用されました。旗を持ったプレイヤーが選択できる方法は2つあります:トンネルの真ん中にあるものと、丘を登る正しい場所にあるものです。そのため、不正行為をしているプレイヤーはトンネルに向かって走り、その後自分自身に遅れを生じます。サーバーと他のクライアントは、彼がサーバーに向かって走っているのを見続けます。しかし、しばらくすると、このクライアントはサーバーに丘に向かっていることを伝えることができます。WoWは、最後に送信された座標と現在の座標との間の距離が時間セグメント内に収まることを確認し、それを受け入れます。
UDPとTCPの使用
初期のバージョンでは、UDPを使用してTCPのオーバーヘッドを削減しました。紛失したパケットは自分で処理しました。これは、プロジェクトの初期には完全に機能しました。しかし、数年前にサーバーを自宅のDSL接続から実際のデータセンターに移動したとき、大きな問題が発生しました。UDPは(少なくとも5年前は)ファイアウォールハードウェアのCPUパワーを非常に要求しています:ルールセットはすべてのUDPパケットに適用する必要があります。ただし、TCPの場合、ルールセットは最初の3パケットにのみ適用されます。その後、接続が確立されます。次のすべてのパケットは、接続追跡テーブルにあるか、SYNフラグがないため、通常のルールセットをバイパスします。
通信とクライアントをリバースエンジニアリングから保護する方法
Arianneは完全にオープンソースであり、これにはクライアント、サーバー、グラフィック、音楽が含まれます。そしてもちろん、プロトコル文書やデバッグに使用されるアナライザーも含まれます。
SSLを使用して、第三者による不正なスニッフィングから通信を保護するのは簡単です。
ただし、リバースエンジニアリングから保護することはできません。確かにそれを難読化し、アンチデバッグ技術を使用できます。しかし、最終的には、ユーザーに提供するソフトウェアのリバースエンジニアリングを防ぐことはできません。開発者がアンチデバッグ技術に多大な努力を払っていたにもかかわらず、Skypeがどのようにリバースエンジニアリングされたかについて非常に興味深いプレゼンテーションがあります:http : //recon.cx/en/f/vskype-part1.pdf
注:リバースエンジニアリングが違法である国や、ライセンスに段落を挿入できる国や、リバースエンジニアリングを禁止するToSがあります。しかし、互換性のあるデータストレージフォーマットまたは送信プロトコル、ライセンスの段落、またはToSを許可しないことを開発しようとするコンテキストで明示的にリバースエンジニアリングを許可する他の国(私が住んでいる国など)は無効です。(このセクションのすべては、私が知る限り、私は弁護士ではありません)
ローカルで計算する必要があるものとサーバー上のもの
サーバー上のゲームロジックに関連するすべてを計算します。クライアントは、ゲームをスムーズにプレイするために特定のイベントを予測します。しかし、最終的にサーバーは常に正しいです。
予測されるイベントとは、たとえば衝突が発生したときに動きを止めることです。Stendhalは、グリッドを使用して要素を配置します。サーバーの観点から見ると、すべてのエンティティの左上隅はちょうど1つの正方形上にあります。しかし、クライアントはタイル間をスムーズに移動します。疑似3D効果も描画されます。したがって、1x1のベースを持つエンティティは、クライアント内でより高い可能性があります。
負荷の問題のバランスをとる方法は?
メンテナンスを容易にするために、これを可能な限りシンプルに保つようにしてください。
静的コンテンツの負荷分散は、httpサーバークラスターおよびコンテンツ配信ネットワークの分野でよく知られています。
ゲームサービスの負荷分散の比較的単純な概念は、リージョン/ゾーン間でサーバーを分割することです。したがって、ゾーンACは1つのサーバー上にあり、ゾーンDFは別のサーバー上にあります。あるセットのゾーンから別のセットのゾーンを見ることができない場合、これは特に簡単です。クライアントがプレーヤーがいるゾーンを担当するゾーンサーバーにのみ接続できるように、そこにチェックを入れる必要があります。
プレイヤーをあるサーバーから別のサーバーに転送する最も簡単な方法は、プレイヤーをデータベースに書き込み、他のゾーンサーバーに接続するようにクライアントに指示し、現在のサーバーから切断することです。その後、クライアントはデータベースからロードする新しいゾーンサーバーに接続します。(とにかくデータベースコードへの/ストアからのロードが必要なので、ハンドオーバーのためのサーバー間の直接通信は後で実装できます)。
いくつかの追加のグローバルサービスが必要です。ログイン時に、クライアントは正しいゾーンサーバーに接続するように指示される必要があります。また、世界規模のチャットシステムが必要な場合もあります。
このトピックの詳細については、「MMOで負荷分散を実現するにはどうすればよいですか?」