void ParseBlockDefinition(NbtCompound compound)
        {
            byte      id   = (byte)compound["ID"].Value;
            BlockInfo info = game.BlockInfo;

            info.Name[id]            = (string)compound["Name"].Value;
            info.CollideType[id]     = (BlockCollideType)compound["CollideType"].Value;
            info.SpeedMultiplier[id] = (float)compound["Speed"].Value;

            byte[] data = (byte[])compound["Textures"].Value;
            info.SetTex(data[0], TileSide.Top, (Block)id);
            info.SetTex(data[1], TileSide.Bottom, (Block)id);
            info.SetTex(data[2], TileSide.Left, (Block)id);
            info.SetTex(data[3], TileSide.Right, (Block)id);
            info.SetTex(data[4], TileSide.Front, (Block)id);
            info.SetTex(data[5], TileSide.Back, (Block)id);

            info.BlocksLight[id] = (byte)compound["TransmitsLight"].Value == 0;
            byte soundId = (byte)compound["WalkSound"].Value;

            info.DigSounds[id]  = NetworkProcessor.breakSnds[soundId];
            info.StepSounds[id] = NetworkProcessor.stepSnds[soundId];
            info.FullBright[id] = (byte)compound["FullBright"].Value != 0;
            info.IsSprite[id]   = (byte)compound["Shape"].Value == 0;
            NetworkProcessor.SetBlockDraw(info, id, (byte)compound["BlockDraw"].Value);

            data = (byte[])compound["Fog"].Value;
            info.FogDensity[id] = (data[0] + 1) / 128f;
            info.FogColour[id]  = new FastColour(data[1], data[2], data[3]);

            data           = (byte[])compound["Coords"].Value;
            info.MinBB[id] = new Vector3(data[0] / 16f, data[1] / 16f, data[2] / 16f);
            info.MaxBB[id] = new Vector3(data[3] / 16f, data[4] / 16f, data[5] / 16f);

            if (info.CollideType[id] != BlockCollideType.Solid)
            {
                info.IsTransparent[id] = true;
                info.IsOpaque[id]      = false;
            }
            info.SetupCullingCache(id);
            info.InitLightOffsets();
            game.Events.RaiseBlockDefinitionChanged();
            info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));

            game.Inventory.CanPlace.SetNotOverridable(true, id);
            game.Inventory.CanDelete.SetNotOverridable(true, id);
            game.Events.RaiseBlockPermissionsChanged();
        }
        byte HandleCpeDefineBlockCommonStart(bool uniqueSideTexs)
        {
            byte      block = reader.ReadUInt8();
            BlockInfo info  = game.BlockInfo;

            info.ResetBlockInfo(block, false);

            info.Name[block]        = reader.ReadAsciiString();
            info.CollideType[block] = (BlockCollideType)reader.ReadUInt8();
            if (info.CollideType[block] != BlockCollideType.Solid)
            {
                info.IsTransparent[block] = true;
                info.IsOpaque[block]      = false;
            }

            info.SpeedMultiplier[block] = (float)Math.Pow(2, (reader.ReadUInt8() - 128) / 64f);
            info.SetTex(reader.ReadUInt8(), TileSide.Top, (Block)block);
            if (uniqueSideTexs)
            {
                info.SetTex(reader.ReadUInt8(), TileSide.Left, (Block)block);
                info.SetTex(reader.ReadUInt8(), TileSide.Right, (Block)block);
                info.SetTex(reader.ReadUInt8(), TileSide.Front, (Block)block);
                info.SetTex(reader.ReadUInt8(), TileSide.Back, (Block)block);
            }
            else
            {
                info.SetSide(reader.ReadUInt8(), (Block)block);
            }
            info.SetTex(reader.ReadUInt8(), TileSide.Bottom, (Block)block);

            info.BlocksLight[block] = reader.ReadUInt8() == 0;
            byte sound = reader.ReadUInt8();

            if (sound < breakSnds.Length)
            {
                info.StepSounds[block] = stepSnds[sound];
                info.DigSounds[block]  = breakSnds[sound];
            }
            info.FullBright[block] = reader.ReadUInt8() != 0;
            return(block);
        }