Skip to content

Data types

Every entry in a save file is associated with a DataType that determines how its payload is laid out and interpreted. There are 33 types in total, numbered 0 through 32.

The entry table is a flat sequence of 8-byte (hash, slot) pairs. The hash field doubles as a discriminator:

  • hash != 0 - a data entry. slot is either the inline value (for inline scalars) or a byte offset into the heap region (for everything else), interpreted under the current DataType.
  • hash == 0 - a type sentinel. slot is itself a DataType value, and it sets the current type for every data entry that follows, until the next sentinel.

These types fit in the 4-byte inline slot of an entry. No separate payload is allocated.

tag = 0 - single byte interpreted as false when zero and true otherwise. Stored in the low byte of the inline slot.

tag = 2 - signed 32-bit integer, little-endian.

tag = 20 - unsigned 32-bit integer, little-endian.

tag = 4 - IEEE-754 binary32, little-endian. The inline slot holds the raw bits.

tag = 6 - unsigned 32-bit murmur3 hash of an enum value name. The set of accepted hashes for each field is listed on the Enums pages.

These types are too large for the inline slot and live in the payload region.

tag = 22 - signed 64-bit integer, little-endian, 8-byte payload.

tag = 24 - unsigned 64-bit integer, little-endian, 8-byte payload.

Packed sequences of 32-bit floats, little-endian, in payload.

tag = 8 - (x, y) as two float32 values. 8-byte payload.

tag = 10 - (x, y, z) as three float32 values. 12-byte payload.

Fixed-capacity UTF-8 byte buffers, NUL-terminated when shorter than the capacity. The number suffix is the buffer length in bytes.

tag = 12 - up to 16 bytes of UTF-8.

tag = 14 - up to 32 bytes of UTF-8.

tag = 16 - up to 64 bytes of UTF-8.

Fixed-capacity UTF-16LE buffers, NUL-terminated when shorter than the capacity. The number suffix is the buffer length in UTF-16 code units, so each holds twice as many bytes as the suffix suggests.

tag = 26 - up to 16 UTF-16 code units (32 bytes).

tag = 28 - up to 32 UTF-16 code units (64 bytes).

tag = 30 - up to 64 UTF-16 code units (128 bytes).

tag = 18 - arbitrary byte buffer of variable length. The container records the byte count; the interpretation is per-field.

Array types share tag = scalar_tag + 1. Each is encoded as a 4-byte little-endian count followed by tightly-packed elements in the same layout as the scalar form, with the exception of BoolArray (see below). Strings inside an array still use their full fixed capacity.

tag = 1 - bit-packed array of Bool. Stored as ⌈count / 8⌉ bytes (minimum 4) after the count, rounded up to a multiple of 4.

tag = 3 - array of Int.

tag = 21 - array of UInt.

tag = 5 - array of Float.

tag = 7 - array of Enum hashes.

tag = 23 - array of Int64.

tag = 25 - array of UInt64.

tag = 9 - array of Vector2.

tag = 11 - array of Vector3.

tag = 13 - array of String16. Each element occupies 16 bytes.

tag = 15 - array of String32. Each element occupies 32 bytes.

tag = 17 - array of String64. Each element occupies 64 bytes.

tag = 27 - array of WString16. Each element occupies 32 bytes.

tag = 29 - array of WString32. Each element occupies 64 bytes.

tag = 31 - array of WString64. Each element occupies 128 bytes.

tag = 19 - array of Binary buffers. Each element is preceded by its own 4-byte length.

tag = 32 - a type carried over from the underlying save framework, not used as a schema field type by Tomodachi Life. GameDataList.Product.100.byml declares zero Bool64bitKey fields. The only entries the game writes in this section are one per save file, whose hash is murmur3(file_name) (Player -> 0x08b37691, Mii -> 0x5917a80c, Map -> 0x441c30df), with slot = 0 and no heap payload.