godotengine / godot

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

Multiple Run Instances takes a long time to start #94605

Closed warent closed 3 months ago

warent commented 3 months ago

Tested versions

Godot v4.3.beta3.mono

System information

Godot v4.3.beta3.mono - Windows 10.0.22631 - Vulkan (Mobile) - dedicated NVIDIA GeForce RTX 3090 Ti (NVIDIA; 32.0.15.6070) - AMD Ryzen 9 5950X 16-Core Processor (32 Threads)

Issue description

When running two instances, the first instance takes many seconds to run any nodes or enable profiler attachment, but the second one starts immediately.

At first, I thought that I had some global node that was blocking something, but then I realized that none of the nodes enter_tree during this entire "lag" period, and the profiler doesn't attach. In fact, when clicking on the "Remote => Scenes" tree view to see the nodes in the remote, only one instance shows its node tree. The lagging instance shows a blank tree (or a copy of the running instance)

https://github.com/user-attachments/assets/192a9bd3-fc6f-4978-93e0-cd6c3fc35cab

Steps to reproduce

Unfortunately, I'm actually not sure how to reproduce this issue or even debug it. I've tried to do the following:

  1. Create a new Mono project.
  2. Create a global node with a console log
  3. Define two run instances, one of which is a dedicated server.
  4. Run the project

The global node logs from both instances very quickly, and the profilers have no issue connecting. So, something beyond this or in addition to this is causing the issue.

Minimal reproduction project (MRP)

I've tried to reproduce this with a minimal project and cannot

Calinou commented 3 months ago

Which port does your dedicated server listen on? Does the issue occur if you make it no longer listen on any port (i.e. comment out the part that creates the dedicated server)?

warent commented 3 months ago

I'm so dumb, finally found the issue.

The lagging instance is making a long network call on _Ready which takes about 5 seconds to resolve, and then it awaits it. During this time, the main game thread is blocked (which apparently is also blocking the profiler?)

Meanwhile, I guess the C# constructors are running on a separate thread, so when I call GD.Print from a constructor, the print doesn't actually make it through until the game thread is unblocked again. This gives the illusion that the constructor itself is blocked, but it isn't.

The moral of the story here is to basically never put logic inside C# constructors. It's kind of a trap which causes weird issues like this. Apologies for wasting anyone's time!