Quick answer: array_copy is shallow. Nested arrays/structs share references with the original. Write a recursive deep_copy for nested data.
An RPG saves the player’s inventory by copying the array into a save slot. Edits to the live inventory mysteriously appear in the saved snapshot. Shallow copy with shared nested structs.
The Trap
var live = [
{ name: "sword", qty: 1 },
{ name: "potion", qty: 3 }
];
var saved = array_create(array_length(live));
array_copy(saved, 0, live, 0, array_length(live));
live[1].qty = 99;
show_debug_message(saved[1].qty); // 99 - share!
The struct references are copied, not the structs themselves. Both arrays point to the same structs.
Deep Copy Helper
function deep_copy(value) {
if (is_array(value)) {
var n = array_length(value);
var result = array_create(n);
for (var i = 0; i < n; i++) result[i] = deep_copy(value[i]);
return result;
}
if (is_struct(value)) {
var result = {};
var keys = variable_struct_get_names(value);
for (var i = 0; i < array_length(keys); i++) {
variable_struct_set(result, keys[i], deep_copy(variable_struct_get(value, keys[i])));
}
return result;
}
return value; // numbers, strings: passed by value
}
Recurses through arrays and structs. Primitives copy by value naturally.
Alternative: JSON Snapshot
var saved = json_parse(json_stringify(live));
Quick and dirty: serialize to JSON and back. Slower than recursive deep copy, but handles all nested data and is one line. Loses methods/refs but for save state usually fine.
Verifying
Make a deep copy. Mutate the original. Check the copy: unchanged. Edge cases: nested arrays inside structs inside arrays — all isolated.
“Shallow copies work for flat data. For nested structures, you need a full traversal.”
For RPG-grade save systems, JSON snapshot is also your serialization format — double duty.