MasterOX 水
MasterOX 水2mo ago

sync game states

i want to sync game states (game started, ended,etc...) between the clients. whats the best way of doing this
19 Replies
kapa.ai
kapa.ai2mo ago
Hi @MasterOX 水. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- In NormalVR, you can synchronize game states using the room's datastore. When you need to change a state, you modify it in the datastore. The datastore will automatically detect any changes and notify all clients connected to the room so they can update their world to match. This is particularly useful for keeping game states in sync across all clients. For example, if you have a game state like "game started" or "game ended", you can represent this state in the datastore. When the game starts or ends, you change this state in the datastore. All connected clients will be notified of this change and can update their local game state to match. Here's a simple example of how you might do this: 1. Create a RealtimeModel to represent your game state. This could be a simple class with a single bool property to represent whether the game has started.
[RealtimeModel]
public partial class GameStateModel {
[RealtimeProperty(1, true)] private bool _gameStarted;
}
[RealtimeModel]
public partial class GameStateModel {
[RealtimeProperty(1, true)] private bool _gameStarted;
}
2. Create a RealtimeComponent that uses this model. This component can be attached to a game object in your scene. When the game state changes, this component updates the model. When the model changes, the component updates the game state in your scene.
public class GameState : RealtimeComponent<GameStateModel> {
public bool gameStarted {
get {
// Return false if we're not connected to the room yet.
if (model == null) return false;

// Return the current game state
return model.gameStarted;
}
}

public void StartGame() {
model.gameStarted = true;
}
}
public class GameState : RealtimeComponent<GameStateModel> {
public bool gameStarted {
get {
// Return false if we're not connected to the room yet.
if (model == null) return false;

// Return the current game state
return model.gameStarted;
}
}

public void StartGame() {
model.gameStarted = true;
}
}
In this example, when you want to start the game, you call the StartGame method on the GameState component. This updates the gameStarted property in the GameStateModel, which is automatically synchronized to all connected clients. When other clients receive this update, their GameState component will see that the gameStarted property has changed and can update the game state in their local scene. For more information, you can refer to the Normcore Documentation (https://normcore.io/documentation/architecture/client#datastore). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@758040514678489279> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mechabit
Mechabit2mo ago
Synchronizing Custom Data | Normcore Documenation
In this guide, I’m going to walk you through how to synchronize custom data in your Unity application using custom realtime components.
Mechabit
Mechabit2mo ago
but you can swap colour for an enum of game states
MasterOX 水
MasterOX 水2mo ago
yeah i saw that, but i think its a bit confusing ( didnt really understand what variable got synced) this explains it better. @Normcore Assistant can you explain this line and its parameters? [RealtimeProperty(1, true)]
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The [RealtimeProperty(1, true)] is an attribute used in Normcore to define a property that should be synchronized across the network. The RealtimeProperty attribute takes two parameters: 1. The first parameter is a unique identifier for the property. This should be a unique number within the class. In this case, the identifier is 1. 2. The second parameter is a boolean that specifies whether the property should be reliable. If set to true, Normcore will ensure that all changes to the property are received by all clients, even if some packets are lost. If set to false, Normcore will not guarantee that all changes are received. This can be useful for properties that change frequently and where it's not critical that every change is received, such as the position of a player in a fast-paced game. Here's an example:
[RealtimeModel]
public partial class GameStateModel {
[RealtimeProperty(1, true)] private bool _gameStarted;
}
[RealtimeModel]
public partial class GameStateModel {
[RealtimeProperty(1, true)] private bool _gameStarted;
}
In this example, _gameStarted is a property that will be synchronized across the network. The 1 is its unique identifier, and true means that all changes to _gameStarted will be reliably delivered to all clients. For more information, you can refer to the Normcore Documentation (https://normcore.io/documentation/guides/creating-a-multiplayer-drawing-app#models). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@758040514678489279> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mechabit
Mechabit2mo ago
there's a 3rd parameter for change event callbacks if you want to get an event when someone makes a change to the property [RealtimeProperty(1, true, true)] will generate an event called gameStartedDidChange
MasterOX 水
MasterOX 水2mo ago
ty, also, just to be sure, do i put the other start game logic in StartGame()?
Mechabit
Mechabit2mo ago
you can if you want, just know that you will only sync properties in the model if you want to sync more things you have to add it to the model
MasterOX 水
MasterOX 水2mo ago
yep i think i got it ill try to see if it works
Andrei Vaduva
Andrei Vaduva2mo ago
sorry to bump this thread a bit, but if, for example, i have 5 properties, how would i know when all the variables have been synced? If i try with events, when the event for property 1 is fired, properties 2-5 are not set, so from what i can tell it sets a variable and then fires the event. I need an event/callback that tells me when all the model variables have been synced. Is there anything like this? @Normcore Assistant
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, Normcore does provide a way to handle this. When Normcore serializes all updates once per network frame (~20hz) and groups them into the same packet, the model updates are applied one at a time, and a change event fires for each value. However, it's possible the other values from that packet hadn't yet been applied when the event for the first property is fired. To get an event that fires once all updates have been applied to a model, you can use RealtimeCallback. This is a special attribute that you can add to a method in your model. When all updates have been applied, Normcore will call this method. This can be useful if you need to perform some action after all properties have been updated. Here's an example of how you might use it:
[RealtimeModel]
public partial class MyModel {
[RealtimeProperty(1, true)] private string _name;
[RealtimeProperty(2, true)] private Color _avatarPrimaryColor;
[RealtimeProperty(3, true)] private Color _avatarAlternateColor;
[RealtimeProperty(4, false)] private Vector3 _movementVelocity;

[RealtimeCallback]
private void OnAllPropertiesUpdated() {
// All properties have been updated.
// You can perform some action here.
}
}
[RealtimeModel]
public partial class MyModel {
[RealtimeProperty(1, true)] private string _name;
[RealtimeProperty(2, true)] private Color _avatarPrimaryColor;
[RealtimeProperty(3, true)] private Color _avatarAlternateColor;
[RealtimeProperty(4, false)] private Vector3 _movementVelocity;

[RealtimeCallback]
private void OnAllPropertiesUpdated() {
// All properties have been updated.
// You can perform some action here.
}
}
In this example, the OnAllPropertiesUpdated method will be called after all properties have been updated. You can put any code you want in this method to perform some action after all properties have been updated. For more information, you can refer to the Normcore 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: ----------------------
kapa.ai
kapa.ai2mo ago
<@1217086475661738045> kapa.ai is still learning and improving, please let us know how it did by reacting below
Andrei Vaduva
Andrei Vaduva2mo ago
yeah, that doesn't work :))
Mechabit
Mechabit2mo ago
if you set all the properties at the same time they will all go out at the same time the events fire one at a time
Andrei Vaduva
Andrei Vaduva2mo ago
that's what i thought and that's what i'm doing, but when each event is fired, the other variables on the model are not set
Mechabit
Mechabit2mo ago
it'll fire event 1 then event 2 but if you wait till the end of frame they will all be there you can add a yield return new WaitForEndOfFrame
Andrei Vaduva
Andrei Vaduva2mo ago
they are ordered so i could get around with a "all_sent" property that i always send last ok, thanks for the info, i'll try the end of frame