-
Notifications
You must be signed in to change notification settings - Fork 258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for netplay input delay. #819
base: master
Are you sure you want to change the base?
Conversation
I'm not sure what performance is to be gained here. In order for the game to advance a frame, it needs the inputs from all players. So having the local player's inputs registered early isn't going to allow the game to advance any quicker. The other potential issue is desyncs (unless I missed something). The local player never re-sends inputs, so if it registers "A" for frame 123, but that never arrives at the server, the server needs to make an assumption about what the input should be. The m64p server just copies the previous frame's inputs, but if that differs from what the local player registered, it will desync. p2p is essentially a game where 1 of the players is hosting the server locally. In that case, the round trip time for that player's inputs would be <1ms, so I don't think there would be anything to be gained there either. |
Thanks for your comments - am happy to discuss this over Discord, too, if that would help clarify. I believe this change does have performance benefits, and also would be needed for a p2p (and maybe rollback) implementation.
Inputs for a frame don't arrive in the same packet / udp datagram for all players, so it's possible for you to have all inputs for your opponents, but be waiting on the network for your own inputs.
This is not true of m64p-netplay-server with fixed input delay. It never copies inputs for fixed input delay games, but rather it always waits for the client to send them.
With two player p2p, you can halve the input delay by not waiting on the host server to send your own inputs back to you, since it is unnecessary for the input to make a roundtrip. Instead, the inputs are traveling one-way in each direction. Consider the following example, where two players have a ping of 45ms to a server and also a ping of 45ms to each other. Server
Total Duration: 90ms P2P
Total Duration: 45ms |
Sorry yes I hadn't considered that neither player would need to receive their own packets in a p2p game. However it seems like that benefit would diminish with a 3rd and 4th player.
I don't think this is true currently, see: The current core implementation has no method for retransmitting inputs. The server has no way to signal to the client "I never received inputs for frame 123, please resend". I think that would need to be implemented alongside this change (or before it).
While this is true, the packets are being sent from the same source, and to the same destination, so any variance between arrival times for each player should be extremely minimal. |
Agreed, 3+ players wouldn't be able to do this.
Ah I didn't realize that was happening! Thanks for the link to the code - I see what's happening there. I agree that the "please retransmit" feature is needed to avoid desyncs, and am happy to spend some time on it. To implement that, the netplay client would need to store the previous inputs for a while before discarding them, which I don't think it currently does. Perhaps it should store 10ish frames of previous inputs in a linked list, in case the server asks for them? |
Choosing arbitrary values can be a little risky and could lead to instability (you never know how long somebody might hang/lose internet for). It would probably be better to just hold on to the input locally until it hears about that input from the server (once the server sends that input to the client, the client knows it's been received/registered with the server, thus there is no longer a need to retain it locally) |
This is an improved version of #799. The primary goal of the change is to improve performance of netplay when using fixed input delay. By informing mupen64plus-core of the input delay, the client is able to be the source of truth for local player inputs instead of having to wait on the server for local inputs.
One thing to note about the implementation here - mupen core is still sending the original count to the server instead of the adjusted-for-input-delay count. This is perhaps something that could be changed later on, but I didn't want to change it now since it would have been a breaking change.
This change also could help with a future p2p implementation, as two player p2p relies on the client using local inputs without waiting on the network to enjoy the perf benefits of p2p.
I made this change as part of some work on m64p - here's the corresponding change there: https://github.com/m64p/mupen64plus-gui/pull/70/files
cc @loganmc10