Skip to content

Allow multiple instances to run and connect to each other for debugging #407

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

helmutbuhler
Copy link

@helmutbuhler helmutbuhler commented Mar 11, 2025

This adds a define ENABLE_FAKE_IP which can be used to build in a way that allows multiple instances to run on the same computer and connect to each other, as if the instances connect in a LAN.

Preview video

Note that this PR only changes the code when the #define is set. So it doesn't actually change anything for the final build. But if the goal for the first patch is to fix network bugs, I believe this could help other developers to tackle those.

See also the following description:

// The following define controls whether fake ips are enabled
// If it's enabled, it changes the behavior of the game in some ways:
// - The game can be started multiple times on the same machine.
// - It can be called with the commandline -fakeip 1 (or some other number),
//   assigning it a fake ip.
// - Multiple instances with fake ips can communicate with each other on the
//   same machine, as if they are communicating in a LAN.
// - The replay is saved to a separate file for each instance (00000000_42.rep for ip 42)
// - The logfile (if one is created) is also saved with the ip name in the filename.
// So, if you want to use this to debug network functionality on a single computer
// you can enable this define and start the game multiple times, each time passing a different
// fake ip.
// WARNING: If this define is set (even if no fake ip is supplied):
// - all network communication works internally via broadcasts (not just in the lobby room).
//   so you might wanna disconnect from your network while using this.
// - the network protocol becomes incompatible with the original.
//
// Note that this define is currently in Debug.h. That's because the logfile is created
// before the commandline is parsed, and we need to create the log file with the correct name.
#define ENABLE_FAKE_IP 0

@DevGeniusCode DevGeniusCode added Enhancement Is new feature or request Major Severity: Minor < Major < Critical < Blocker Debug Is mostly debug functionality labels Mar 11, 2025
@xezon
Copy link

xezon commented May 4, 2025

@helmutbuhler Did you explore changing the port of clients instead of the ip?

@helmutbuhler
Copy link
Author

@helmutbuhler Did you explore changing the port of clients instead of the ip?

I initially wanted to do it with different ports, but there are several issues:

  • The players are identified in the code only via ip, there is no other real identifier or something else. Changing that would involve a lot of code.
  • There are several ports used already. I'm not 100% sure on this, but I think it's for player discovery (via broadcasts), for lobby communication and for communication during the game. If you want to change ports, you have to touch all those places instead of just one in the UDP layer.
  • If you want to use an individual port for each peer, each peer also has to listen on multiple ports. That means instead of just one, every peer has to open and maintain multiple sockets. Quite a big change.
    So I only see downsides to using ports, no upsides.

But I also don't understand what the problem with this PR is. I put quite some effort into it to make it work and for the diff to be so small. The only downside I see is that it cannot be used to connect with the retail client locally. But I think that's just impossible to implement.

@xezon
Copy link

xezon commented May 4, 2025

I can confirm the observation that using ports would involve much more code changes. What are the estimated disadvantages of broadcasting all messages to all players during matches? I suspect traffic will be quite a bit larger since every client receives all packages?

@jaapdeheer
Copy link

Just a thought in case it helps, afaiu localhost is not just 127.0.0.1 but actually 127.0.0.0/8 (i.e. 127.*.*.*), so you might also be able to bind to e.g. 127.0.0.1 for one instance and 127.0.0.2 for the second. Networking-wise I would expect that to Just Work; game-wise I have no idea if it would work :)

@helmutbuhler
Copy link
Author

Yeah, broadcasting will scale terribly. P2P already scales n^2 with the number of peers, this broadcasting worsens it to n^3. So far I have tested this PR only with up to 3 peers, I don't know with how many peers it will still work.

@helmutbuhler
Copy link
Author

Just a thought in case it helps, afaiu localhost is not just 127.0.0.1 but actually 127.0.0.0/8 (i.e. 127.*.*.*), so you might also be able to bind to e.g. 127.0.0.1 for one instance and 127.0.0.2 for the second. Networking-wise I would expect that to Just Work; game-wise I have no idea if it would work :)

Hm, that sounds too good to be true :) But I havn't checked, it might work.

@xezon
Copy link

xezon commented May 5, 2025

Oh this looks promising !!

https://en.wikipedia.org/wiki/Localhost

IPv4 network standards reserve the entire address block 127.0.0.0/8 (more than 16 million addresses) for loopback purposes.[2] That means any packet sent to any of those addresses is looped back. The address 127.0.0.1 is the standard address for IPv4 loopback traffic; the rest are not supported by all operating systems. However, they can be used to set up multiple server applications on the host, all listening on the same port number.

>ping 127.0.0.2

Pinging 127.0.0.2 with 32 bytes of data:
Reply from 127.0.0.2: bytes=32 time<1ms TTL=128
Reply from 127.0.0.2: bytes=32 time<1ms TTL=128
Reply from 127.0.0.2: bytes=32 time<1ms TTL=128
Reply from 127.0.0.2: bytes=32 time<1ms TTL=128

Ping statistics for 127.0.0.2:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Debug Is mostly debug functionality Enhancement Is new feature or request Major Severity: Minor < Major < Critical < Blocker
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants