gschup / ggrs

GGRS is a reimagination of GGPO, enabling P2P rollback networking in Rust. Rollback to the future!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ability to simulate poor network conditions

shelbyd opened this issue · comments

Is your feature request related to a problem? Please describe.
To make a high quality, robust game, I need to be able to experiment with how it works when the local or remote player(s) have poor network conditions.

Describe the solution you'd like
I would like some mechanism to hook into the ggrs protocol and interfere with packet arrival or contents. The most flexible interface would probably be something like:

trait Interference {
  fn interfere(&mut self, session: &P2PSession, packet: Packet) -> PacketBehavior;
}

enum PacketBehavior {
  Drop,
  Process(Packet),
  Delay(Packet, Duration),
}

P2PSession having an Option<Box<dyn Interference>> field shouldn't affect performance when not using interference (as the compiler should be able to see it's always None and remove related checks.

Having it as a trait will let users override with their own impl to test the cases they're interested in. We can include some basic impls for common cases as well.

Describe alternatives you've considered
There are existing tools that interact at the ethernet or OS layer, but they are general purpose (possibly not allowing for specific problems) and difficult to configure (requiring hardware or OS-level interfacing, making it difficult for a team to have a consistent setup). Additionally, much testing is done by running multiple instances on one machine, making it unclear if OS or eth level interference would even work.

Additional context
I'm happy to implement this, I'd just like some guidance around the interface and then some guidance around where I should be changing things.

To emulate poor network conditions, I recommend using clumsy! It's a very easy-to-use tool for a lot of different networking use cases.

https://jagt.github.io/clumsy/index.html

Do you see any advantages adding this kind of network emulation to the library?

I definitely would prefer something like this to be hidden behind a feature flag so it does not bloat the library unnecessarily.

That looks like a really useful tool. Having an OS level interference still has the problems I originally outlined.

I did just consider that if ggrs allowed overriding the transport, then this could be easily accomplished at a lower level. And ggrs does, with P2PSession::new_with_socket. So for posterity, I would recommend using that method and providing a custom (crappy) socket to simulate what you'd like to.

I may create a crate for that. If I do, I'll try to remember to post it here.

Writing a struct with impl NonBlockingSocket would definitely be the cleanest approach. We could also consider adding it to the library. Currently, GGRS only provides a single socket, but having a TurbulenceUpdSocket might be useful.