reading the PRNT chunk
I felt like dropping a little guide on how to read the PRNT
chunk in an RBXM file, this is documented, however I’d felt like I’d showcase how to read it in a slightly different way.
This assumes you already know how RBXM stores Referent
and interleaving as a concept.
Lets assume we have a basic folder structure like this:
When this gets packed into the PRNT
chunk, it could look like this in HEX (uncompressed)
00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 04 02 03
08 01 04 02 0D 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 01
08 07 00 00 01
The first five bytes are just used to denote the version (always 00
) and the number of Refs in the PRNT
chunk. The remaining bytes are two arrays of referents.
While I haven’t observed this myself, it may be possible that multiple
PRNT
chunks could appear, since the chunk contains aReferent
count.
Once thats been deinterleaved and parsed, we’ll end up with two tables of Referent
types.
local child_refs = {2, 3, 1, 5, 4, 6, 7, 0}
local parent_refs = {1, 1, 0, 4, 0, 0, 0, -1}
Its worth noting that we should also map each Folder
above in the image to their Referent
ID.
Folder1 - 0
Folder2 - 1
Folder3 - 2
Folder4 - 3
Folder5 - 4
Folder6 - 5
Folder7 - 6
Folder8 - 7
An index in a child_ref
and parent_ref
table creates a link where
child_refs[i].Parent = parent_refs[i]
Or in another way, this can be visualised with a table like this:
child_ref | child_ref_instance | parent_ref | parent_ref_instance |
---|---|---|---|
0 |
Folder1 | -1 |
<<<ROOT>>> |
1 |
Folder2 | 0 |
Folder1 |
2 |
Folder3 | 1 |
Folder2 |
3 |
Folder4 | 1 |
Folder2 |
4 |
Folder5 | 0 |
Folder1 |
5 |
Folder6 | 4 |
Folder5 |
6 |
Folder7 | 0 |
Folder1 |
7 |
Folder8 | 0 |
Folder1 |
If a Referent
is < 0
then it should be parented to the root of the tree.
You can use a script like this to build the tree from these lists
for i = 1, count_of_refs do
local child_ref = child_refs[count_of_refs]
local parent_ref = child_refs[count_of_refs]
local child = referents[child_ref]
local parent = if parent_ref >= 0 then referents[parent_ref].Children or TREE_ROOT
table.insert(parent, child)
end