Player Health mechanic
In the docs its mentioned to use RealtimeDictionary for something like this, but I'm having trouble getting a class set up with this.
8 Replies
Hi @rj. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To implement a player health mechanic using Normcore, the recommended approach is to use a
RealtimeDictionary to store each player's health as a model. This allows multiple clients to modify health values without causing datastore conflicts, and all updates are synchronized efficiently across clients.
How to Set Up a Player Health Mechanic with RealtimeDictionary
#### 1. Create a Health Model
First, define a model to represent the player's health. For example:
This model will store the health value for each player. The [RealtimeProperty] attribute ensures the health value is synchronized and fires change events when updated.
#### 2. Add a RealtimeDictionary to Store Player Health
In your main game model, add a RealtimeDictionary to store each player's health model, keyed by their client ID or another unique identifier:
You can then add, update, or remove health models for each player as needed.
#### 3. Access and Modify Health
To update a player's health, retrieve their PlayerHealthModel from the dictionary and set the health value:
To add a new player:
#### 4. Listen for Changes
You can subscribe to the modelAdded, modelRemoved, and modelReplaced events on the RealtimeDictionary to react to changes in player health models:
Important Notes
- RealtimeDictionary is designed for real-time updates and can be modified by multiple clients simultaneously. All updates are applied instantly and rolled back if rejected by the server due to ownership issues.
- Only supported primitives (like int, float, etc.) can be serialized in models. If you need to sync more complex data, break it down into supported fieldsCommon Questions.
- Do not use standard C# collections like Dictionary<> or List<> for synchronization, as Normcore cannot track their changes automatically. Use RealtimeDictionary, RealtimeSet, or other provided collections insteadCollections.
For more details, see the RealtimeDictionary reference and the Common Questions section in the docs.
If you need a concrete example or run into a specific error, please provide your code snippet or error message for more targeted help!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@446432643115122688> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
This has ended up being more complicated than I expected. Things like late joiners, lobby switching, etc, all affect this and it's common for health to get out of sync across certain client connections
If anyone has had experience with this specific concept in Normcore I'd definitely appreciate some pointers to make it bulletproof
if you disconnect from a room then all the data stored in it will be gone
if you want to retain player health data between scenes you can have a seperate realtime for avatars and one for scenes
then the stored player health data will persist as you don't disconnect from the avatar room
late joiners should still see all the data store in the dictionary
I dont need to retain between scenes or anything, I just want it to reliably work in one scene but I think the way I'm setting it up is the issue.
I have the "player health" on the realtimeavatar and I'm wondering if this isnt the right approach. It involves sending requests to the owner and it seems to convoluted that I'm not even sure where its breaking
yeah the dictionary should be unowned and off the avatar so anyone can access it without telling the owner to do it
here's an example for a leaderboard but you can swap score for health https://gist.github.com/d12/f577bb50b0fdeeb17084819c78fe5c43
Gist
How to use RealtimeDictionary
How to use RealtimeDictionary. GitHub Gist: instantly share code, notes, and snippets.
Interesting, I did see that post but I'll give it another shot. Thanks!