If two players request ownership at the same moment
Are there circumstances where it looks momentarily like you could own the item locally but then your ownership is rejected by the server?
17 Replies
Hi @cryptomax. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Yes, there are circumstances where it may momentarily appear that you own an item locally, but then your ownership is rejected by the server. This can happen when two clients simultaneously request ownership of the same object.
In NormalVR's Normcore, the
RequestOwnership()
and ClearOwnership()
methods take effect immediately. However, if the server blocks the request—say, because preventOwnershipTakeover
is true
or because the view's parent is owned by another client—then ownership and all changes that required ownership will be rolled back.
Also, when using RealtimeModel objects, updates appear to take effect immediately for the local client. However, the server may reject an update due to either ownership or Normcore Private plug-ins. When this happens, the server sends back the rejected update or a modified version of the state in the update. The datastore then rolls the data back or replaces it with the version transformed by the server.
In the case of RealtimeTransform, it is available for immediate use after RequestOwnership()
is called. Normcore will assume the call is going to succeed, and will roll back any state changes automatically if the call is rejected by the server. A RequestOwnership()
call is only rejected if the RealtimeView or a parent RealtimeView is owned by a different client.
Sources:
- RequestOwnership() + ClearOwnership() (https://normcore.io/documentation/room/ownership-and-lifetime-flags#requestownership--clearownership)
- Instant updates (https://normcore.io/documentation/room/datastore#instant-updates)
- RealtimeTransform > How it works (https://normcore.io/documentation/realtime/realtimetransform#how-it-works)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@401986039964631060> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant does this mean in asituation where it is likely ownership is being requested at the same exact moment you can just wait a frame and check if it is owned locally?
Let me check the knowledge base for you. One moment! :books:
----------------------
Yes, you can wait a frame and then check if the object is still owned locally. This is because Normcore handles ownership requests and updates immediately on the local client, but these changes might be rolled back in the next frame if the server rejects the ownership request.
You can use the
isOwnedLocallyInHierarchy
property of the RealtimeView
to check if the object is still owned locally. Here's an example of how you might do this in Unity:
Please note that this is a simplified example and actual usage may vary depending on your specific needs and the structure of your project.
Sources:
- Realtime > Common Questions (https://normcore.io/documentation/realtime/common-questions#i-have-a-script-on-my-player-why-is-it-updating-all-players-in-the-room)
- RealtimeTransform > How it works (https://normcore.io/documentation/realtime/realtimetransform#how-it-works)
- Datastore > Instant updates (https://normcore.io/documentation/room/datastore#instant-updates)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@401986039964631060> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant What was hte difference between isOwnedLocallyInHierarchy and isOwnedLocallySelf?
Let me check the knowledge base for you. One moment! :books:
----------------------
The
isOwnedLocallySelf
and isOwnedLocallyInHierarchy
properties are used to determine the ownership status of a component or model in Normcore.
- isOwnedLocallySelf
: This property returns true
if the component or model is owned by the local client. It only checks the ownership of the specific component or model on which it is called.
- isOwnedLocallyInHierarchy
: This property returns true
if the component or model or any of its parents in the hierarchy are owned by the local client. It checks the ownership of the entire hierarchy, from the specific component or model up to the root.
In other words, isOwnedLocallySelf
checks if the specific component or model is owned by the local client, while isOwnedLocallyInHierarchy
checks if the specific component or model or any of its parent components or models are owned by the local client.
Sources:
- RealtimeModel > Properties Part 2 (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeModel)
- RealtimeView > Properties Part 1 (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeView)
- IRealtimeComponent (https://normcore.io/documentation/reference/classes/Normal.Realtime.IRealtimeComponent)
- RealtimeComponent<TModel> (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeComponent%601)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@401986039964631060> kapa.ai is still learning and improving, please let us know how it did by reacting below
Waiting one frame doesn't seem like a reliable solution since normcore only syncs at 20Hz. It won't sync changes every frame, so you'd need to wait until after the next normcore sync
hmmm so you would subscribe to the write to know when that would be?
Yeah, that'd be one way to do it. Or you could be lazy and wait 100ms or half a second 😛
subscribing feels a little like over kill to solve the problelm since then forever you have 20 methods running per second that was really only to fix this tiny issue
maybe better to just check if it's still unowned and tryagain?
gues thats what your saying just wait longer
If it's a common pattern you could have a single helper class to increment a counter after each write and just wait for the counter to change. Similar to Time.frameCount, but it'd be writeCount
depending on what you need it for you can continue like it succeeded and poll the owner or use the ownerid changed event
if it's for spawning stuff you can use the string key dictionary to be 100% sure only one message gets through
was just handling losing ownership with a disconnected using ownership did change to check if it's unowned and then request onwership, but that means everyone would do iot, I geussI should just have only lowest connected request that would also handle it
that would work
wonder when that auto transfer to lowest connected might come about..... 🙂