khoi
khoi2w ago

"Incrementing" a value on a model

If I have a private int _damage on a model, and then I do the following code: public void AddDamageToModel(int damage) { SetDamage(model.damage + damage); } public void SetDamage(int damage) { model.damage = damage; } And multiple clients call this function. What happens? Will it sequentially increment without overriding each other?
11 Replies
kapa.ai
kapa.ai2w ago
Hi @khoi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- When multiple clients call AddDamageToModel(int damage) as you've written it, each client will read the current value of model.damage from their local copy, add their own damage, and then set the new value. However, this approach is not atomic across the network: if two clients read the same value at the same time and both increment it, they may both write back the same result, causing one increment to be lost (a classic race condition). Normcore's datastore uses a "last-client-wins" approach for non-transactional model updates: the last update received by the server will overwrite previous ones. There is no built-in mechanism to guarantee that increments from multiple clients are merged together automatically. So, if two clients both call AddDamageToModel(1) at the same time when model.damage is 0, both may read 0, both set it to 1, and the final value will be 1, not 2. If you need to support concurrent increments from multiple clients without losing updates, you should use a transactional collection or design your model to avoid this pattern. For example, you could use a RealtimeDictionary or StringKeyDictionary to track per-client contributions and sum them, or implement a server-authoritative approach to manage increments safely. In summary:
No, increments are not merged automatically—simultaneous updates can overwrite each other, and you may lose increments if multiple clients update the value at the same time using your current approach. You need to use a different pattern or collection to handle concurrent increments safely in Normcore.
Room > Datastore
Room > Collections ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
khoi
khoiOP2w ago
"or implement a server-authoritative approach to manage increments safely." Does normcore have one built in I can use? @kapa.ai
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Normcore does not provide a built-in, general-purpose server-authoritative increment operation for model fields like integers. However, it does offer mechanisms for server authority and ownership enforcement: - Ownership and Lifetime Flags: By default, only the owner of a model can modify it. This prevents other clients from making changes, but does not merge concurrent increments from multiple owners. Ownership is enforced at the model level, not at the operation level, so it does not solve the atomic increment problem for shared values across clients Server Authority + Ownership + Lifetime Flags. - Normcore Private Authoritative Servers: If you need true server-side logic (such as atomic increments), Normcore Private allows you to run a custom authoritative Unity game server alongside the room server. This server can modify any state in the datastore, including implementing custom logic for safe increments. However, this requires deploying and maintaining your own authoritative server logic and is only available with Normcore Private, not the standard hosted version Authoritative Servers. Summary:
Normcore’s standard offering does not include a built-in atomic increment operation for shared values. For advanced server-authoritative logic (like atomic increments), you would need to use Normcore Private and implement this logic yourself on a custom authoritative server. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
khoi
khoiOP2w ago
if this model is a custom model and no one owns it, who can modify it? everyone? @kapa.ai
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- If a custom model in Normcore is unowned (i.e., its ownerID is -1), then any client in the room can modify it. Ownership in Normcore is used to restrict who can make changes: when a model is unowned, all clients are permitted to update its state. When a model is owned by a client, only that client can make changes to it or its child models; all other clients are blocked from modifying it Server Authority + Ownership + Lifetime Flags. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit2w ago
if you want to avoid a race condition you can sync a list of damage instances
khoi
khoiOP2w ago
do you mean with RealtimeDictionary and then sum them? That’s what I was planning but was wondering if there was just an incrementer
Mechabit
Mechabit2w ago
RealtimeSet would be better

Did you find this page helpful?