Skip to content
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

📶 Network Performance #790

Open
zicklag opened this issue Jun 2, 2023 · 3 comments
Open

📶 Network Performance #790

zicklag opened this issue Jun 2, 2023 · 3 comments
Labels
kind:tracking An issue used to track development, usually containing links to other issues that will be worked on.

Comments

@zicklag
Copy link
Member

zicklag commented Jun 2, 2023

This issue is to track networking performance improvement efforts until we get it to a place where we think it should be and is sufficient for normal play.

@zicklag zicklag added the kind:tracking An issue used to track development, usually containing links to other issues that will be worked on. label Jun 2, 2023
@zicklag
Copy link
Member Author

zicklag commented Jun 2, 2023

One thought that might be causing lower-than-expected networking throughput is the fact that we are currently sending inputs as raw datagrams, without making sure that they fit into the MTU. We may need to fragment the packets to fit them into the MTU and avoid them being dropped.

@erlend-sh
Copy link
Member

I asked @maniwani for advice and they shared some preliminary thoughts:

I can think of some usual suspects for stuttering

GGRS has a fixed-timestep simulation. To render that smoothly, you can either:

  1. Interpolate
  • Save the current (tick N) and previous (tick N - 1) simulation state. Every frame, render the output of interp(state N - 1, state N, percent), where percent is the time remaining in the fixed timestep's accumulator divided by the timestep.
  • If you wanted to avoid the one tick of interpolation delay, you can have your clients always predict an additional tick further into the future (tick N + 1), so that every frame you can render the output of interp(state N, state N + 1, percent).
  1. Substep
  • Every frame, after client has advanced their simulation 0+ ticks, restore their state to the latest "full" tick (tick N), then simulate one additional "partial" tick using the time remaining in the fixed timestep's accumulator as dt. Render the output.
    To do any of these, notice you'll need copies of the state.

It's good that you use the unreliable QUIC channel to exchange inputs, so I think we can rule it out.

I can't remember if having too many ticks to resimulate can cause stuttering, but if it does, there's stuff you could do. Since you have a client-server network / client traffic goes through the server, I'd recommend making the server responsible for:

  • Being the anchor/reference for clients to synchronize their simulation clocks.
  • Retransmitting inputs.
    • It'll be faster than if clients had to do it. The sooner inputs arrive, the less clients will need to resimulate.
  • Enforcing a late cutoff for inputs.
    • Basically, if the server does not receive a client's input for tick N in time, it'll reuse their tick N - 1 input. If the input for N arrives late, the server will ignore it. Having a cutoff prevents bad/struggling clients from increasing the number of ticks the others have to resimulate.

@zicklag
Copy link
Member Author

zicklag commented Jun 3, 2023

Very useful thoughts. I've considered doing interpolation before, and substep sounds like a cool and simple idea, too.

Having the server responsible for some stuff is a very interesting idea. That might require some collaboration and changes in GGRS, but it could be quite useful.

I still think there's a fundamental network transport issue somewhere, especially since the GGRS author said that they got a smooth gameplay before over the internet ( not sure with what game ). I want to try to tackle that first.


The next step for this I think is to create a networking transport trait that we can use throughout the game that will allow us to easily swap out the piece of our networking stack that is repsonsible for sending raw messages.

This will allow us to:

  • Test out different transport implementations, such as alternative QUIC implementations, renet etc. without having to change the game, which may help us troubleshoot and see there are performance problems with the QUIC library/configuration we are using.
  • Support networking on the web by having a different transport implementation for browsers.
  • Support networking on steam, by using the steam transport.

It shouldn't be a huge deal to setup, because we will just be taking our existing logic and doing a one-time transition to use our new NetworkTransport structs/methods instead of it being hard-coded to use the quinn structs/methods.


After we get that setup, then I think I should also make a debug window that we can use to test the network bandwidth, to see how many megabits we can send over the transport if we send stuff as fast as we can. That should help tell us if there is a serious issue with our transport speed.

@zicklag zicklag pinned this issue Jun 17, 2023
@zicklag zicklag changed the title Network Performance 📶 Network Performance Jun 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:tracking An issue used to track development, usually containing links to other issues that will be worked on.
Projects
None yet
Development

No branches or pull requests

2 participants