ネットワークゲームの書き方 [閉まっている]


73

基づいて、なぜそれがMMOを開発するのは難しいのですか?

ネットワーク化されたゲーム開発は簡単ではありません。遅延だけでなく、チート防止、状態管理、および負荷分散においても克服すべき大きな障害があります。ネットワークゲームを作成した経験がない場合、これは難しい学習課題になります。

ソケット、サーバー、クライアント、プロトコル、接続などに関する理論を知っています。

今、私はどのようにネットワークゲームを書くことを学ぶことができるのだろうか:

  • 負荷の問題のバランスをとる方法は?
  • ゲームの状態を管理する方法は?
  • 物事を同期させる方法は?
  • 通信とクライアントをリバースエンジニアリングから保護する方法
  • 遅延の問題を回避する方法は?
  • ローカルで計算する必要があるものとサーバー上のもの
  • ...

これに関する良い本、チュートリアル、サイト、興味深い記事、またはその他の質問はありますか?

幅広い答えを探していますが、違いを学ぶには特定の答えでも構いません。


4
はい、これに関する書籍、チュートリアル、サイト、興味深い記事、その他の質問があります。
リケット

2
質問を修正せずにプッシュし、この質問に答える価値があるため、ユーザーに答える理由を与えるために賞金を追加しました。
タマラWijsman

回答:


61

他の回答にリンクされている記事に加えて、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で負荷分散を実現するにはどうすればよいですか?」


1
UDPにはわずかに多くのCPUが必要であると述べましたが、TCPはパケットが処理される前にクライアントとサーバー間で少なくとも3回のトリップが必要であり、以前のすべてのパケットが受信されるまでパケットがバッファリングされるため、ばかげている可能性があります関連性がなくなったパケットを待つ遅延量。言及する重要なことのようです。
BlueRaja-ダニーPflughoeft

2
@Danny、新しいTCP接続を開始するために必要な3つのパケットがあります:クライアントからサーバー:SYN、サーバーからクライアント:SYN ACK、クライアントからサーバー:ACK +データ。これはUDPよりも1往復多いですが、クライアントが最初にサーバーに接続したときの最初にのみ発生します。確立された接続では、すべてのパケットは追加のラウンドトリップなしですぐに処理されます。ACK応答がありますが、受信したデータはすでに処理されており、ACKパケットは戻ります。
ヘンドリックブルマーマン

1
@ Danny、TCPはパケット損失を自動的かつ非常に効率的な方法で処理します。UDPを使用して自分で再実装することは困難です。プロトコルがランダムな未配信パケットで問題ない限り。次の問題は、TCPがパケットの順序を保証する一方で、UDPパケットが間違った順序で受信される可能性があることです。繰り返しになりますが、たとえばパケットカウンタに基づいて古いパケットを単に無視できない限り、自分で再実装することは困難です。TCPに非常に短い応答時間が必要な場合、Nagleのアルゴリズムを無効にする必要があります。
ヘンドリックブルーマーマン

非常に現実的なTCPラグの問題に対処せずに、自分の立場を徹底的に擁護したようです。おそらく、本当の問題ではなく、DDoS攻撃耐性プロトコルのハードウェアファイアウォールのあなたの選択である
MickLH

27

http://gafferongames.com/networking-for-game-programmers/

ゲームネットワーキングに関するさまざまな問題と解決策に関する素晴らしい記事のセットです。


1
+1、しかし盲目的に信用しないでください。たとえば、私の経験によれば、UDPを使用してTCPの機能を再発明することは得策ではありません。UPDは、紛失したパッケージがまったく影響を与えない場合、つまりすべてのUDPパッケージに世界の完全な関連状態が含まれる場合にのみ役立ちます。WoWはTCPを使用し、SLはUDPからTCP(静的コンテンツのHTTPも含む)への移行を進めており、これらの変更によりパフォーマンスが大幅に向上しています。
ヘンドリックブルーマーマン

7
ただし、TCP機能を再発明するのではなく、少なくともすべての機能を再発明するわけではありません。TCPフロー制御とパケット損失のセマンティクスは、低遅延接続を必要とするゲームにとってはひどいものです。TCPは、待ち時間を気にしたり、必要な帯域幅を最小限にしたりしない場合にのみ役立ちます。
jsimmons

