ネットコードの落とし穴 ― 静かに消えるメッセージ
マルチプレイのバグは、ちょっと特別な種類です。クラッシュもしないし、エラーも記録されません。ただ、何も起きないのです。自分たちのネットワークコードで出会った、お気に入りの落とし穴を二つ、注意喚起と読み物としてご紹介します。
落とし穴その1:登録されていないメッセージ。私たちのネットワークプロトコルには、「ブロックが変わった」「プレイヤーが動いた」「チャット」といったメッセージのクラスがあります。新しいメッセージの種類は、すべてコーデックに登録して、IDをもらい、シリアライズできるようにしなければなりません。これを忘れると、最悪のことが起きます。送信の呼び出しは失敗しているのに、そのエラーが黙って握りつぶされる場所で起きるのです。クラッシュもログもなく、機能がただ「動かない」。何度もこれでデバッグして、ついに反射的に身につきました。新しいメッセージクラスを作ったら、まず聞くことは「登録した?」です。
落とし穴その2:ゴーストブロック。サーバーがブロックを変えるとき(たとえばスクリプトが地形を作り変えるとき)、接続しているすべてのプレイヤーに自分から知らせる必要があります。ブロードキャストを忘れると、ゴーストブロックが生まれます。サーバーはそこにブロックがあると知っているのに、クライアントには空気しか見えません。プレイヤーは見えない壁にぶつかったり、もっと困ったことに、サーバー側にはもう存在しない場所に建物を建てたりします。チャンクを読み込み直して、やっと二つの世界が合います。
共通点は、マルチプレイには必ず二つの真実があるということです。サーバーのものと、クライアントのもの。そして、両方を同期させなければならない場所は、すべて落とし穴になりえます。私たちの答えは、まさにその同期をチェックするテストと、新しいメッセージ用のチェックリストでした。地味ですが、それ以来ゴーストはめったに出なくなりました。
コメント