入力同期通信ゲーム開発時の参考情報ついて説明します。
同期通信を開始するタイミングでステーション間で状態が一致していない場合、同期ずれの原因となります。
同期通信のための処理は、全ステーションで状態が一致し、同期通信が可能な状態になってから行ってください。例えば、SyncProtocol::Start を呼ぶ前にゲームプレイに影響を与える処理が行われ、状態が一致しなくなると、同期ずれが起こることになります。
同期を終了するタイミング(フレーム番号)は、ステーション間で一致しないため、終了直前に送信された同期データは全てのステーションに受信されない可能性があります。受信されなかった同期データがゲームプレイに影響する場合、同期ずれの原因となります。
同期終了は、ゲームクリア直後ではなく、クリア後の画面演出の後に行うなど、全てのステーションで進行に必要な同期データの送受信を行う必要がなくなってから行ってください。または、同期データとして同期終了フレームを送受信し、各ステーションがゲーム中に使用する同期データの最終フレームを合わせてください。
各ステーションでゲームプレイに影響する乱数が異なっていると、同期ずれの原因となります。例えば、エフェクトはゲームプレイに影響しないことが多いですが、エフェクト処理のために乱数が使用され、乱数生成呼び出し回数がずれると同期ずれの原因となります。
乱数のシード値を同期開始前に共有するようにしてください。シード値を共有した上で、乱数生成が行われる順番と回数が各ステーションで一致している必要があります。
乱数生成の呼び出しは 1 つの関数に統一しておくことで、同期ずれ調査が行いやすくなります。例えば、調査時には乱数生成をやめて固定値を返す、などの対応が可能になります。また、「ゲームプレイに影響するようなケースで使用する乱数」と、それ以外の「ゲームプレイに影響のないケースで使用する乱数」を、それぞれ別の乱数生成器で生成するようにすることで、乱数生成呼び出し処理の管理がしやすくなり、問題が発生した時の原因が特定しやすくなります。
「非同期処理(リソースのロードなど)が終了次第、それを同期通信のゲームプレイに反映する」という処理があると、同期ずれの原因となります。
非同期処理の後、ゲームプレイに反映するタイミングを各ステーションで一致させるようにしてください。
各ステーションで表示される画面が異なり、カリングによって各ステーションで計算されるオブジェクトやその挙動が異なると、挙動のずれや乱数生成呼び出し回数のずれによって同期ずれの原因となります。
各ステーションで計算されるオブジェクトが一致するようにしてください。
「所持しているアイテムを使用する」、「過去に倒した敵の数が 100 体超えるとアイテムが出現する」などの要素がある場合、同期ずれの原因となります。
「所持しているアイテム」、「過去に倒した敵の数」などのプレイヤー情報を各ステーションが同期通信開始前に共有するようにしてください。
「BGM のタイミングに合わせて敵の挙動を変化させる」、「BGM のある特定の部分である動作をすると特殊な効果がある」などの処理がある場合、BGM のストリーミング再生の同期が取れなければ、同期ずれの原因となります。
セッションホストの BGM トリガーを同期データとし、セッションクライアントはその BGM トリガーを使用して処理を行う等の対策を行ってください。
同期ずれが起きた時にステーション間で値が一致しなくなりやすい情報(プレイヤーの位置、ボールの位置など)を同期データとして送り合い、全ステーションのデータが一致しているかチェックすることで同期ずれを検知しやすくなります。その分、通信量が大きくなり、フレームドロップしやすくなるのでデバッグ時のみ使用してください。
上記の同期ずれ検知機能の実装が難しい場合、画面にフレーム値と同期データを表示することで、同期ずれが起きたタイミングが確認しやすくなります。複数のステーションのゲーム画面を録画し、両方の画面を見比べていくことで同期ずれが起きたタイミングがわかり、原因が特定しやすくなります。