godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.72k stars 21.12k forks source link

When I debug/breakpoint while connected as a peer, it soon disconnects #79246

Open TheYellowArchitect opened 1 year ago

TheYellowArchitect commented 1 year ago

Godot version

4.1

System information

Artix (Arch Linux)

Issue description

Like everyone, I often place breakpoints in the code to find bugs. So you place a breakpoint, watch the values in locals and press F10 slowly to find out where logic is flawed. If you do this for 8 seconds or so, connection times out, and if you continue (e.g. F7), game is ultra broken and spammed with essentially this error: multiplayer-instance

Video of localhost with 3 players

Now, here is an interesting point. If I place the breakpoint on the host/server, and timeout happens, it disconnects all clients (as shown in the above video), but if I place the breakpoint on a client, just the client times out (and theoritically the game is salvageable)

This bug is not exclusive to localhost, I did port forwarding to play with a friend far away, and if a breakpoint hits, I have to swiftly continue/F7 so the game won't disconnect for either of us.

If I had to suggest a solution, it would be that on breakpoint, the classic packet ping overrides the pause of godot, so the connection doesn't break. That is, if it doesn't do that by default

Steps to reproduce

  1. Debug -> Run Multiple Instances -> 2
  2. Start the game, host locally with 1 instance, join with any other
  3. Place breakpoint on some RPC
  4. Trigger above^ RPC
  5. Wait like 8seconds
  6. Any function inheriting from multiplayer. will not work because the instance is deactivated.

Minimal reproduction project

Look below.

TheYellowArchitect commented 1 year ago

I managed to replicate this on the official 4.0 scene replication tutorial

Video-proof: https://files.catbox.moe/5dbth1.mkv

Faless commented 1 year ago

Now, here is an interesting point. If I place the breakpoint on the host/server, and timeout happens, it disconnects all clients (as shown in the above video), but if I place the breakpoint on a client, just the client times out (and theoritically the game is salvageable)

I mean, this is expected, if you hit a breakpoint, the game will pause.

If the other side of the connection keeps sending reliable packets/pings/etc, the connection will timeout after a while.

We can't do anything about this...

You can adjust the timeout for ENet via set_timeout if you plan to debug-break, but you'll still hit a disconnect after a while, or the outgoing buffer will fill if you send too many reliable packets that don't get ACKed, and the peer will timeout anyway.

TheYellowArchitect commented 1 year ago

All problems are solveable, though obviously I understand this is especially hard. I have basically 3 suggestions (disclaimer: I don't know Godot's inner workings, nor have I written a packet manager):

  1. If the set_timeout can be set at runtime, Godot calls this right before hitting a breakpoint, and sets it very very high (and ofc via a flag detects if the timeout is that high, and on closing the playable instance, sets the timeout to default)

  2. If set_timeout can not be set on runtime, and the debug breakpoint hits by a client, you start a new thread, connect as client, then kill the thread once the debugger continues.

  3. (bloat warning) If the playable instance is spawned by an editor, whenever you connect, there is a constant ack packet transfer each X ms, which cannot be interrupted by editor breakpoints. Basically a duplicate socket connection which never pauses

Anyway, somehow, when the game pauses, the connection must go on.


I consider this feature a necessity for debugging multiplayer games (quality/production games don't have simple game states), and so much time is gained by proper debugging instead of monke trial&error. I also don't understand why the bug label is removed. This bug breaks normal debugging functionality inherent in Godot, and any game engine. A bug which prevents easy bugfixing

juliohq commented 1 year ago

I agree with @TheYellowArchitect, I think the game shouldn't be totally paused upon a breakpoint, multiplayer is just part of it. If you've also noticed you'll get a freezed window too, which means rendering is also paused. I think we should go with something close to point 3, including not pausing the rendering at all (maybe the contents of the window are important for debugging and you wouldn't want it to be lost).

TheYellowArchitect commented 1 year ago

I agree with @TheYellowArchitect, I think the game shouldn't be totally paused upon a breakpoint, multiplayer is just part of it. If you've also noticed you'll get a freezed window too, which means rendering is also paused. I think we should go with something close to point 3, including not pausing the rendering at all (maybe the contents of the window are important for debugging and you wouldn't want it to be lost).

I think a misunderstanding may have been made. My suggestion was that the game should be completely paused like in a local offline singleplayer breakpoint (but technically speaking, what should be excluded from this pause is the peer connection, in order to not timeout)

juliohq commented 1 year ago

I think a misunderstanding may have been made. My suggestion was that the game should be completely paused like in a local offline singleplayer breakpoint (but technically speaking, what should be excluded from this pause is the peer connection, in order to not timeout)

I partially agree with that, but apparently there are other topics that need to be excluded from the pause (because the issue seems to be bigger than only a network problem). For example, if you have music playing in your game or any other kind of sound, it keeps playing even after the breakpoint is reached, so why would rendering and network be paused?