Skip to content

Merge world-sync into entity-sync - #99

Open
Liparakis wants to merge 6 commits into
entity-syncfrom
world-sync
Open

Liparakis wants to merge 6 commits into
entity-syncfrom
world-sync

Conversation

@Liparakis

@Liparakis Liparakis commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Changes

  • Save sync: SaveManager now syncs Silksong save data. save-data.json is rebuilt for Silksong, and the Godseeker overrides are removed.
  • Encoding: EncodeUtil handles all primitive numeric types, enums, HashSet<string>, byte arrays and strings missing from string-data.json.
  • Server saves: global save data is now kept in the mod save file and written when the host's game saves.
  • Joining: with full sync on, ServerInfo sends the current save to the joining client, so they load the host's world instead of picking a local slot.
  • /copysave: reports a missing source save instead of throwing, and disconnects with the new SaveCopy reason.
  • Music: music-data.json now lists Silksong's music cues and snapshots, and the music lookups are simplified.
  • Fixes: remote players progress is saved now, and the multiplayer panel hides after joining.

* feat: Save data

* feat: implement live music capture instrumentation and add XML documentation

* feat: enable SaveManager for save synchronization

* chore: remove godseeker save data overrides and checks

* feat: add HashSet<string> serialization support for save data

* feat: add dynamic string fallback encoding for unlisted strings

* feat: implement type-aware null encoding to prevent save manager serialization crash

* feat: add serialization and deserialization support for primitive numeric types

* fix: make MusicCueData and AudioMixerSnapshotData property setters public for deserialization

* fix: prevent NullReferenceException on uninitialized save lists/sets during scan

* chore: comment out entity manager hook registration to keep entities disabled for world sync

* Fix UI transition NullReferenceException, support diverse numeric types in save decoding, adjust /copysave disconnect reason, and redirect modsav to config path

* chore: Small IDE suggested fixes and formatting

* chore: Converted multiple ifs to switches and some slight formatting

* Clean up MusicComponent: comment out InitializeCapture and convert property accessors to read-only with JsonConstructor

* Fix client/server components, packet validation, and null string encoding

* Add XML documentation for ValidateAndNormalizeSaveData method
- Send PlayerData changes from remote players (public PlayerData constructor, null compound fields)
- Load HashSet entries from the remote player save file
- Hide the multiplayer panel when entering the game from the MP menu
- Remove the disabled music capture tooling
- Restore <inheritdoc /> on the MusicComponent overrides
@Liparakis
Liparakis requested a review from Extremelyd1 October 18, 2026 09:35

@Extremelyd1 Extremelyd1 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a bit, but I've gone through the changes and left a bunch of comments.

I'm going to assume that the data files (music-data.json, save-data.json, string-data.json) are somewhat correct, as I'm not going to check those!

Looks pretty good, I haven't tested it in-game yet, so these are only comments about the code itself and what I can deduce might be missing/incorrect.

Comment thread SSMP/Game/Client/Save/SaveManager.cs Resolved
Comment thread SSMP/Game/Client/Save/SaveManager.cs Resolved
Comment thread SSMP/Game/Client/Save/SaveManager.cs Resolved
Comment thread SSMP/Game/Server/ModServerManager.cs Resolved
Comment thread SSMP/Util/EncodeUtil.cs Resolved
Comment thread SSMP/Util/EncodeUtil.cs Resolved
Comment thread SSMP/Util/EncodeUtil.cs Resolved
Comment thread SSMP/Util/EncodeUtil.cs Resolved
- Decode save data values by their exact length and correct the type of
  the memoryOrbs_Clover variables, which were the reason for leniency
- Simplify encoding of null values and explain the string encoding
- Make NetServer protected in ServerManager and reuse it
- Define the mod save file path in a single place
- Keep GetCompoundCopy non-nullable and check for null before calling it
- Remove unneeded comparers and warning suppressions in MusicComponent
Scene data:
- Send geo rocks and persistent bools/ints from the host's scene data and
  store received values in the local scene data
- Skip semi-persistent items when sending and keep the flags of known items
  when receiving
- Sync pickups through their persistent item
- Apply the save data again once a new game has started
- Skip a save value that cannot be applied instead of stopping the join

Save loading:
- Merge the mod save over the loaded save, because older files are missing
  values such as scene data
- Skip a value that cannot be read instead of failing the whole file
- Keep a copy of a file that cannot be loaded, since the next save
  overwrites it

EncodeUtil:
- Split encoding and decoding into small methods dispatched by a switch
- Reject truncated values and trailing bytes when decoding
- Warn about int list values that do not fit in a byte
- Organise the class into regions

SaveManager:
- Check the PlayerData 10 times per second instead of every frame
- Cache the PlayerData fields and hash collections without copying them
- Move local functions to documented methods and simplify the checks

Remove the boss sequence door and boss statue variables, which are not used
in Silksong, including their serialization classes and encoding.

The encoded bytes are unchanged, except that the memoryOrbs_Clover variables
are now correctly treated as ulong.
@Liparakis
Liparakis requested a review from Extremelyd1 October 31, 2026 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants