サーバーがタイルベースの領域のみをクライアントに送信することは可能ですか?


8

はじめに、私はネットワーキング(ハードウェア、ルーターなど)については十分な知識を持っていますが、ネットワークプログラミングの基本的な知識はほとんどありません。これは馬鹿げた質問のように思えるかもしれませんが、自分のゲームでのマルチプレイヤーの実装を理解しながら、自分が何に興味を持っているのかを知りたいのです。

シンプルな2D配列によって生成されるタイルベースの世界を作成しています。簡単にするために、World [100] [100]のようなものを考えてみましょう。

現在、renderメソッドは、ウィンドウの解像度と1つのタイル(移動中のスムーズなレンダリング用)に基づいてタイルのみをレンダリングします。世界がどれほど大きい場合でも(10x10、1million x 1million)、レンダリングのパフォーマンスは完璧です。

ゲームプレイでは、現在表示されているもの(画面+1にレンダリングされたもの)と、おそらくプレーヤーの周囲の領域にあるタイルのいくつかの情報を知るだけです。

したがって、サーバーから送信されるものはすべて、完全なタイル情報にはなりません。例 地面、地面のタイプ、木などの上に置かれるアイテムは、プレーヤーの視野の外側の領域では重要ではなく、クライアント/プレーヤーがそれらのタイルについて知っておく必要があることだけです。(例:プレーヤー[キャラクターまたはプレーヤー]がレンダリングビューのタイルを超えていることをプレーヤーが知ることができるUltima Onlineの「着信名」。)

私はネットワーキングについてあまり知らないので、おそらくこれを知って、これが私の質問に答えるかもしれません。しかし、これが実現可能な解決策なのか、あるいはアイデアが単に笑えるものなのか、私は興味があります。

送信される情報は、タイルの約10x15の領域であり、各タイルはタイルの内容に関する情報を保持します。より効率的には、すべてがオブジェクトであり、タイルはタイル上のすべてのオブジェクトを保持します。例 Tile [4] [4]は、Sword#23452、Rock2、Tree5、Player3、Monster4を保持します。

初期化/ロード中にまだロードされていない場合、空のタイルは地形タイプ[草、砂、水]のみを送信します。一部のタイルには、少数のオブジェクトがあります[Tree2、Sword#924、Gold、Corpse、Rock3]。

したがって、クライアントが主にロードする必要のあるテクスチャとそれを画面に配置するために配置する必要があるため、タイルがサーバーからクライアントに送信する情報が非常に多いとは思えません。クライアントにレンダリングするように指示するファイルのリストでは、位置は2つの整数のみであり、テクスチャは1つの整数です。

最悪の場合、サーバーは150個のタイルに少数のオブジェクトOnLOADの情報のみを送信し、それ以降は更新によってタイル(存在する場合)と新しいタイル(プレーヤーが方向に移動するたびに10から15)への変更のみを送信します。 )と画面上のキャラクターの移動方向(クライアントがタイル間のスムーズな移動をシミュレートできるようにするため)。

これはインターネットまたはピア間で送信される信じられないほどの量の情報であると私は思っているので、私は正しいと思います。それとも、ネットワーキングについてあまり知らないので、ようやくマルチプレーヤーネットワーキングに関する本を開くことに取り掛かったとき、私の心は打たれるでしょうか。

クライアント/サーバー間で送信される情報の量が非常に少ない場合、初期化時に全世界を単にロードする方が理にかなっていますか?または、世界が大きすぎる場合は「マップ」。そして、LOADの後、更新されたタイルのみを送信しますか?

どうすれば具体的なデータの扱い方を考えているのか。私が参照として使用している本では、オブジェクトを追加および削除するリンクリストが必要なので、すべてがboolです。「キャラクターはいる?木はある?」

オブジェクトを保持するコンテナーや、レンダリングするものをクライアントに伝えるために必要なものだけを送信するサーバーロジックなど、別のアプローチを考えていました。おそらくそれ自体の内部にネットワーク情報を保持するオブジェクトがあり、サーバーから呼び出されたときに送信されます。


