Mischa
Mischa6d ago

Check for definitive Ownership

Am I correct that, in theory, two clients could return "true" to "isOwnedLocallySelf" in a given frame (right before the server blocks and rolls back the request for one of the two clients). What would be the most definitive way to make sure no-one else is fighting for ownership in a given frame? Check over multiple frames seems like a brute force way of doing this? I sthere a better way?
13 Replies
kapa.ai
kapa.ai6d ago
Hi @Mischa. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, you are correct. In theory, two clients could return "true" to "isOwnedLocallySelf" in a given frame before the server blocks and rolls back the request for one of the two clients. This is because the RequestOwnership() and ClearOwnership() methods take effect immediately on the client side, but the server might block the request due to reasons like preventOwnershipTakeover being true or the view's parent being owned by another client. In such cases, ownership and all changes that required ownership will be rolled back by the server. To definitively ensure no one else is fighting for ownership in a given frame, you could use the RequestOwnership(bool sendRedundantUpdates = false) method with the sendRedundantUpdates parameter set to true. This will send the ownership update even if the model is already owned by the local client. This might send redundant updates but is useful if you expect contention. However, this does not circumvent the "Prevent Ownership Takeover" lifetime flag if it applies. Here's an example of how you can use it:
// Get the RealtimeView component
RealtimeView myObjectView = myObject.GetComponent<RealtimeView>();

// Request ownership of the RealtimeView with redundant updates
myObjectView.RequestOwnership(true);
// Get the RealtimeView component
RealtimeView myObjectView = myObject.GetComponent<RealtimeView>();

// Request ownership of the RealtimeView with redundant updates
myObjectView.RequestOwnership(true);
This approach ensures that the server is updated about the client's intent to own the object, even if the client already owns it. This can help in situations where multiple clients might be trying to take ownership of the same object. However, please note that this approach might lead to increased network traffic due to redundant updates. If this becomes a concern, you might need to implement a more sophisticated system for managing ownership requests, possibly involving some form of client-side prediction or a queue system for ownership requests. Sources: - RequestOwnership() + ClearOwnership() (https://normcore.io/documentation/room/ownership-and-lifetime-flags#requestownership--clearownership) - RealtimeModel Methods (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeModel) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai6d ago
<@847936237003604048> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mechabit
Mechabit6d ago
StringKeyDictionary is the only data type that returns a message when the server receives it. you can use that for what you need
Mischa
Mischa6d ago
Oh, so you would just add a custom filed of that type that holds the ownership value to the realtime model?
Mechabit
Mechabit6d ago
if you wanted to make sure only one person owned a thing you can have them both try to insert a model and the one that succeeds can make the ownership request
Mischa
Mischa6d ago
Thank you for the idea!
kapa.ai
kapa.ai4d ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To invite someone to a private room in Normcore, you need to share the room name and the App Key with them. When they use these details to connect to the room, they will join the same room server. Here's a basic example of how to connect to a room:
// Get the Room component
Room room = GetComponent<Room>();

// Connect to the room
room.Connect("YourRoomName", "YourAppKey");
// Get the Room component
Room room = GetComponent<Room>();

// Connect to the room
room.Connect("YourRoomName", "YourAppKey");
In this example, replace "YourRoomName" with the name of your room and "YourAppKey" with your App Key. Please note that all clients that connect to the same room name with the same App Key will connect to the same room server. If you are working with Normcore Private, make sure to set the matcherURL parameter to your Normcore Private matcher URL. For more information, you can refer to the Connecting to a room server (https://normcore.io/documentation/room/room#connecting-to-a-room-server) section in the Normcore documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4d ago
<@1124402583155511357> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mischa
Mischa2d ago
Are we sure that isOwnedLocallySelf is not verified by the server? I.e. will this flag be set immediately when requesting ownership or does it only get set once it gets confirmed by the server? Would be be nice to have a simpler way to test for definitive ownership other than attempting to add a model to a transactional collection. @Max ?
maxweisel
maxweisel2d ago
it's set immediately and waits for the server to reject as we expect the majority case to be that it's allowed there is an ownerIDChanged event you can subscribe to, but I think it will fire instantly and then fire again on roll back StringKeyDictionary is the correct approach for atomic value changes as it won't fire a callback until the server confirms / denies We're definitely working to create a better API for these types of transactions in the next version. I'm hoping as a whole we can provide both an instant caching layer + server confirmation events for all properties in the datastore
Mischa
Mischa2d ago
Thank you for the clarification.
maxweisel
maxweiselthis hour
sure thing!