com.unity.netcode.gameobjects
com.unity.netcode.gameobjects copied to clipboard
Unwanted OnValueChanged network variable calls on Gained and Lost ownership.
Description
I have an in-scene object (just using as simplifies testing) with four network variables with differing permissions:
// anyone can read but only server/host can write - these are the default permissions and can be omitted
NetworkVariable<int> anyReadHostWrite_1 = new NetworkVariable<int>(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
// only owner and server/host can read, only server/host can write - other client reads will return initial value as it's not updated
NetworkVariable<int> ownerReadHostWrite_2 = new NetworkVariable<int>(0, NetworkVariableReadPermission.Owner, NetworkVariableWritePermission.Server);
// anyone can read, only the owner can write - writes by non-owners including host result in an error
NetworkVariable<int> anyReadOwnerWrite_3 = new NetworkVariable<int>(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
// only owner and server/host can read, only owner can write - writes by non-owners including host result in an error
NetworkVariable<int> ownerReadOwnerWrite_4 = new NetworkVariable<int>(0, NetworkVariableReadPermission.Owner, NetworkVariableWritePermission.Owner);
On granting ownership of said object to a client, on the client the OnValueChanged events are triggered for anyReadHostWrite_1 and ownerReadHostWrite_2. On losing ownership the OnValueChanged event are triggered for anyReadHostWrite_1 and anyReadOwnerWrite_3.
Is this correct, as to me where the permission is set to Everyone there's no need to trigger an OnValueChanged event as the value is already correct.
Actual Outcome
OnGainedOwnership events: OnValueChanged anyReadHostWrite_1 OnValueChanged ownerReadHostWrite_2
OnLostOwnership events: OnValueChanged anyReadHostWrite_1 OnValueChanged anyReadOwnerWrite_3
Expected Outcome
OnGainedOwnership events: OnValueChanged ownerReadHostWrite_2
OnLostOwnership events: None
It looks like only ownerReadHostWrite_2 need be triggered on gained ownership and there should be no triggers on lost ownership, unless I'm missing something?
Environment
- OS: macOS Big Sur
- Unity Version: [e.g. 2020.3]
- Netcode Version: 2.0.0-pre-4
Additional Context
The code I've used is available here
@ezoray Yeah that doesn't seem right to me either, and thank you for the reference source code (it helped me verify this issue quickly)!
I can see where ownerReadHostWrite_2 should update upon the new owner acquiring ownership, but that should happen on the new owner's side but should not happen when ownership is lost (at least it seems that would be the expected/correct behaviour). It seems when ownership changes and the write permissions are server it happens on both anyReadHostWrite_1 and anyReadHostWrite_2.
Going to add this for import. 👍
@NoelStephensUnity great thanks. On the same sort of subject, I was just looking at network lists and if the read/write permissions are both Owner and ownership changes the list contents are not sent to the new owner, is this as expected?
I wrote some code for this here in case you want to check, you'll just need to change the list permissions on InSceneObject in the inspector.
@NoelStephensUnity great thanks. On the same sort of subject, I was just looking at network lists and if the read/write permissions are both Owner and ownership changes the list contents are not sent to the new owner, is this as expected?
I wrote some code for this here in case you want to check, you'll just need to change the list permissions on InSceneObject in the inspector.
Thank you for this additional example and heads up. I have added an internal ticket for this issue. While I have been on this project since the beginning some of these areas were written by other authors and there were some interesting scenarios/decisions made. The ticket I created internally is placed at a normal priority as I seem to remember a discussion a long (long long) time ago about this particular permissions configuration.
The general idea behind the owner write owner/server read was to have a client specific set of data that was exclusive between the client and the server. If ownership of the object changes the intended behavior very well could be considered a "fresh slate" between the new client and server...as I said this conversation regarding the security aspect of this particular permissions configuration took place a long time ago...but I (kind of) remember a several day debate as to whether the "private data" between say Client-A and the server should be handed off to another client when ownership changes. So, this particular issue might end up being a "works as expected" (but opened a ticket to allocate some time to just make sure it isn't a bug).
Since we have added collection support to NetworkVariable, it might be that the same permissions settings (Owner write and Owner/Server read) will update with an ownership change (another thing I added to the ticket to investigate) and if that is the case then most likely we will want to mirror that behavior with NetworkList (i.e. if NetworkVariable<List<T>> ends up synchronizing the content with the new owner then we would want to keep consistency with NetworkList, but if it shows the same behavior then we will most likely keep that same behavior with NetworkList).
Thank you for your time and the input! (Very much appreciated) 👍
Thanks Noel I appreciate the detailed explanation. I'm on the fence about this, I was struggling to think of a use case for it where it would be the preferred method of data transfer. If the variable/list is mutually exclusive would it need to be networked in the first place, having it sync up on owner change could be the differentiator but I'll leave it to your better judgement.
Sorry to take this off-topic but you mentioned NetworkVariable collections, is it possible to get an example of how to use it? I was going to create my own example but when I was using it for a network dictionary I couldn't figure up how the receiver would pick up the delta's in a similar fashion to say NetworkLists. It didn't seem to work as I expected but that may be just me not understanding the implementation.
Absolutely... You can take a look at this integration test to see some examples of using Linq queries to get what was:
- Added
- Removed
- Changed
- Remained the same
Aha thanks Noel, I'll have a play with it.
Yeah... I am behind on documentation (and such)...so that is the best I can provide in terms of an example... 😸
I believe this issue has been resolved. Update to the latest version of NGO (v2.3.2+) and you should not see the OnValueChanged notifications.