2
TCP上のUDPからHTTPに行くことによってセカンドライフ大規模なパフォーマンスの向上:blogs.secondlife.com/community/technology/blog/2010/08/13/...
ヘンドリック・Brummermann

5
そうではない、彼らはそれがどのように動作するかを変更することにより、資産ストリーミングのパフォーマンスを改善しました。そのインスタンスでHTTP / TCPを使用すると、実装が簡単になり、高速ではなくなりました。また、zeromqは興味深いプロジェクトであり、ゲームネットワーキングに非常にうまく対応できる可能性があることに注意してください。 zeromq.org
jsimmons

8

作成しているゲームの種類によっては、低レベルのネットワークプログラミングの一部を回避できる場合があります。一部の種類のゲームでは、クライアントとサーバー間の多くの往復通信を必要としません。そのような場合、より高いレベルのフレームワークを使用することを選択できます。たとえば、私はC#/。NETでターンベースの戦略ゲームを開発しています。ターンベースの戦略ゲームは、クライアント/サーバー通信の大部分がターンの開始時と終了時に発生し、その間に比較的少ないという点でやや独特です。そのため、主にWebサービス用に設計された高レベルの通信フレームワークであるWindows Communication Foundation(WCF)の使用を選択しました。ソケットとすべての低レベルのネットワークガンクを直接操作する代わりに、標準のメソッド呼び出しのように見えるものを作成できます。WCFにプロトコルとトランスポートレイヤーを処理させます。低レベルのネットワーク関連のものに対処する必要があったのは、エンドポイントを構成したときだけでした。これは、構成ファイルでの1回限りの処理です。それでもいくつかのカスタムシリアル化ロジックを実装する必要があるかもしれませんが、とにかくそのようなことをする必要があります。


8

問題は広すぎる。答えは、それ自体でウェブサイトを満たすことができます。しかし、これに関係する本があります。主に次の2つです。

これらの本でさえ完全なガイドではなく、代わりに使用できるアイデアとアプローチのコレクションであり、それらの一部は一緒に機能しないか、矛盾していることさえあります。通常、ゲーム、ネットワークアプリケーション、または理想的にはその両方の開発経験があることを前提としています。

(元の質問でMMOについて詳しく話していることに注意してください-「ネットワークゲーム」は、PHPベースのテキストゲームからMMOまでのあらゆる種類のことを意味する可能性があり、上記のサブ質問はすべてではありません各タイプに適用されます。)


7

負荷の問題のバランスをとる方法は?

固定された地理的サイズ+複数のインスタンスが最も簡単なソリューションです。SWGに取り組んでいる人たちは、動的なサイズを試し、後悔しました。

ゲームの状態を管理する方法は?

サーバーは信頼できます。

物事を同期させる方法は?

サーバーからの定期的な同期更新。(懸念がここにあるかどうかはよくわかりません)

通信とクライアントをリバースエンジニアリングから保護する方法

不可能な。クライアントから受け取ったものを信頼しないこと、およびサーバーが信頼できることを確認してください。

遅延の問題を回避する方法は?

これは何マイルも深くなりますが、表面的にはクライアントとサーバーと同じシミュレーションを実行し、同期が発生したら問題を修正します。クライアント上で行われたすべての決定は、サーバー上でもシミュレートされるため、不適切な決定が行われる可能性がありますが、通常はうまくいきます。

ローカルで計算する必要があるものとサーバー上のもの

クライアントは、サーバーで行われていることの権限のないシミュレーションを実行していると考えてください。応答性はプレイヤーエクスペリエンスの鍵であるため、たとえバーが始まったばかりであっても、プレイヤーが決定するたびに何かをする必要があります。

正直言って、これらの問題の多くは直交的であり、後で解決策を適用することができます。ゲームを始めて、これらのことについてあまり心配しないでください。


4

この質問は非常に広範です。また、マスターするのは非常に難しい領域です。ネットワークプログラマーは、業界ではマッチングペイでかなり求められています。これは、「未解決」の領域であることを示しています。本がありますか、はい、たくさんあります。良い本がそこにありますか、間違いないでしょう。あなたの質問に答える本がありますか?...私はそうは思いません。彼らはいくつかの状況で働く解決策や探すべきものへのポインタを持っているかもしれませんが、あなたの質問のほとんどはゲームに依存しています....これはあなたが本当に自分で多くのことをしなければならない分野です些細なことであり、非常に多くの(制御されていない)方法でうまくいかないことがあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.