freemmorpgmaker.comをご覧になることをお勧めします。このエンジンは、始めたばかりのときに非常に役立ちました。スクリプトは比較的単純で、操作するのにたくさんの楽しみがあります。このコードは、自分の2Dエンジン/ゲームを作成するために知っておくべきことをすべて教えてくれました。それらから学ぶべきではないのは、サーバー/クライアントを保護する方法です。
Nick

回答:


6

あなたは正しい軌道に乗っています。

Minecraftを検討してください。Minecraftは、プレーヤーを直接囲む領域(チャンクとも呼ばれます)のみをロードします。これは、サーバーがメモリ不足になることなく実行できる方法であり、クライアントがネットワークトラフィックによって行き詰まらない理由です。

クライアント/サーバー間で送信される情報の量が非常に少ない場合、初期化時に全世界を単にロードする方が理にかなっていますか?または、世界が大きすぎる場合は「マップ」。そして、LOADの後、更新されたタイルのみを送信しますか?

これはまさにあなたがすべきことです。送信する必要があるデータのみを送信します。

  1. クライアントが参加したら、タイルマップのチャンクを送信します(小さな領域を扱っている場合は、すべてのマップを送信します)。
  2. プレーヤーがタイルを変更しようとすると、そのデータをサーバーに送信します。
  3. タイルの状態が変化したら、その情報を含むパケットを関連するすべてのクライアントに送信します。

タイルIDの2D配列を送信するだけの場合、特に256未満の異なるタイルタイプがある場合、データのサイズが非常に小さくなる可能性があります。その場合は、1バイト(またはunsigned char)を使用できます。したがって、プレーヤーに100x100のタイルを送信し、各タイルが1バイトのみで構成されている場合...アイデアがわかります。それは多くのデータではありません。

Minecraftコミュニティは、そのプロトコルを文書化する素晴らしい仕事をしました:http : //mc.kev009.com/Protocol

http://www.minecraftwiki.net/wiki/Classic_server_protocol


1
わぁ、ありがとうございます!これは、自分がほとんど知らないときに正しい方向に進んでいると私に言われた自信の大きな後押しです。私は物事を正しく理解し、できる限り最善の方法でエンジニアリングしていることを教えてくれます。勉強を続ければ十分にできると確信しています。前向きなアドバイスを聞くのはとても満足であり、「あなたはそれを間違っている!」笑:)

マルチプレイヤーゲームや3Dゲームをプレイするために神経質になる前に、長い時間がかかりました。:)
Nick Caplinger 2013年

また、積極的な助言は、このコミュニティが成功するためのものです。誰でもできる限りの方法で貢献することをお勧めします!
Nick Caplinger 2013年

3

一般に、プレーヤーに表示されることになっているクライアントにのみ情報を送信することをお勧めします。この原則に従うと、ネットワークトラフィックが減少し、不正行為が防止されます。

ただし、プレイヤーがキャラクターを移動するときは、サーバーから確認を受け取る前にクライアント側で移動を開始して、ゲームのラグを減らして反応をよくする必要があることに注意してください。それはおそらく、まだロードされていない領域まで画面をスクロールし始めることを意味するでしょう。これにより、マップのこの部分を空白のままにして、ロードされたときに実際の世界に置き換える必要があります。それはかなり没頭型のブレーカーになるでしょう。そのため、プレーヤーの画面の特定の半径の領域をプリロードする必要があります。

プリロードされた領域のサイズは、プレーヤーの移動速度と平均レイテンシの長さに依存します。


-1

サーバーからクライアントに送信するデータ量は、ごくわずかな場合があります。送信する必要があるのがこれだけの場合は、Loadでできるだけ多くロードすることを強くお勧めします。これにより、必要なデータがさらに少なくなります。ロード時に送信される量は、ロード時間を正当化するのに十分なほど小さく、世界が途方もなく大きすぎない限り、メモリ使用量はほとんど存在せず、データをほとんど更新する必要はありません。

ラグの予測を最適化するためにいくつかの巧妙なトリックを実行して、ユーザーが経験する平均遅延を補正し、キャラクターとの予測可能な動きを可能にすることもできると思います。

また、キャラクターの動きとキャラクターのアクション/反応を最優先にして重要でないデータを優先することで、ラグのあるプレイヤーでもラグをほとんど感じないようにすることができます。

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