Skip to content
faf5678 edited this page Nov 13, 2014 · 3 revisions

Overview

Desyncs can probably be avoided if FA.exe is kept isolated from any disconnect events. The lobby will detect end of stream from the disconnecting peer, silently discard that package and from there start generating the packets that the peer would have sent if it was still connected. There will be N lobbies running and each will independently simulate the missing peer to its associated FA.exe.

What needs to be generated

The simplest information to generate are the desync detection hashes. The simulator waits for the local FA.exe to send out its own hash to all peers and then pretends that it calculated the same hash and sends it back.

The simulator will advance its simtick counter whenever the local FA.exe does the same and thus be in sync. Note that this means that there is no guarantee that all remaining FA.exe will receive the ADV command at the same time (relative to all other simticks) as each simulator is synchronized to a different FA.exe, but this is not gonna be a problem as it is already the case due to differences in network distance between normal peers. The same strategy of locking onto the local FA.exe as a reference is used for the C33 and C34 commands, which presumably inform about what simticks are finished executing and not accepting more input respectively.

Generally speaking, when or in which order simticks are advanced or acknowledged should not matter.

Finally the ACK command is handled similarly: whenever the local FA.exe redistributes any ACK that it received to the simulator, the simulator will pretend that it received the ack itself and will re-send those ACKs to the local FA.exe.

If there are two simulators running, forward progress is guaranteed, because the ADV is tied to the ADV of the local FA.exe and the simulators all ACK their own ADV command and so the local FA.exe will make the 2 simulators ACK their respective simticks by distributing the ACK-after-ADV to them.

The fact that the distributed simulated peers do not agree amongst themselves in what simtick they currently are or which ACKs they currently have received does not matter at all as they are not introducing any commands into any of the simulations.

In fact there is no such thing as a consistent state of an arbitrary peer A as seen from any other peer B, C, D as it depends on the network distance between them.

Determining the current simtick of disconnected peer

The lobby could either keep track of the simtick increses of each remote peer or, more efficiently, store the last few command packets that it received. Then after a EOF from a peer it can find the current simtick by scanning those packets for ACK-after-ADV and in general for all ACKs of all peer simticks and catch up to the state the lost peer was in.

TL;DR

the peer simulator receives all 0x03, 0x33, 0x34 from the local FA.exe and sends them back with the same hash/simtick. The simulator receives any ACKs from the local FA.exe and sends them back. The simulator receives ADV from local FA.exe and sends its own ADV and generates an ACK for its own simtick (which is basically the only state variable the simulator updates).

Reality bites

It may be necessary to echo more: Pause/Unpause events. Hopefully these can all be handled as above: by simply taking local FA.exe as reference.