Skip to content

Save File Format

Antonio edited this page Oct 24, 2021 · 14 revisions

All save files (except for baked stuff) will be exported as a JSON derivative. This derivative allows for pointers and typed arrays; plus more clarity about the type.

The changes to usual JSON include:

  • All objects need to have the "class" property as their first property, if not already specified

  • Property names other than "class" need to specify the type of data, in the format type:name

  • Objects have an UUID attribute as pointer

  • Properties may be pointers to objects; those objects can appear anywhere in the file

  • Arrays of all types start with the size as the first element, so it can be allocated with the correct size from the start when deserializing.

Example:

[
   {
      "class":"SMap",
      "l:uuid":1,
      "S:notice":"#thisIsJSON",
      "S:ffmpegPath":"ffmpeg\\bin\\ffmpeg.exe",
      "S:style":"dark"
   }
]

Property Types:

Type Meaning
b, i1 boolean, true or false
B, i8 8 bit int, byte
s, i16 16 bit int, short
i, i32 32 bit int, int
l, i64, u64 64 bit int, long
f, f32 32 bit float, float
d, f64 64 bit float, double
c 16 bit UTF-16 char (Java style)
S String, UTF-8, including Smileys
R File Reference, saved as UTF-8 string
v2, v3, v4 Vectors with f32 coordinates
v2d, v3d, v4d Vectors with f64 coordinates
q4, q4d Quaternions with f32/f64 coordinates
m3x3, m4x3, m4x4 Matrix formats, with mx, saved in column order
AABBf, AABBd Axis aligned bounding boxes with f32/f64 coordinates
SMap Mapping from Strings to anything
Keyframe A keyframe, contains a time (float) and a value (any)
Transform 3D folder, base class for all 3D objects
Text 3D Text element
Circle 3D Circle element
Polygon 3D Polygon element
Image 3D Image element
Audio 3D Audio element
Video 3D Video element, inherits from Audio
Cubemap Cubemap element
Mesh Mesh element
MaskLayer Masked element with special shaders
GFXArray Array element, copying its children
Timer Timer element

There probably are more types than this; the properties and the name will give you insights about their meaning :). If there are important types to be known, and not included here, write me, and I'll add them. For most types, [] or [][] can be appended for 1d and 2d arrays respectively.

Implementation

The IO is implemented in me.anno.io in Saveable.kt, base.BaseReader.kt, text.TextReader.kt and text.TextWriter.kt . All objects, which want to be serialized, need to inherit from the interface ISaveable.kt, but I recomment to implement from the class Saveable.

When a property is read, readTYPE(name, value) is called (read in past tense). When reading starts, onReadingStarted() is called, onReadingEnded() at the end.

The method save(writer: BaseWriter) is for serialization. When serializing an object, the caller must be specified (or null), to hint the size of objects to avoid deeply nested objects.

String getClassName() must return the unique class name. Your module needs to register custom classes in ISaveable.registerCustomClass(). Use prefixes if you are developing mods to avoid ambiguities.

int getApproxSize() should be static for a class; having the same or lower score than the predecessor prevents deep nesting.

Binary Format

There also is a binary format, but currently, with small sized arrays, the binary format isn't really worth the worse debuggability. It is implemented in me.anno.io.binary.

Clone this wiki locally