-
Notifications
You must be signed in to change notification settings - Fork 2
Open Binary Format
OBF is a binary format that aims at storing data in a compact way that is also version-compatible.
That means that if in a version an item has one property called "type" and in the next version the property "amount" is added, the first version should be loaded correctly anyway.
Same thing with removal and such.
The easiest way to use this (for the user point of view) is to store data as like a map with the names as keys, the data will be stored keeping the names, and when the data is then re-loaded the developer will do a name lookup to find the saved values.
You can think of this as like a simplified version of an xml or yaml document, but stored in binary.
There may be different versions, for now there's only one.
The beginning is a map of '\0'
ended utf-8 strings mapped (followed by) a byte indicating the data type and a variable numbers of bytes that indicate the type.
Example:
+----------+-------+---------+
Field: | Name | Type | Payload |
Content: | "amount" | int_8 | 64 |
Size: | 7B | 1B | 1B |
+----------+-------+---------+
There are 16 types that can be used:
- int_8
- int_16
- int_32
- int_64
- float_32
- float_64
- string #
'\0'
termined - section # Another string-keyed map
- array_int_8
- array_int_16
- array_int_32
- array_int_64
- array_float_32
- array_float_64
- array_string # Array of
'\0'
termined strings - array_section # Array of string-keyed map
A limitation of this design is that you cannot create nested arrays, but you can simulate them using sections
The section has a varint to indicate the number of elements contained.
All the array types have a varint before their elements to indicate the how many elements it contains.
As every section in this version the root section must have a varint indicating the number of entries before the rest of the data.
{ entries: 4
"id": int_32(314),
"name": string("paolo"),
"age": int_8(17),
"items": array_section( length: 3;
{ entries: 2;
"type": string("diamond"),
"amount": int_8(32),
},
{ entries: 1;
"type": string("pickaxe"),
},
{ entries: 2;
"type": string("dirt"),
"amount": int_8(53),
},
)
}
in hexadecimal bytes:
696400 03 0000013A # "id" + int_32 + 314
6E616D6500 06 70616F6C6F00 # "name" + string + "paolo"
61676500 00 11 # "age" + int_8 + 17
6974656D7300 0F 03 # +"items" + array_section + 3
02 # |+entries: 2
7479706500 06 6469616D6F6E6400 # ||"type" + string + "diamond"
616D6F756E7400 00 20 # ||"amount" + int_8 + 32
01 # |+entries: 1
7479706500 06 7069636B61786500 # ||"type" + string + "pickaxe"
02 # |+entries: 2
7479706500 06 6469727400 # ||"type" + string + "dirt"
616D6F756E7400 00 35 # ||"amount" + int_8 + 53