Quick answer: GameMaker buffer_write(buf, buffer_string, "Hello") behaving differently than buffer_text? buffer_string writes the bytes plus a null terminator. buffer_text writes only the bytes.

A save format mixes buffer_string and buffer_text; reading produces corrupted data.

Match Read and Write Type

Always use the same constant for both sides. If you write buffer_string, read buffer_string. The terminator presence must match.

Length-Prefixed Pattern

// write
buffer_write(buf, buffer_u16, string_length(s));
buffer_write(buf, buffer_text, s);
// read
var n = buffer_read(buf, buffer_u16);
var s = buffer_read_text(buf, n);

Length first, bytes next. Independent of terminator behavior.

UTF-8 Considerations

String length and byte length differ for non-ASCII. string_byte_length for the byte count; string_length for character count. Length-prefix uses byte length.

Endianness

buffer types are little-endian by default. If interoperating with big-endian protocols, manually byteswap.

Verifying

Save round-trips strings without corruption. Cross-platform reads produce identical results.

“buffer_string and buffer_text differ on the terminator. Length-prefix strings is safest.”

Adopt length-prefix as the project standard — you avoid the terminator question entirely and gain Unicode safety.