I was just wondering what the easiest way to sync a pulse engine simulation across multiple users would be. (Using the unity integration for pulse)
Initially, I thought about using a synced networked room time value to start the simulation and set the time accordingly to match but I wasn’t sure if there was any random variation that would still cause differences.
Ideally, it would also be great if someone who joined late would still be in sync. So their sim would be able to apply a log of all pulse actions to their local sim at the specified times it happened, before syncing to the network room’s timestamp.
I’m not sure if this is something I’m overcomplicating - but ideally, I would like each local client to run the sim themselves so that leaving/joining the room does not impact the simulation for others.
There are 2 ways you can approach this.
Run each Pulse patient/engine on a server. Only the server is simulating. Each client can push actions to the server to change the patient. These actions would be applied to the simulation running on the server. The server can process Pulse data and send out vitals information to each client to render/process. This would easily allow clients to dynamically enter/exit the scenario with ease. New clients would just recieve vitals info to render like any other client.
Each client has its own simulation instance. This is much more complicated, but has been done, and seems to work well. But you need a lot of infrastructure to sync all engine instances. You will still need to broadcast out actions to apply to Pulse and listeners will need to apply them at the same time for engines to stay in sync. Maybe you always time stamp an action to be applied in 5 seconds, so that gives the network enough time to properly propagate to all clients and for clients to queue actions to be applied at the same time. You would probably need a frame lock to ensure each client simulates at the same speed, even on different hardware. (Unity should already have this, but I’d want to double check things don’t get out of sync after 5 or 10min of simulation)
For either approach, broadcasting actions is required. Pulse uses Protobuf under the hood, so you can easily serialize action information in a network compliant format (json or binary), and easily reform those back into the Pulse API to be applied.
Thanks for your timely response!
I appreciate the detail, I’m going to look into the idea of queing actions to apply based on a networked room time - as this would fit into the app well.
In regards to the engine in unity, is there any functionality for writing data to a csv that’s built in? This could be useful to sense check the simulations over 10/20 minute periods
When you set up the data requests you want from Pulse, you can also provide a csv file that Pulse will automatically write those values to every time step
You also have the ability to save the entire state of the engine to a json or protobuf binary file (use .json for a json file, and any other extension for binary)
You can then pass that over to another machine for them to initialize an engine with that exact same state
you can also read/write the state from/to a buffer if you don’t want to rely on a filesystem and directly pass data over a network socket
Its all setup and working really well so thankyou for your help!
I did have another small query. In the case that via the unity API I apply oxygen, by created a new SESupplementalOxygen and get the engine to process this. How would I then remove this action? for example if a user removes an oxygen mask from the patient?
got it! - thats what I was currently doing, just wanted to check I didn’t need to dispose of anything. Thanks