Octoyisus
Octoyisus2w ago

Quiz answer synchroinization

Hi everyone, I have a question. I have this feature in which the users need to answer questions from a quiz. Any user in the room can answer, and the results are shown to everyone.   Currently, I'm synchronizing with a model that uses two ints one to store the selected answer's index and another one just to increase it and use the didChange callback to process the result in each client. The issue is that sometimes the callback value is modified first and the called is launched before the answer value has been setted. I've managed to work around this problem by waiting a couple of milliseconds before updating the callback value. Is there any better way of doing this?
9 Replies
kapa.ai
kapa.ai2w ago
Hi @Octoyisus. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the knowledge sources, I can offer some guidance on how to better synchronize quiz answers in NormalVR. Your current approach using two integers in a model is on the right track, but there's a more robust way to handle this synchronization. Instead of using separate integers and relying on callbacks, you can create a custom RealtimeModel for your quiz answers. This approach is described in the Synchronizing Custom Data guide. Here's a suggested approach: 1. Create a custom RealtimeModel for your quiz answers:
[RealtimeModel]
public partial class QuizAnswerModel
{
[RealtimeProperty(1, true)]
private int _answerIndex;

[RealtimeProperty(2, true)]
private int _answerSubmissionId;
}
[RealtimeModel]
public partial class QuizAnswerModel
{
[RealtimeProperty(1, true)]
private int _answerIndex;

[RealtimeProperty(2, true)]
private int _answerSubmissionId;
}
2. Create a RealtimeComponent to manage this model:
public class QuizAnswerSync : RealtimeComponent<QuizAnswerModel>
{
private void ProcessAnswer()
{
// Process the answer here
Debug.Log($"Answer submitted: {model.answerIndex}");
}

protected override void OnRealtimeModelReplaced(QuizAnswerModel previousModel, QuizAnswerModel currentModel)
{
if (previousModel != null)
{
previousModel.answerSubmissionIdDidChange -= AnswerSubmissionIdDidChange;
}

if (currentModel != null)
{
currentModel.answerSubmissionIdDidChange += AnswerSubmissionIdDidChange;
}
}

private void AnswerSubmissionIdDidChange(QuizAnswerModel model, int value)
{
ProcessAnswer();
}

public void SubmitAnswer(int answerIndex)
{
model.answerIndex = answerIndex;
model.answerSubmissionId++; // Increment to trigger the change event
}
}
public class QuizAnswerSync : RealtimeComponent<QuizAnswerModel>
{
private void ProcessAnswer()
{
// Process the answer here
Debug.Log($"Answer submitted: {model.answerIndex}");
}

protected override void OnRealtimeModelReplaced(QuizAnswerModel previousModel, QuizAnswerModel currentModel)
{
if (previousModel != null)
{
previousModel.answerSubmissionIdDidChange -= AnswerSubmissionIdDidChange;
}

if (currentModel != null)
{
currentModel.answerSubmissionIdDidChange += AnswerSubmissionIdDidChange;
}
}

private void AnswerSubmissionIdDidChange(QuizAnswerModel model, int value)
{
ProcessAnswer();
}

public void SubmitAnswer(int answerIndex)
{
model.answerIndex = answerIndex;
model.answerSubmissionId++; // Increment to trigger the change event
}
}
This approach ensures that both the answer index and the submission ID are updated atomically. The AnswerSubmissionIdDidChange event will only be triggered after both values have been updated, solving your synchronization issue. To use this in your game, you would attach the QuizAnswerSync component to a GameObject in your scene, and call the SubmitAnswer method when a user selects an answer. This solution leverages Normcore's built-in synchronization capabilities and avoids the need for manual delays. It's a more robust and reliable way to handle real-time synchronization of quiz answers across multiple clients. For more details on creating custom RealtimeComponents and Models, refer to the Synchronizing Custom Data guide. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@286884711874166784> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit2w ago
yield one frame or wait till end of frame
Octoyisus
OctoyisusOP2w ago
Will that work always? I mean does not the time needed to ensure the first value has been updated depend on the connection quality or other factors?
Mechabit
Mechabit2w ago
they go out in the same packet but deserialise in a random order it will always be there in the same frame
Octoyisus
OctoyisusOP2w ago
And if I wait a frame they ll be sended on thwo different packets?
maxweisel
maxweisel2w ago
I don't think I fully understand the issue. Why is the callback value modified first? Are you changing the value before someone tries to answer a question?
Mechabit
Mechabit2w ago
what you want to do is send both the answer and the callback at the same time but wait till the end of frame to read both
Octoyisus
OctoyisusOP2w ago
I meant in the receiving client, sorry for not being more clear This actually sounds pretty good and makes a lot of sense. Thanks a lot

Did you find this page helpful?