Closed NaolShow closed 4 months ago
Found a solution (might not be the right one, not experienced enough with FishNet codebase):
On the first time hosting, everything works because (in SyncList for example) ignoreReadChanges is false. So the changes in the ServerCollection are replicated on the ClientCollection for the host.
This underlying issue is from the SyncBase class, that contains "_lastReadDirtyId". On first time hosting, this value is set to "-1" which allows the ReadChangeId method (used to determine if the changes should be ignored or not) to return:
!reset && (id <= _lastReadDirtyId)
(reset is false for a Full Write, always the case, no problem here). But the _lastReadDirtyId IS NOT reset for the host when the network shutdowns
Which mean, on the second and latter starts, the value might not be -1 whereas the id resets. So the condition is true, and we ignore changes.
It appears that modifying the ResetState method of the SyncBase from:
internal protected virtual void ResetState(bool asServer) {
if (asServer) {
_lastWriteFullLocalTick = 0;
_changeId = 0;
NextSyncTick = 0;
SetCurrentChannel(Settings.Channel);
IsDirty = false;
} else {
_lastReadDirtyId = DEFAULT_LAST_READ_DIRTYID;
}
}
to:
internal protected virtual void ResetState(bool asServer) {
if (asServer) {
_lastWriteFullLocalTick = 0;
_changeId = 0;
NextSyncTick = 0;
SetCurrentChannel(Settings.Channel);
IsDirty = false;
}
// Reset the last read dirty id for everyone
_lastReadDirtyId = DEFAULT_LAST_READ_DIRTYID;
}
makes everything work again (from my quick tests). Is it the right solution? Might not be, but it seems strange to not reset this specific id for the server? (Errors could also appear in other Sync variants, since this issue is directly in the SyncBase)
I'll not do a PR for now, since I do not know if this solution is valid or not. But I can do it in case its the right one.
Realistically you should only need to reset the Id for client. Perhaps asServer: false is not being called for any number of clientHost reasons. The server has no use for the lastReadDirtyId so resetting it with asServer: true is safe.
You can go ahead and submit a PR, there's no risk of your changes hurting anything. Thank you!
Thank you for your answer, No problem, I'll do a PR over the week end then!
Resolved in 4.3.8, release date is not known yet. You can still submit a PR for credit.
All good, as long as it is fixed. Thank you!
Important
General Unity version: 2022.3.11f1 Fish-Networking version: 4.3.5R Discord link: https://discord.com/channels/424284635074134018/1251846863720546334/1251846864949481563
Description When having a SyncList that is placed on a NetworkObject, that also gets populated in the OnStartServer method and the host does:
This results in bugs when modifying the list (for example setting the value on an index that should be present) since SyncList Read method tries to access the index that is not contained in the ClientCollection.
Replication Steps to reproduce the behavior:
Exception thrown from SyncList Read method:
Example script (just press B to modify the first index):
Expected behavior Behavior should not change when stopping/starting the host again, and the SyncList should properly synchronize the ClientCollection from the ServerCollection. And our step 6 of modifying the first index should work, because the elements added in the OnStartServer should be in the ClientCollection.