Discovering the DZE format
Last evening I decided to nose around the DZE file format, generated by the venerable DayZ Editor. The DZE format is the "native" save file format of the editor, and is the usual output as well. The recommended way of using edits from the editor is to load files in this format with a special mod.
It is, to the best of my knowledge, a bespoke format. It may be documented somewhere online, and it could be reverse engineered from the mod (or better, the loader mod), but I wanted to take a stab at it going in blind. As I poked around the format I kept a running stream-of-conciousness document open. This post is that document, tidied up to make it understandable from outside my head.
The Setup
I needed some small, sample files, so I fired up editor and made three. On one I placed a single tree. The second was the same tree, but I ticked all the checkboxes in the properties. The final one was deleting a single tree.
To help, I recorded some values from the editor itself. For the add_tree.dze I got the object classname (bldr_plnt_t_malusDomestica_3s_summer), the position (4134.939, 223.920, 10927.966) and the orientation (99.00, 1.23, 4.56). For delete.dze I didn't grab the position or orientation (I probably should have), only the classname, (TreeHard_t_populusNigra_3sb_summer)
Getting Started
The first thing I did was just hex dump one to see what there was to see.
$ hexyl add_tree.dze
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 0c 00 00 00 45 64 69 74 ┊ 6f 72 42 69 6e 6e 65 64 │_⋄⋄⋄Edit┊orBinned│
│00000010│ 08 00 00 00 05 00 00 00 ┊ 45 6e 6f 63 68 03 00 00 │•⋄⋄⋄•⋄⋄⋄┊Enoch•⋄⋄│
│00000020│ 00 dd 8b 81 45 82 a3 5d ┊ 43 73 da 2a 46 11 00 00 │⋄×××E××]┊Cs×*F•⋄⋄│
│00000030│ 00 37 36 35 36 31 31 39 ┊ 38 30 34 33 38 34 31 30 │⋄7656119┊80438410│
│00000040│ 35 30 01 00 00 00 11 00 ┊ 00 00 37 36 35 36 31 31 │50•⋄⋄⋄•⋄┊⋄⋄765611│
│00000050│ 39 38 30 34 33 38 34 31 ┊ 30 35 30 e6 a4 90 6a e6 │98043841┊050×××j×│
│00000060│ a4 90 6a 01 00 00 00 24 ┊ 00 00 00 62 6c 64 72 5f │××j•⋄⋄⋄$┊⋄⋄⋄bldr_│
│00000070│ 70 6c 6e 74 5f 74 5f 6d ┊ 61 6c 75 73 44 6f 6d 65 │plnt_t_m┊alusDome│
│00000080│ 73 74 69 63 61 5f 33 73 ┊ 5f 73 75 6d 6d 65 72 24 │stica_3s┊_summer$│
│00000090│ 00 00 00 62 6c 64 72 5f ┊ 70 6c 6e 74 5f 74 5f 6d │⋄⋄⋄bldr_┊plnt_t_m│
│000000a0│ 61 6c 75 73 44 6f 6d 65 ┊ 73 74 69 63 61 5f 33 73 │alusDome┊stica_3s│
│000000b0│ 5f 73 75 6d 6d 65 72 03 ┊ 00 00 00 83 37 81 45 a2 │_summer•┊⋄⋄⋄×7×E×│
│000000c0│ eb 5f 43 dd bf 2a 46 03 ┊ 00 00 00 b0 00 c6 42 a3 │×_C××*F•┊⋄⋄⋄×⋄×B×│
│000000d0│ 70 9d 3f 84 eb 91 40 00 ┊ 00 80 3f 1e 00 00 00 00 │p×?×××@⋄┊⋄×?•⋄⋄⋄⋄│
│000000e0│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 01 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄•⋄⋄⋄⋄│
│000000f0│ 00 00 00 33 00 00 00 64 ┊ 7a 5c 70 6c 61 6e 74 73 │⋄⋄⋄3⋄⋄⋄d┊z\plants│
│00000100│ 5f 62 6c 69 73 73 5c 74 ┊ 72 65 65 5c 74 5f 6d 61 │_bliss\t┊ree\t_ma│
│00000110│ 6c 75 73 64 6f 6d 65 73 ┊ 74 69 63 61 5f 33 73 5f │lusdomes┊tica_3s_│
│00000120│ 73 75 6d 6d 65 72 2e 70 ┊ 33 64 00 00 00 00 00 00 │summer.p┊3d⋄⋄⋄⋄⋄⋄│
│00000130│ 00 00 00 00 00 00 ┊ │⋄⋄⋄⋄⋄⋄ ┊ │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
Well, some things jump right out, don't they? First off, lots of ASCII strings in there. A couple are obvious, EditorBinned looks like a marker for the format, Enoch is the name of the DayZ mission (that's the name of Livonia), and I can see the classname of the tree I deleted, as well as a reference to the 3D model (...summer.p3d)
A less obvious string is 76561198043841050. I only recognize that because I see it somewhat regularly, it's my Steam ID.
Before each string there is a pattern, XX 00 00 00. This looks like a length encoding; so a string entry would be an integer "how long is the string" and then the string bytes. At four bytes, it's probably a little endian uint32, and if we check them, it does match up: 0x0c == 12 == len("EditorBinned").
With that sorted, our format looks like this:
┏━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃00000000│ 0c 00 00 00 ┊ │x⋄⋄⋄ ┊ │ String Length ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000004│ 45 64 69 74 6f 72 42 69 ┊ 6e 6e 65 64 │EditorBi┊nned │ String ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000016│ 08 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000020│ 05 00 00 00 ┊ │x⋄⋄⋄ ┊ │ String Length (Map) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000024│ 45 6e 6f 63 68 ┊ │Enoch ┊ │ String (Map) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000029│ 03 00 00 00 dd 8b 81 45 ┊ 82 a3 5d 43 73 da 2a 46 │x⋄⋄⋄xxxE┊xx]Csx*F│ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000045│ 11 00 00 00 ┊ │x⋄⋄⋄ ┊ │ String Length (Steam ID) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000049│ 37 36 35 36 31 31 39 38 ┊ 30 34 33 38 34 31 30 35 │76561198┊04384105│ String (Steam ID) ┃
┃00000065│ 30 ┊ │0 ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000066│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000070│ 11 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Length (Steam ID Again) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000074│ 37 36 35 36 31 31 39 38 ┊ 30 34 33 38 34 31 30 35 │76561198┊04384105│ String (Steam ID Again) ┃
┃00000090│ 30 ┊ │0 ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000091│ e6 a4 90 6a e6 a4 90 6a ┊ 01 00 00 00 │xxxjxxxj┊x⋄⋄⋄ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000103│ 24 00 00 00 ┊ │$⋄⋄⋄ ┊ │ Length (Object Name) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000107│ 62 6c 64 72 5f 70 6c 6e ┊ 74 5f 74 5f 6d 61 6c 75 │bldr_pln┊t_t_malu│ String (Object Name) ┃
┃00000123│ 73 44 6f 6d 65 73 74 69 ┊ 63 61 5f 33 73 5f 73 75 │sDomesti┊ca_3s_su│ ┃
┃00000139│ 6d 6d 65 72 ┊ │mmer ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000143│ 24 00 00 00 ┊ │$⋄⋄⋄ ┊ │ Length (Object Name Again) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000147│ 62 6c 64 72 5f 70 6c 6e ┊ 74 5f 74 5f 6d 61 6c 75 │bldr_pln┊t_t_malu│ String (Object Name Again) ┃
┃00000163│ 73 44 6f 6d 65 73 74 69 ┊ 63 61 5f 33 73 5f 73 75 │sDomesti┊ca_3s_su│ ┃
┃00000179│ 6d 6d 65 72 ┊ │mmer ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000183│ 03 00 00 00 83 37 81 45 ┊ a2 eb 5f 43 dd bf 2a 46 │x⋄⋄⋄x7xE┊xx_Cxx*F│ Unknown ┃
┃00000199│ 03 00 00 00 b0 00 c6 42 ┊ a3 70 9d 3f 84 eb 91 40 │x⋄⋄⋄x⋄xB┊xpx?xxx@│ ┃
┃00000215│ 00 00 80 3f 1e 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄x?x⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ ┃
┃00000231│ 00 00 00 00 01 00 00 00 ┊ 00 00 00 00 │⋄⋄⋄⋄x⋄⋄⋄┊⋄⋄⋄⋄ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000243│ 33 00 00 00 ┊ │3⋄⋄⋄ ┊ │ Length (Model) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000247│ 64 7a 5c 70 6c 61 6e 74 ┊ 73 5f 62 6c 69 73 73 5c │dz\plant┊s_bliss\│ String (Model) ┃
┃00000263│ 74 72 65 65 5c 74 5f 6d ┊ 61 6c 75 73 64 6f 6d 65 │tree\t_m┊alusdome│ ┃
┃00000279│ 73 74 69 63 61 5f 33 73 ┊ 5f 73 75 6d 6d 65 72 2e │stica_3s┊_summer.│ ┃
┃00000295│ 70 33 ┊ │p3 ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000297│ 64 00 00 00 ┊ │d⋄⋄⋄ ┊ │ Unknown ┃
┗━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
How about those floats...
Ok, so that clears a lot out, but leaves a lot to decode. One thing we know should be in here are the position and orientation floats. I wrote a little Go to encode those so we know what to look for (sadly, I can't do IEEE 754 in my head);
package main
import (
"encoding/binary"
"os"
)
func main() {
f, err := os.Create("floats.bin")
if err != nil {
panic(err)
}
defer f.Close()
binary.Write(f, binary.LittleEndian, 4134.939)
f.Write([]byte{0, 0, 0, 0})
binary.Write(f, binary.LittleEndian, 223.920)
f.Write([]byte{0, 0, 0, 0})
binary.Write(f, binary.LittleEndian, 10927.966)
f.Write([]byte{0, 0, 0, 0})
binary.Write(f, binary.LittleEndian, 99.0)
f.Write([]byte{0, 0, 0, 0})
binary.Write(f, binary.LittleEndian, 1.23)
f.Write([]byte{0, 0, 0, 0})
binary.Write(f, binary.LittleEndian, 4.56)
f.Write([]byte{0, 0, 0, 0})
}
And the output...
$ hexyl floats.bin
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ f2 d2 4d 62 f0 26 b0 40 ┊ 00 00 00 00 3d 0a d7 a3 │××Mb×&×@┊⋄⋄⋄⋄=_××│
│00000010│ 70 fd 6b 40 00 00 00 00 ┊ f8 53 e3 a5 fb 57 c5 40 │p×k@⋄⋄⋄⋄┊×S×××W×@│
│00000020│ 00 00 00 00 00 00 00 00 ┊ 00 c0 58 40 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄×X@⋄⋄⋄⋄│
│00000030│ ae 47 e1 7a 14 ae f3 3f ┊ 00 00 00 00 3d 0a d7 a3 │×G×z•××?┊⋄⋄⋄⋄=_××│
│00000040│ 70 3d 12 40 00 00 00 00 ┊ │p=•@⋄⋄⋄⋄┊ │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
Well, none of that is in there. Not big endian either, since it's the same bytes, just in another order and, for instance, 0x6b isn't in the file at all.
After stewing for a bit I realized Go was encoding 64 bit floats, and this format (like many DayZ things) was almost certainly using 32 bit floats. I wrapped all my literals in float32() and ran it again, and there they all were, same as in the file.
$ hexyl floats.bin
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 83 37 81 45 00 00 00 00 ┊ 85 eb 5f 43 00 00 00 00 │×7×E⋄⋄⋄⋄┊××_C⋄⋄⋄⋄│
│00000010│ dd bf 2a 46 00 00 00 00 ┊ 00 00 c6 42 00 00 00 00 │××*F⋄⋄⋄⋄┊⋄⋄×B⋄⋄⋄⋄│
│00000020│ a4 70 9d 3f 00 00 00 00 ┊ 85 eb 91 40 00 00 00 00 │×p×?⋄⋄⋄⋄┊×××@⋄⋄⋄⋄│
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
Marking those out gets us this segment;
┏━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃00000183│ 03 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000187│ 83 37 81 45 ┊ │x7xE ┊ │ Position X ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000191│ a2 eb 5f 43 ┊ │xx_C ┊ │ Position Y ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000195│ dd bf 2a 46 ┊ │xx*F ┊ │ Position Z ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000199│ 03 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000203│ b0 00 c6 42 ┊ │x⋄xB ┊ │ Orientation X ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000207│ a3 70 9d 3f ┊ │xpx? ┊ │ Orientation Y ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000211│ 84 eb 91 40 ┊ │xxx@ ┊ │ Orientation Z ┃
┗━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
As a WAG, I'd say those 03 00 00 00 fields are a count of the coming float values, so we will assume that for now. Using this format, are there any other float-triplets in here that seem likely? Just one, near the top right after the map name. If we convert those bytes to floats, what would they be?
package main
import (
"encoding/binary"
"fmt"
)
func main() {
var x, y, z float32
binary.Decode([]byte{0xdd, 0x8b, 0x81, 0x45}, binary.LittleEndian, &x)
binary.Decode([]byte{0x82, 0xa3, 0x5d, 0x43}, binary.LittleEndian, &y)
binary.Decode([]byte{0x73, 0xda, 0x2a, 0x46}, binary.LittleEndian, &z)
fmt.Println(x, y, z)
}
$ go run main.go
4145.483 221.6387 10934.612
Those sure look like in game coordinates, and are very near our tree. Since these are in the "header" section of the file, I think it's probably the camera location at time of save, since I do know DayZ Editor stores that (you zoom to the camera location when loading a DZE file). No orientation though, which is interesting. Something to test and come back to later.
Vexillology
At this point, I had only a few points of data left; the flags I knew I toggled in add_tree_all_flags.dze I ran the current packet printer against both and compared the diff. These lines jumped out at obviously being flags;
64c64
< ┃00000227│ 00 00 00 00 ┊ │⋄⋄⋄⋄ ┊ │ Unknown ┃
---
> ┃00000227│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
66c66
< ┃00000231│ 00 00 00 00 ┊ │⋄⋄⋄⋄ ┊ │ Unknown ┃
---
> ┃00000231│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
70c70
< ┃00000239│ 00 00 00 00 ┊ │⋄⋄⋄⋄ ┊ │ Unknown ┃
---
> ┃00000239│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
I remember ticking more than three, but maybe they are not all things that get written to the save file? Either way, to classify exactly which is which. I'll have to generate new test files for each flag, something to pursue later.
Wait, why did that change?
The diff also showed some other changes. The position and orientation had changed, but that was expected because one of the tick boxes gave the tree physics and it fell over. The other change was more suspicious;
32c32
< ┃00000091│ e6 a4 90 6a e6 a4 90 6a ┊ 01 00 00 00 │xxxjxxxj┊x⋄⋄⋄ │ Unknown ┃
---
> ┃00000091│ fd a4 90 6a e6 a4 90 6a ┊ 01 00 00 00 │xxxjxxxj┊x⋄⋄⋄ │ Unknown ┃
It's up in the metadata/header area of the file, right after the second Steam ID value. Why would that change, but only a little bit?
Well, one obvious reason is perhaps a timestamp. This file was saved after the first add_tree.dze, so maybe it's a timestamp that updated? But 12 bytes is too big for a timestamp, what would that even unpack into? The 01 00 00 00 looks like another length one, so let's drop that and see what the top 8 bytes decodes to.
package main
import (
"encoding/binary"
"fmt"
)
func main() {
var t uint64
binary.Decode([]byte{
0xfd, 0xa4, 0x90, 0x6a,
0xe6, 0xa4, 0x90, 0x6a,
},
binary.LittleEndian,
&t,
)
fmt.Println(t)
}
$ go run main.go
7678818674203993341
Ok, that is way too big. Even assuming nanosecond precision, if that's a unix timestamp it's for the year 2213.
Looking at the diff again, I noticed on the first file it's the same 4 bytes twice. That'd be a wild coincidence for a timstamp, so what if it's actually two timestamps? Created and modified?
package main
import (
"encoding/binary"
"fmt"
)
func main() {
var ta, tb uint32
binary.Decode([]byte{
0xe6, 0xa4, 0x90, 0x6a,
},
binary.LittleEndian,
&ta,
)
binary.Decode([]byte{
0xfd, 0xa4, 0x90, 0x6a,
},
binary.LittleEndian,
&tb,
)
fmt.Println(ta, tb)
}
$ go run main.go
1787864294 1787864317
Well look at that, two timestamps, and they are even from today. That seems like a match!
Wrapping Up
At this point most of the file is accounted for, with some odds and ends remaining.
The 08 00 00 00 at the top is almost certainly a file version, I'll have to gather some old DZE files to know for sure.
We have a couple 01 00 00 00 left in as well, we will assume those are field counts similar to the 03 00 00 00 for the floats. We don't know what they do exactly, but they seem to be carrying information themselves. I think the one after the timestamps is probably a count of the object entries that follow.
The biggest unknown segment is the 00 00 80 3f 1e 00 00 00 00 00 00 00.
One thing I forgot to inject in my test files was a scale factor I could search for. The default scale it 1.00, so it should be in here somewhere. Encoded that is 00 00 80 3f, which we do have in that unknown section. Another one bytes the dust!
Wrapping it up here is the final format we have sniffed out.
┏━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃00000000│ 0c 00 00 00 ┊ │x⋄⋄⋄ ┊ │ String Length ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000004│ 45 64 69 74 6f 72 42 69 ┊ 6e 6e 65 64 │EditorBi┊nned │ String ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000016│ 08 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000020│ 05 00 00 00 ┊ │x⋄⋄⋄ ┊ │ String Length (Map) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000024│ 45 6e 6f 63 68 ┊ │Enoch ┊ │ String (Map) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000029│ 03 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Float32 Count ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000033│ dd 8b 81 45 ┊ │xxxE ┊ │ Camera Position X ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000037│ 82 a3 5d 43 ┊ │xx]C ┊ │ Camera Position Y ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000041│ 73 da 2a 46 ┊ │sx*F ┊ │ Camera Position Z ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000045│ 11 00 00 00 ┊ │x⋄⋄⋄ ┊ │ String Length (Steam ID) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000049│ 37 36 35 36 31 31 39 38 ┊ 30 34 33 38 34 31 30 35 │76561198┊04384105│ String (Steam ID) ┃
┃00000065│ 30 ┊ │0 ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000066│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000070│ 11 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Length (Steam ID Again) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000074│ 37 36 35 36 31 31 39 38 ┊ 30 34 33 38 34 31 30 35 │76561198┊04384105│ String (Steam ID Again) ┃
┃00000090│ 30 ┊ │0 ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000091│ e6 a4 90 6a ┊ │xxxj ┊ │ Timestamp (Modified) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000095│ e6 a4 90 6a ┊ │xxxj ┊ │ Timestamp (Created) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000099│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000103│ 24 00 00 00 ┊ │$⋄⋄⋄ ┊ │ Length (Object Name) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000107│ 62 6c 64 72 5f 70 6c 6e ┊ 74 5f 74 5f 6d 61 6c 75 │bldr_pln┊t_t_malu│ String (Object Name) ┃
┃00000123│ 73 44 6f 6d 65 73 74 69 ┊ 63 61 5f 33 73 5f 73 75 │sDomesti┊ca_3s_su│ ┃
┃00000139│ 6d 6d 65 72 ┊ │mmer ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000143│ 24 00 00 00 ┊ │$⋄⋄⋄ ┊ │ Length (Object Name Again) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000147│ 62 6c 64 72 5f 70 6c 6e ┊ 74 5f 74 5f 6d 61 6c 75 │bldr_pln┊t_t_malu│ String (Object Name Again) ┃
┃00000163│ 73 44 6f 6d 65 73 74 69 ┊ 63 61 5f 33 73 5f 73 75 │sDomesti┊ca_3s_su│ ┃
┃00000179│ 6d 6d 65 72 ┊ │mmer ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000183│ 03 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Float32 Count ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000187│ 83 37 81 45 ┊ │x7xE ┊ │ Position X ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000191│ a2 eb 5f 43 ┊ │xx_C ┊ │ Position Y ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000195│ dd bf 2a 46 ┊ │xx*F ┊ │ Position Z ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000199│ 03 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Float32 Count ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000203│ b0 00 c6 42 ┊ │x⋄xB ┊ │ Orientation X ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000207│ a3 70 9d 3f ┊ │xpx? ┊ │ Orientation Y ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000211│ 84 eb 91 40 ┊ │xxx@ ┊ │ Orientation Z ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000215│ 00 00 80 3f ┊ │⋄⋄x? ┊ │ Float (Scale) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000219│ 1e 00 00 00 00 00 00 00 ┊ │x⋄⋄⋄⋄⋄⋄⋄┊ │ Unknown ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000227│ 00 00 00 00 ┊ │⋄⋄⋄⋄ ┊ │ Flag ??? ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000231│ 00 00 00 00 ┊ │⋄⋄⋄⋄ ┊ │ Flag ??? ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000235│ 01 00 00 00 ┊ │x⋄⋄⋄ ┊ │ Flag ??? ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000239│ 00 00 00 00 ┊ │⋄⋄⋄⋄ ┊ │ Flag ??? ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000243│ 33 00 00 00 ┊ │3⋄⋄⋄ ┊ │ Length (Model) ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000247│ 64 7a 5c 70 6c 61 6e 74 ┊ 73 5f 62 6c 69 73 73 5c │dz\plant┊s_bliss\│ String (Model) ┃
┃00000263│ 74 72 65 65 5c 74 5f 6d ┊ 61 6c 75 73 64 6f 6d 65 │tree\t_m┊alusdome│ ┃
┃00000279│ 73 74 69 63 61 5f 33 73 ┊ 5f 73 75 6d 6d 65 72 2e │stica_3s┊_summer.│ ┃
┃00000295│ 70 33 ┊ │p3 ┊ │ ┃
┠┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┨
┃00000297│ 64 00 00 00 ┊ │d⋄⋄⋄ ┊ │ Unknown ┃
┗━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Next Steps
So what next? Well, more data is needed really. I need to attribute the flags we observed, figure out why steam ID is in there twice (my guess is creator and last editor), and figure out some of those length fields. Lastly is that long 1e 00... segment which I have no idea about, and the trailer 64 00....
Still, not bad for a first pass! At a minimum, we should be able to parse locations out of here, which we can use for....something!
I've got the beginnings of a decoder going on GitHub, and will update it as I learn more. If there's enough to be getting on with, maybe I'll write a follow up post.