about Serialize Coroutine.

I’m making a PVP game going on the network (like Clash Royal …)
When two people are playing (A, B), one (B) closes the app completely and then reconnects again
The problem is that you have to restore the same client state as the other one (A).
Theoretically, when B connects, it binds the values ​​of all objects that A has at the moment
It is a simple matter to restore it after sending it to B.
But there is one problem here, coroutines.
How can I restore the coroutine from A to B in the same way?
The variables declared inside the coroutine must also be restored to the point where the coroutine is running
This is the same problem that needs to be restored.
I wonder if there is a way to solve this problem in the Unity engine.

Coroutines are a bit tricky. Perhaps you should first understand, what they really are.
When you call a method that uses the yield keyword, you are actually creating an instance of a compiler-generated class. It’s called a generator, and it’s uses go far beyond coroutines. This class works as an Enumerator, which means you can eg. use it in a foreach loop, or use the enumerator interface directly.
The generated class contains the local variables, plus a variable which says where in the generator code the execution stopped. More specifically, it’s an integer, marking which ‘yield’ keyword was reached the last and where will it continue next time, implemented as a switch.
Now each time you enumerate the object, it executes part of the code, and the enumerator yields the new value (which would eg. be used in the foreach loop).
Now the coroutines: What unity does, is that it takes control over the enumeration, and watches the yielded value. When it’s something the engine recognizes (eg. WaitForSeconds) it will store the enumerator for the later use, remembering what to do with it. For example, enumerating it once more after the given time.


Now what does this all mean to you:
You’ve given the control of the enumerator to the engine when you called StartCoroutine(). The engine holds the enumerator and its last yielded instruction, and you have no reach to it. You don’t know, how much time is left on the WaitForSeconds, for example.
Another problem is, that the generator class produced by the compiler is non-serializable. You cannot just take it and feed it to a serializer. You’d have to serialize it by your own code, perhaps using the reflection. It’s not impossible.
But the first point, the engine blackboxing the coroutine execution, that’s a main problem.


So what can you do? Here are some options I can think of now

  1. Don’t use coroutines for shared states, only for local / clientside stuff.
  2. Write your own coroutine engine. It’s not as hard as it may sound, and you will have a full control over its execution, allowing you to restore the state to whatever you want