fix: squad saving and loading - #1435
Conversation
There was a problem hiding this comment.
3 issues found across 3 files
Confidence score: 3/5
- In
objects/obj_ini/Create_0.gml, deserialization now calls_squad.load(_data)without the previous post-load member validation, so malformed or legacy save payloads can leave squads in invalid states or fail at runtime—add defensive error handling and restore/replace member integrity checks after load. - In
objects/obj_ini/Create_0.gmlserialize(), squad members are normalized to UIDs butsquad_leaderis still saved as a full struct clone, which can reload as a detached plain struct without expected methods and break leader-related behavior—store the leader as a UID and re-resolve it on load. - In
scripts/scr_squads/scr_squads.gml, pruning unresolved member UIDs without recomputinglife_memberscan leave stale counts and show phantom members in the squad UI—recalculatelife_membersduring the cleanup pass.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/scr_squads/scr_squads.gml">
<violation number="1" location="scripts/scr_squads/scr_squads.gml:483">
P2: When a saved member UID no longer resolves, this cleanup removes the member but leaves `life_members` at its saved value. Recalculate `life_members` while pruning so the squad UI does not show phantom members.</violation>
</file>
<file name="objects/obj_ini/Create_0.gml">
<violation number="1" location="objects/obj_ini/Create_0.gml:163">
P2: In serialize(), squad members are normalized to uid strings, but `squad_leader` is left as a full marine-struct clone, so it is embedded in the save and reloaded as a detached plain struct without methods instead of the live marine. Convert `squad_leader` to its uid like members (and resolve it back in `load`).</violation>
<violation number="2" location="objects/obj_ini/Create_0.gml:317">
P2: Custom agent: **Code Quality Review**
The new `_squad.load(_data)` call during deserialization has no error handling, and the post-load member validation loops from the previous code were removed. Because this loads user-provided save data, a malformed squad struct will cause an unhandled runtime exception. Follow the project's established deserialization pattern—used for artifact loading a few lines below—and wrap the call in `try/catch` with `LOGGER.exception()`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
|
||
| for (var s = array_length(members) - 1; s >= 0; s--) { | ||
| if (!is_struct(members[s])) { | ||
| array_delete(members, s, 1); |
There was a problem hiding this comment.
P2: When a saved member UID no longer resolves, this cleanup removes the member but leaves life_members at its saved value. Recalculate life_members while pruning so the squad UI does not show phantom members.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/scr_squads/scr_squads.gml, line 483:
<comment>When a saved member UID no longer resolves, this cleanup removes the member but leaves `life_members` at its saved value. Recalculate `life_members` while pruning so the squad UI does not show phantom members.</comment>
<file context>
@@ -471,10 +471,17 @@ function UnitSquad(squad_type = undefined, company = 0) constructor {
+
+ for (var s = array_length(members) - 1; s >= 0; s--) {
+ if (!is_struct(members[s])) {
+ array_delete(members, s, 1);
+ }
}
</file context>
| array_delete(members, s, 1); | |
| array_delete(members, s, 1); | |
| life_members = array_length(members); |
| for (var s = 0; s < array_length(_squad.members); s++) { | ||
| if (is_struct(_squad.members[s])) { | ||
| _squad.members[i] = _squad.members[s].uid; | ||
| _squad.members[s] = _squad.members[s].uid; |
There was a problem hiding this comment.
P2: In serialize(), squad members are normalized to uid strings, but squad_leader is left as a full marine-struct clone, so it is embedded in the save and reloaded as a detached plain struct without methods instead of the live marine. Convert squad_leader to its uid like members (and resolve it back in load).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At objects/obj_ini/Create_0.gml, line 163:
<comment>In serialize(), squad members are normalized to uid strings, but `squad_leader` is left as a full marine-struct clone, so it is embedded in the save and reloaded as a detached plain struct without methods instead of the live marine. Convert `squad_leader` to its uid like members (and resolve it back in `load`).</comment>
<file context>
@@ -160,7 +160,7 @@ serialize = function() {
for (var s = 0; s < array_length(_squad.members); s++) {
if (is_struct(_squad.members[s])) {
- _squad.members[i] = _squad.members[s].uid;
+ _squad.members[s] = _squad.members[s].uid;
}
}
</file context>
| var _data = _squad_structs[$ _squad_uid]; | ||
| var _squad = new UnitSquad(); | ||
| _squad.load_json_data(_squad_structs[$ _squad_uid]); | ||
| squads[$ _squad_uid] = _squad; | ||
| for (var s = 0; s < array_length(_squad.members); s++) { | ||
| _squad.members[s] = fetch_unit_uid(_squad.members[s]); | ||
| } | ||
| _squad.load(_data); |
There was a problem hiding this comment.
P2: Custom agent: Code Quality Review
The new _squad.load(_data) call during deserialization has no error handling, and the post-load member validation loops from the previous code were removed. Because this loads user-provided save data, a malformed squad struct will cause an unhandled runtime exception. Follow the project's established deserialization pattern—used for artifact loading a few lines below—and wrap the call in try/catch with LOGGER.exception().
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At objects/obj_ini/Create_0.gml, line 317:
<comment>The new `_squad.load(_data)` call during deserialization has no error handling, and the post-load member validation loops from the previous code were removed. Because this loads user-provided save data, a malformed squad struct will cause an unhandled runtime exception. Follow the project's established deserialization pattern—used for artifact loading a few lines below—and wrap the call in `try/catch` with `LOGGER.exception()`.</comment>
<file context>
@@ -314,18 +314,10 @@ deserialize = function(save_data) {
var _squad_count = array_length(_squad_uids);
for (var i = 0; i < _squad_count; i++) {
var _squad_uid = _squad_uids[i];
+ var _data = _squad_structs[$ _squad_uid];
var _squad = new UnitSquad();
- _squad.load_json_data(_squad_structs[$ _squad_uid]);
</file context>
| var _data = _squad_structs[$ _squad_uid]; | |
| var _squad = new UnitSquad(); | |
| _squad.load_json_data(_squad_structs[$ _squad_uid]); | |
| squads[$ _squad_uid] = _squad; | |
| for (var s = 0; s < array_length(_squad.members); s++) { | |
| _squad.members[s] = fetch_unit_uid(_squad.members[s]); | |
| } | |
| _squad.load(_data); | |
| var _data = _squad_structs[$ _squad_uid]; | |
| var _squad = new UnitSquad(); | |
| try { | |
| _squad.load(_data); | |
| } catch (e) { | |
| LOGGER.exception("Failed to load squad " + _squad_uid, e); | |
| } |
Summary by cubic
Fixes squad save/load so squads and their members persist after reloading. Previously, serialization wrote to the wrong member index and deserialization didn’t register squads or resolve member IDs, which made squads disappear or appear empty after load.
uids; savesquad_structsfrom_squad_copiesinstead of livesquads.load_json_datawithUnitSquad.load, which moves data into the instance, registers it inobj_ini.squads, resolves member IDs viafetch_unit_uid, and prunes invalid entries.fetch_unit_uidnow usescompany_length(i)for bounds rather thanarray_length(obj_ini.TTRPG[i])to avoid out-of-range access.load_json_data, rename those calls toload.Written for commit 84efc69. Summary will update on new commits.