Skip to content

Make FCollection's set field transient to skip redundant serialization#9991

Merged
tool4ever merged 1 commit intoCard-Forge:masterfrom
MostCromulent:fix/fcollection-transient-set
Mar 5, 2026
Merged

Make FCollection's set field transient to skip redundant serialization#9991
tool4ever merged 1 commit intoCard-Forge:masterfrom
MostCromulent:fix/fcollection-transient-set

Conversation

@MostCromulent
Copy link
Contributor

Summary

  • Makes FCollection's internal HashSet field transient, skipping it during Java serialization
  • Adds readObject() to rebuild the set from the list after deserialization
  • Removes final from the set field (required because field initializers don't run during Java deserialization — the field is null after defaultReadObject() and must be reassigned in readObject())

Context

Discussed with @tool4ever based on the investigation in copyChangedProps.md (change #3 + RE 3 feedback).

FCollection is a hybrid list+set data structure that is serialized on every network setGameView call. The set duplicates all list element references — since Java serialization shares object references within a single writeObject call, these are back-references (~5 bytes each) rather than full copies, but it's still pure waste across dozens of collections per GameView.

The list is the source of truth for element order and indexed access. Rebuilding the set from the list in readObject() is equivalent to serializing it, but also guarantees correct HashMap bucket placement — eliminating a class of structural HashMap corruption observed during network play testing where deserialized entries end up in wrong buckets due to circular object graph references.


🤖 Generated with Claude Code

The set duplicates all list elements during Java serialization. Since
the list is the source of truth, rebuild the set from it in readObject()
instead of serializing it. Also fixes HashMap bucket corruption on
deserialization of circular object graphs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Hanmac Hanmac requested a review from tool4ever March 5, 2026 09:47
@Hanmac Hanmac requested a review from tehdiplomat March 5, 2026 13:29
@tool4ever tool4ever merged commit d1a4494 into Card-Forge:master Mar 5, 2026
2 checks passed
@Jetz72
Copy link
Contributor

Jetz72 commented Mar 5, 2026

Are we sure we never serialized any of these when writing stuff like Quest/PlanarConquest/Adventure saves? Or that if we did, it's backwards compatible?

@tool4ever
Copy link
Contributor

tool4ever commented Mar 5, 2026

hmn, I see no direct reason why it would become incompatible this way
would certainly be weird if Adventure saved it though 🤔

@Jetz72
Copy link
Contributor

Jetz72 commented Mar 5, 2026

Yeah, looking over it I guess these are mostly just used for in-game and GUI collections. It's the ItemPools that would be more dangerous if modified. We still need to move away from Java serialization for saving files at some point, but that's neither here nor there.

@MostCromulent MostCromulent deleted the fix/fcollection-transient-set branch March 5, 2026 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants