Quick answer: GameMaker buffer_async_save returning before finishing leaves a corrupt file? Async writes don't have transactional semantics - write to a temp file and rename on completion.
Player closes the app mid-save. Save file is partial; next launch fails to parse.
Write temp then rename
buffer_async_save(buf, "save.tmp", 0, buf_size);
// in async complete:
file_rename("save.tmp", "save.dat");Rename is atomic on most filesystems. Partial temp files don't replace the good save.
Validate on load
Compute and store a checksum at save time. Reject loads with bad checksum; fall back to a backup.
Keep generational backups
save.dat, save.dat.1, save.dat.2. Each save rotates. Recovery from corruption becomes a one-line action.
“Saves should be transactional. Atomic rename is the cheapest transaction primitive.”
Document the save flow in the engineering wiki. New contributors will need to know exactly how the save file becomes valid; the algorithm is short but easy to break.