void WriteField(DatWriter w, JField field)
        {
            w.WriteUInt8((byte)field.type);
            w.WriteUtf8(field.field);

            if (field.klass == null)
            {
                return;
            }
            w.WriteUInt8(TC_STRING);
            w.WriteUtf8(field.klass);
        }
        void WriteClassDesc(DatWriter w, string klass, JField[] fields)
        {
            // Write serialised Level Object
            w.WriteUInt8(TC_CLASSDESC);
            w.WriteUtf8(klass);
            w.WriteInt32(0); w.WriteInt32(0);          // serialUUID
            w.WriteUInt8(SC_SERIALIZABLE);             // SC_SERIALIZABLE

            w.WriteUInt16((ushort)fields.Length);
            foreach (JField field in fields)
            {
                WriteField(w, field);
            }

            w.WriteUInt8(TC_ENDOFBLOCKDATA);   // classAnnotations
            w.WriteUInt8(TC_NULL);             // superClassDesc
        }
        void WriteValue(DatWriter w, JField field)
        {
            switch (field.type)
            {
            case 'I':
                w.WriteInt32((int)field.value);
                break;

            case '[':
                w.WriteUInt8(TC_ARRAY);
                WriteClassDesc(w, "[B", new JField[0]);
                w.WriteInt32(((byte[])field.value).Length);
                //w.WriteBytes((byte[])field.value);
                // NOTE: need to convert since level might have blocks that don't exist in classic
                WriteLevelBlocks(w.dst, (byte[])field.value);
                break;

            default:
                throw new InvalidOperationException("Can't write fields of type " + field.type);
            }
        }
        public override void Write(Stream dst, Level lvl)
        {
            JField[] fields = GetFields(lvl);

            using (Stream s = new GZipStream(dst, CompressionMode.Compress))
            {
                DatWriter w = new DatWriter();
                w.dst = new BinaryWriter(s);

                w.WriteInt32(DAT_SIGNATURE);
                w.WriteUInt8(DAT_VERSION);

                w.WriteUInt16(JSF_SIGNATURE);
                w.WriteUInt16(JSF_VERSION);

                // Write serialised Level Object
                w.WriteUInt8(TC_OBJECT);
                WriteClassDesc(w, "com.mojang.minecraft.level.Level", fields);
                foreach (JField field in fields)                 // classData
                {
                    WriteValue(w, field);
                }
            }
        }