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.