6

私はQuake 2から大まかに派生したゲームエンジンに取り組んでおり、スクリプト化された効果のようなものを追加しています(クライアントが可能な限られた数のハードコードされた効果のみを持つのではなく、サーバーがクライアントに詳細に特殊効果を指定できるようにします) of.) これは、ネットワーク効率と柔軟性のトレードオフです。

面白い壁にぶち当たりました。最大パケット サイズは 2800 バイトで、フレームごとにクライアントごとに 1 つのみ送信できます。

「火花」エフェクトを実行するスクリプトは次のとおりです (弾丸の衝突火花、電気ショックなどに適しています) http://pastebin.com/m7acdf519 (理解できない場合は、気にしないでください。これは私が作成したカスタム構文であり、私が求めている質問には関係ありません.)

そのスクリプトのサイズを縮小するために可能な限りのことをしました。変数名も 1 文字に減らしました。しかし、結果はちょうど 405 バイトです。つまり、フレームごとに最大 6 個のこれらを収めることができます。また、サーバー側の変更でさらに 12 削減できる可能性があることと、プロトコルの変更でさらに 6 削減できる可能性があることも念頭に置いています。ただし、どのスクリプトを使用しているかによって、節約できる量は異なります。

ただし、これらの 387 バイトのうち、41 バイトだけが効果の複数の使用法の間で一意であると推定されます。つまり、これは圧縮の最有力候補です。

R1Q2 (拡張ネットワーク プロトコルを備えた後方互換性のある Quake 2 エンジン) に Zlib 圧縮コードが含まれているのはたまたまです。私はこのコードを持ち上げるか、少なくとも参照として厳密に従うことができます。

しかし、ここでは Zlib が必ずしも最良の選択でしょうか? 少なくとも 1 つの代替手段、LZMA を思いつくことができます。

要求事項:

  1. 非常に高速である必要があります (1 秒間に 100 回以上実行した場合、パフォーマンスへの影響が非常に小さい必要があります)。
  2. できるだけ多くのデータを 2800 バイトに詰め込む必要があります
  3. メタデータのフットプリントが小さい
  4. GPL互換

Zlib は良さそうですが、もっと良いものはありますか? このコードはまだマージされていないため、実験の余地が十分にあることに注意してください。

ありがとう -マックス

編集:スクリプトをバイトコードにコンパイルすることを提案した人に感謝します。私はこれを明確にするべきでした--はい、私はこれを行っています。必要に応じて、私の Web サイトで関連するソース コードを閲覧できますが、まだ「きれいに」作成されていません。
これはサーバー側のコードです:
Lua コンポーネント: http://meliaserlow.dyndns.tv:8000/alienarena/lua_source/lua/scriptedfx.lua
C コンポーネント: http://meliaserlow.dyndns.tv:8000/alienarena/lua_source /game/g_scriptedfx.c
私が投稿した特定のサンプル スクリプトの場合、これは 1172 バイトのソースを 405 バイトに減らしますが、それでも十分小さくはありません。(これらをできるだけ多く 2800 バイトに収めたいことに注意してください!)

EDIT2: 特定のパケットが到着するという保証はありません。各パケットには、以前のパケットで伝達された情報に依存することなく、「世界の状態」が含まれていると想定されています。通常、これらのスクリプトは「見栄え」を伝えるために使用されます。1 つの余地がない場合、パケットからドロップされますが、それは大したことではありません。しかし、あまりにも多くのドロップが発生すると、見た目がおかしくなり始めます。これは望ましくありません。

4

6 に答える 6

4

LZOはこれに適した候補かもしれません.

于 2010-02-17T10:05:11.507 に答える
2

最終更新: 2 つのライブラリはほぼ同等のようです。Zlib は約 20% 優れた圧縮を提供し、LZO のデコード速度は約 2 倍高速ですが、どちらのパフォーマンスへの影響も非常に小さく、ほとんど無視できます。それが私の最終的な答えです。他のすべての回答とコメントに感謝します!

更新: LZO 圧縮を実装し、パフォーマンスがわずかに向上しただけであることがわかりましたが、パフォーマンス ヒットの原因が自分のコードにあることは明らかです (パケットごとに可能なスクリプト化されたエフェクトの数が大幅に増加したため、エフェクトの「インタープリター」がより多く実行されます)。 .) 責任を転嫁したことを謹んでお詫び申し上げます。私はいくつかのプロファイリングを行い、他の誰かにとってより役立ついくつかの数値を取得できるかもしれません.

元の投稿:

OK、ようやくこのためのコードを書くことができました。私は Zlib から始めました。これが最初の調査結果です。

Zlib の圧縮は非常に優れています。(Z_DEFAULT_COMPRESSIONの代わりに)Z_BEST_SPEEDで圧縮した場合でも、たとえば8.5 kibのパケットをたとえば750バイト以下に確実に削減しています。圧縮時間もかなり良好です。

しかし、解凍速度がこれほど悪いとは思いもしませんでした。実際の数値はわかりませんが、少なくともパケットあたり 1/8 秒かかっているはずです! (Core2Duo T550 @ 1.83 Ghz) まったく受け入れられません。

私が聞いたところによると、LZMA は、Zlib と比較した場合のパフォーマンスの低下と圧縮の向上のトレードオフです。Zlib の圧縮はすでに過剰であり、そのパフォーマンスはすでに信じられないほど悪いため、LZMA は今のところ目に見えないため、検討の余地がありません。

LZO の減圧時間が主張されているほど優れている場合は、それを使用します。最終的にサーバーは極端な場合でも Zlib パケットを送信できると思いますが、クライアントはそれらを無視するように構成でき、それがデフォルトになります。

于 2010-02-22T05:19:53.163 に答える
1

OpenTNLを見て、Network Strings の概念のように、そこで使用されているテクニックのいくつかを適応させる必要があります。

于 2010-02-17T17:49:57.140 に答える
1

zlibは良い候補かもしれません。ライセンスは非常に優れており、高速に動作し、その作成者によると、オーバーヘッドはほとんどなく、オーバーヘッドは少量のデータを使用する際に問題となるものです。

于 2010-02-17T10:11:23.057 に答える
0

現在無駄になっている各文字の最上位ビットを使用する傾向があります。9 バイトのグループを左にシフトすると、8 バイトに収まります。

さらに進んで、文字を小さなスペースにマップすることもできます。たとえば、大文字を許可せず、各文字から 0x20 を差し引いて (スペースが値になるように)、6 ビット (つまり、有効な文字は 64 文字のみ) にできますか? 0 )

各文字の頻度をマッピングし、ハフマン型の圧縮を行って、各文字の平均数ビットを減らすことで、さらに進むことができます。

一般的なケースでは、すでに行った変更後にメッセージに冗長性が本質的にないため、データを保存するアルゴリズムはこれ以上優れていないと思います。

于 2010-02-17T10:19:47.517 に答える
0

スクリプトのバイナリ表現を送信するのはどうですか?

だから私は、各手続きが識別子を持つ抽象構文木の行で考えています。

これは、1 回の解析によるクライアントのパフォーマンスの向上と、メソッド名の削除によるサイズの縮小を意味します。

于 2010-02-17T10:26:07.903 に答える