1

I want to pause game execution for one second every frame. However, the game never resumes, why is that?

I am using the following _process function in the root/world node:

func _process(delta):
    get_tree().paused = true
    await get_tree().create_timer(1).timeout
    get_tree().paused = false

Eventually I want to create some more logic to have the game send and receive information to another non-Godot process, possibly using semaphores and shared memory or some other IPC. So I would not be using any time-based pausing like that. Would appreciate some pointers in that direction as well. Am completely new to Godot.

dotconfig
  • 11
  • 3

1 Answers1

0

the game never resumes, why is that?

The expression get_tree().create_timer(1) will create a SceneTreeTimer, which will not execute while the game is paused.

If you want a timer that will run even when the game is paused, use a Timer (the Node) which you can set to run even while the game is paused by setting its process_mode.

I also want to point out that you can create Threads in Godot, and have them sleep with OS.delay_msec.


Eventually I want to create some more logic to have the game send and receive information to another non-Godot process, possibly using semaphores and shared memory or some other IPC

There aren't many options for inter-process communication with Godot. In part because games don't use them often, and in part because it is hard - if not impossible - to implement a portable solution for the platforms that Godot supports.

So, Godot does not have built-in support for named semaphores, nor named pipes, nor shared memory. Being mindful of the target platform, you could use C# or C++ with GDExtension to get access to such features.

Limiting yourself to what Godot can do out of the box, you could:

  • Have Godot start other processes using OS.execute passing data as command line arguments. The calling thread in Godot will block during the execution, so it can get the standard output from the other program back. And the other program could do whatever means of communication you want if necessary.
  • Communicate over localhost. If you need Godot to listen for incoming connections you can use TCPServer or UDPServer (you might want to check and close connection that are not from localhost). Alternatively, you can have Godot connect to a server with StreamPeerTCP or PacketPeerUDP. There is also HTTPClient if what you need to communicate on the other side is a web server.
  • Good old hacky communication by reading and writing files in a location established beforehand.
Theraot
  • 31,890
  • 5
  • 57
  • 86
  • Thank you for the extensive answer, it helps a lot! GDExtension seems interesting, will take a look. Although communication over localhost is probably enough. Target platform is no issue, as it's not really meant to be distributed. – dotconfig Apr 10 '23 at 18:46
  • The 2nd parameter of [`SceneTree.create_timer()`](https://docs.godotengine.org/en/stable/classes/class_scenetree.html#class-scenetree-method-create-timer) is named `process_always`, which defaults to `true`. Shouldn't this force the timer to run, even if the `SceneTree` is paused? In fact, with Godot 4, OPs code snippet works for me as expected. – zett42 Apr 11 '23 at 14:44
  • Right, the documentation says it should process, weird. I've tested it on a minimal example, just a 3D scene imported from blender and standard CharacterBody3D node with template script. Then added this snippet to the outermost node Node3D. – dotconfig Apr 11 '23 at 15:43
  • Setting the breakpoint on each line of this function and just stepping through it works actually interestingly. – dotconfig Apr 13 '23 at 14:19
  • Tried this function one of the example godot projects. It works, but the unpausing happens very sporadically. It pauses and unpauses a few times with 1 second inbetween as it should, then it stays frozen for longer until it eventually goes back to working as intended. Did you see the same @zett42? – dotconfig Apr 13 '23 at 14:41
  • @dotconfig No, seemed to work reliably for me. But I had created an new project with just a single Node3D in it. I had pasted your code into the attached script's `_process()` function and inserted a `print` before and after the `create_timer()` line. Which demo project did you use? – zett42 Apr 13 '23 at 15:57
  • 1
    @dotconfig Another idea. Instead of delaying the `_process()` function for an extended time, which might be unexpected by the Godot engine, you could do this instead: `get_tree().create_timer(1).timeout.connect( func(): get_tree().paused = false )`. This lets `_process()` return immediately, while the timer continues to run and call the lambda function after 1 sec, which unpauses the tree. – zett42 Apr 13 '23 at 16:02
  • @zett42 I tried it with the 2D particles demo, it actually works somewhat weirder than I initially saw. It seems some of the particles stay paused while others are not, and then they switch. I tried the expression, thank you, but unfortunately, it didn't change anyhing. Just tested with print statements, it does actually print fine before and after, but in the view I can see nothing is moving. Maybe this snippet is interfering with the physics process? – dotconfig Apr 14 '23 at 12:13
  • @dotconfig I have the feeling we are getting stuck in the wrong rabbit hole. Maybe you should start at the beginning and explain the bigger picture instead of your attempted solution to a problem we don't actually know. This way we could possibly suggest a better solution. The comments here are not very well suited for that. Posting an entire new question would propably be better than adding this information to the existing question, so the current answer doesn't get invalidated. – zett42 Apr 14 '23 at 14:01
  • @dotconfig On one hand pausing the game does not pause shaders, which might help explain what is going on with the particles. On the other hand, pausing does not stop the execution of the method where you do it. - I see that the docs say the `SceneTreeTimer` should work even when paused (except that wasn't my experience). - Regardless I still believe a `Timer` is a better option. – Theraot Apr 14 '23 at 17:08
  • @zett42 yea, this is not super important, would still like to know then why this snippet doesn't work, so im leaving this question up, maybe someone else has an idea. – dotconfig Apr 17 '23 at 15:24