How to update a element in a realtimeArray for all clients?
I currently have a realtimeArray of a Vect2 within another Sync script. On a fresh model I loop through the number of players I want the array to account for and I Add a new Vect2 Model to it then subscribe the index to the DidChange events I want. The onChange event does fire locally but it doesn't sync the data of the array to other clients.
Should I add the realtimeArray of Vect2 to the model of the Sync script that holds it? I know that I'm subscribing to the event and that the DidChange event fires locally but it never syncs the array to other players. How do I ensure that the synced data goes to every client?
11 Replies
Hi @Funkey. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
The
RealtimeArray
in Normcore is a special model type that holds a sequential list of models that can be modified at runtime. When you modify the array, it sends the minimal amount of information necessary for other clients to replicate the change. The whole collection is not sent every time. This means that changes to the array should be automatically synced to all clients.
However, there are a few things you need to ensure for the syncing to work correctly:
1. The RealtimeArray
should be part of a RealtimeModel
. If it's not part of a RealtimeModel
, it won't be synced across clients.
2. Updates to RealtimeModel
objects appear to take effect immediately for the local client, and change events also fire immediately for the local client. However, the server might 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. Change events then fire again to reflect the new values.
3. Normcore serializes all updates once per network frame (~20hz) and groups them into the same packet. When model updates are applied, they’re applied one at a time, and a change event fires for that value. However, it’s possible the other values from that packet hadn’t yet been applied. In order to get an event that fires once all updates have been applied to a model, use RealtimeCallback
.
4. If you're adding elements to the RealtimeArray
, you should use the Add
method. This appends a RealtimeModel
to the end of the array. Add operations take effect instantly. If the server rejects a change (due to ownership) the model will be removed.
5. If you're trying to update an element at a specific index in the RealtimeArray
, you should retrieve the model at that index using the Item
property, and then modify the model. The changes to the model should then be automatically synced to all clients.
Here's an example of how you can add a model to a RealtimeArray
and listen for changes:
Sources:
- RealtimeArray Documentation (https://normcore.io/documentation/reference/classes/Normal.Realtime.Serialization.RealtimeArray%601)
- Instant Updates Documentation (https://normcore.io/documentation/room/datastore#instant-updates)
- Common Questions Documentation (https://normcore.io/documentation/room/common-questions#sometimes-when-i-log-the-values-on-my-model-from-inside-of-valuedidchange-not-all-the-values-that-i-set-on-another-client-update-when-are-updates-sent-out-and-how-are-they-applied)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant
c#
Would something like this work then? The model now has the realtimeArray called players and I'm subscribing to it's event on a fresh model like this.
c#
Then above is how I'm handling the change.
Let me check the knowledge base for you. One moment! :books:
----------------------
Yes, your approach seems correct based on the information provided in the knowledge sources.
You are creating a
RealtimeArray
of PlayerModel
in your RealtimeModel
and adding a new PlayerModel
for each player. You are also correctly subscribing to the readyDidChange
event for each PlayerModel
in the array.
When the readyDidChange
event is fired, you are finding the index of the player whose ready
status changed, and then updating the ready
status of the player at that index in the _players
array.
Here's a simplified version of your code:
This code should work as expected, as long as the _players
array is kept in sync with the players
RealtimeArray
in the RealtimeModel
.
Sources:
- RealtimeArray Documentation (https://normcore.io/documentation/reference/classes/Normal.Realtime.Serialization.RealtimeArray%601)
- RealtimeModel Documentation (https://normcore.io/documentation/room/realtimemodel#change-event)
- RealtimeComponent Documentation (https://normcore.io/documentation/realtime/synchronizing-custom-data#creating-a-realtimecomponent-subclass)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant The code I provided in the last example doesn't seem to work. I get an error when I attempt to index into the array.
Let me check the knowledge base for you. One moment! :books:
----------------------
I'm sorry to hear that you're encountering an error. Based on the information provided, it's difficult to pinpoint the exact issue without more details about the error message or the context in which the error occurs. However, here are a few general suggestions that might help:
1. Check the size of the array: Ensure that the
_players
array has been properly initialized and that it contains the expected number of elements. If you're trying to access an index that is outside the bounds of the array, you will get an IndexOutOfRangeException
.
2. Check the index value: Make sure that the index
value you're using to access the array is valid. If the index
value is negative or greater than or equal to the length of the array, you will get an IndexOutOfRangeException
.
3. Check the array initialization: Ensure that the RealtimeArray
of PlayerModel
is properly initialized in your RealtimeModel
. If the array is null
, trying to access it will result in a NullReferenceException
.
4. Check the event subscription: Make sure that the readyDidChange
event is properly subscribed to for each PlayerModel
in the array. If the event is not firing as expected, the ReadyDidChange
method will not be called, and the ready
status of the players will not be updated.
If you're still encountering issues, I would recommend checking the Normcore Documentation (https://normcore.io/documentation) for more information, or joining the Normcore Discord (https://normcore.io/discord) to ask for help from the community.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant
So it's acting like the data is syncing but the onChange doens't fire across all clients. It seems that the data is being synced based off behavior but I'm looping through the synced array to verify values onChange and logging them. The debugLog only fires on the client that changes the value and it doesn't account for everyone else's changed values.
Let me check the knowledge base for you. One moment! :books:
----------------------
Based on the information provided, it seems like the
readyDidChange
event is only firing locally and not on all clients. This could be due to a few reasons:
1. Event Subscription: Ensure that the readyDidChange
event is subscribed to on all clients. If the event subscription only happens on one client, the event will only fire on that client.
2. Data Synchronization: Normcore serializes all updates once per network frame (~20hz) and groups them into the same packet. When model updates are applied, they’re applied one at a time, and a change event fires for that value. However, it’s possible the other values from that packet hadn’t yet been applied.
3. Server Rejection: Updates to RealtimeModel
objects appear to take effect immediately for the local client. However, the server might 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. Change events then fire again to reflect the new values.
If you're still encountering issues, I would recommend checking the Normcore Documentation (https://normcore.io/documentation) for more information, or joining the Normcore Discord (https://normcore.io/discord) to ask for help from the community.
Sources:
- Common Questions Documentation (https://normcore.io/documentation/room/common-questions#sometimes-when-i-log-the-values-on-my-model-from-inside-of-valuedidchange-not-all-the-values-that-i-set-on-another-client-update-when-are-updates-sent-out-and-how-are-they-applied)
- Instant Updates Documentation (https://normcore.io/documentation/room/datastore#instant-updates)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below