How to simulate a game scene instantly?

I’m developing a game where you have to catch a toy to win a prize and I need to make sure that the user actually caught the toy on my server when he sends a request that he caught it. On my server, I receive a request from the user that contains frame-by-frame information about what he did in the game, then I create a Unity instance when the user wins and there I simulate the data that the user sent. I need the game to “replay” and I can see the result of the outcome.

Now i do it like this:

private void Start() {
    Physics.simulationMode = SimulationMode.Script;
    StartCoroutine(Simulate());
}

private IEnumerator Simulate() {
    GameObject machine = Instantiate(machinePrefab);
    MachineController controller = machine.GetComponent<MachineController>();
    APIMachineControlStateRequest request = JsonUtility.FromJson<APIMachineControlStateRequest>(json);
    controller.SetSimulate(Physics.defaultPhysicsScene);
    foreach(MachineControlState state in request.value) {
        controller.SetState(state);
        Physics.Simulate(Time.fixedDeltaTime);
        yield return new WaitForFixedUpdate();
    }
}

Everything works great, the simulation works, but you have to wait as long as you use the game…
I tried set the Time.timeScale to 20f and this speed up the process (when 30f this not working), all okey, but this looks like a mistake and in production such a solution is not good.

How to implement my task correctly and so that it is immediate?

You can’t do anything “instantly” or “immediate” in a computer, you can only do it as fast as the computer can perform the operation. This means that if you have 5 seconds worth of time to simulate but the computer takes 0.4 real-world seconds to perform the simulation, you can’t do anything to complete the task in less than 0.4 seconds.

This said: if you want to put all available resources into the simulation and finish it as soon as possible, just simulate more than once per frame:

while (timeToSimulate > 0)
{
Physics.Simulate(Time.fixedDeltaTime);
timeToSimulate -= Time.fixedDeltaTime;
}

This doesn’t make sense in your case. You’re simply skipping simulation steps, which will cause the simulation to break. The actual problem with your code is you’re waiting at least a full frame between simulation steps by using WaitForFixedUpdate(), so if you have 5 seconds worth of physics to simulate, it will take 5 seconds to complete it. Doing all steps back to back in a single frame (hence the while loop) will complete the task faster - but block the main thread until it’s done.