ゲームラグ白書 › 一部のユーザーだけに起きる問題
入場直後に集中する出現情報の欠落 Initial spawn burst lost (unreliable channel, receive buffer, fragmentation)
原因ID pt-spawn-burst · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
図と実験のあるメインページでこのカードを開く →
ゾーンに入った瞬間、サーバーは周囲の数十〜数百個のオブジェクトの出現情報を一気に送ります。これを非信頼(unreliable)チャネルで送ったり、ロード中でソケットを読めない間に受信バッファがあふれたりすると、一部が消えて二度と届きません。
なぜ 入場直後に出現情報が短時間に集中して届く → すると ロード中のクライアントがソケットを読むのが遅れてOSの受信バッファがあふれるか、大きなUDPパケットがフラグメント化され、フラグメントを1つ失っただけで丸ごと消える。非信頼チャネルなら再送もされない → 画面では ロードが遅い側のクライアントでだけNPCが数体抜ける。視界から外れて戻ると見える
- 症状
- 表示されない・ゴースト
- 要因
- パケットロス
- 誰に起きるか
- 同じPCの片方のクライアントだけ, 自分だけ
- いつ
- 接続直後・メンテ明け, 移動中・マップ切り替え時
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
- ゲーム開発チームの対応
- サーバー:出現・消滅通知は必ず再送が保証される信頼チャネルで送る、初期情報は分割して送る。クライアント:受信はロードとは別のスレッドで行う、受信バッファのサイズを増やす。
- 数値の目安
- PCのUDP受信バッファのデフォルト値はOSによって違いますが、たいてい数十〜数百KBです。人の多い町の入場情報がこれより大きいと、ロードのせいでソケットを少し読めないだけであふれます。
- グラフでは
- 接続直後・メンテ明けに急増 · 入場直後の受信量、出現通知の欠落数
- 確認箇所
- サーバーが入場直後に送った出現通知の数とクライアントが受け取った数を比較し、どのチャネル(信頼・非信頼)で送ったかを確認。サーバー側のパケットキャプチャで、入場直後にそのユーザーに送った量とフラグメント化されたパケット(Wiresharkのフィルター:ip.flags.mf == 1 || ip.frag_offset > 0)を確認
- 該当する場合
- 受け取った数が送った数より少なく、抜けたものが入場直後の集中区間に固まっており、非信頼チャネルで送ったか、大きなパケットがフラグメント化されている。ロードが遅い側のクライアントでより頻繁に起きる
- 該当しない場合
- 送った数と受け取った数が同じなのに表示されないなら、受け取った後に破棄した(ロード中に届いた出現通知の破棄)か、視界計算の問題。入場直後に関係なく随時抜けるなら、回線のパケットロス
- 確認手段
- ゲームサーバー・クライアントのログ・メトリクスが必要
出典
- RFC 8085: UDP Usage Guidelines IETF
フラグメント化されたパケットは、フラグメントを1つ失っただけで丸ごと消える - UDP vs. TCP Gaffer On Games
UDPは到達・順序を保証しないため、失ったパケットは自分で検知して再送する必要がある - Socket.ReceiveBufferSize Property Microsoft
ソケットの受信バッファのデフォルトサイズはOSによって違う - Display Filter Reference: Internet Protocol Version 4 Wireshark
ip.flags.mf(More fragments)・ip.frag_offset(Fragment Offset)でフラグメント化されたIPパケットを絞り込む
あわせて読みたい原因
同じ層:一部のユーザーだけに起きる問題
同じ症状(表示されない・ゴースト)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る