アヒルのある日

株式会社AHIRUの社員ブログです。毎週更新!社員が自由に思いついたことを書きます。

通信対戦で送信データを最適化したい!

こんにちは、ちゃらいアヒルです。
今ではすっかり当たり前になりつつ通信対戦ですが、例えばプレイヤーの情報を全体へ送信する必要があるとき送信量が少なければ少ないほど良いとされています。
今回はよく知られているビットパッキングの方法を紹介したいと思います。

■ビットパッキングとは

ビット演算を用いて一つの値の中に複数の値を詰め込むこと

■例えば以下のプレイヤーパラメータを送信する場合

・種族 (最大15)
・状態異常 (最大7)
・レベル (最大99)
・HP (最大999)
・武器ID (最大255)

そのままint型で通信すると型情報を含めて25バイト必要ですが
・種族 - 必要なビット数4(0 ~ 15)
・状態異常 - 必要なビット数3(0 ~ 7)
・レベル - 必要なビット数7(0 ~ 127)
・HP - 必要なビット数10(0 ~ 1023)
・武器ID - 必要なビット数8(0 ~ 255)
のように扱える値の範囲をビット数で分割していくとちょうど合計32ビットになるので一つのint型 = 5バイトにすることができます。

まるでパズルみたいですね。。

最後にC#で記載すると以下のようなイメージです。

・プレイヤーパラメータを一つのint型に変換する関数
public int Serialize( int tribe, int badStatus, int level, int hp, int weaponId )
{
    return (tribe << 28) | (badStatus << 25) | (level << 18) | (hp << 8) | weaponId ;
}

・int型のデータをプレイヤーパラメータに変換する関数
public (int tribe, int badStatus, int level, int hp, int weaponId) Deserialize(int data)
{
    return (
        (data >> 28) & 0b_1111,
        (data >> 25) & 0b_111,
        (data >> 18) & 0b_111_1111,
        (data >>  8) & 0b_11_1111_1111,
        data  & 0b_1111_1111
    );
}

それではまた次回!