Hi,

I want to use a loop to run over methods that are defined in a separate text file.
In order to do this, I am using:

for instruction in _instructions:
    callv(instruction["funcion_name"], instruction["arguments"])

This in a loop executes correctly and executes all defined methods, however, they are executed all at the same time.
So I was thinking of using yield to wait for one method to finish before starting the next method in the loop.

However, when I try to use:
yield(callv(instruction["func"], instruction["args"]), "completed")

It says:

First argument of yield() not of type object

I read that I need to return an object from the called function or call resume() to allow for it to work,
however, I have no idea how I do this, I tried several methods but nothing worked.

For example, I am calling this function here:

func walk_to_position(target_position_x, target_position_y):
	var target_position = Vector2(int(target_position_x), int(target_position_y))
	entity.current_mouse_position = target_position
       >>>>         what to put here to return? I tried return, I tried yield(), nothing worked.....           <<<<<<

How do I return from here so that yield accepts the function and continues execution to the next?

    Benny they are executed all at the same time.

    I don't see how they could be executed "at the same time". Do you mean they're executed too quickly, with no delay between them?

      Godot is very event-driven. If you're tempted to use yield, you're probably thinking too linearly, and yield won't do what you want anyway. You'll probably have better results if you use signals to call the functions (for example, from a timer).

      Remember that yield only returns execution to the calling function, so whatever is next in the function your for loop is in will be executed, including the next _process() call, if that's where the loop is at -- so you could end up yielding repeatedly. You'd have to post more code for me to be certain of whether it could work or not. I'm not even sure what you're trying to accomplish.

      If you still think yield is the right solution, you have to pass it an object that will send a signal at the time to resume your loop. If you're planning to give it an object that signals immediately, you might as well just use the original loop.

      If your functions are launching animations or other asynchronous processes, you might have the animation signal a controlling object that launches the next process in a queue. I can't be more specific without knowing what you're doing.

      TLDR: Don't use yield.

        No, they are not executed at the same time. That is essentially impossible. Godot (for the most part) is single threaded, at least if you are not explicitly spawning threads, so all function calls are sequential.

        Even if you were to use threads, which I don't recommend outside some advanced use cases, they still wouldn't be "at the same time". They would be concurrently, though in an arbitrary and unpredictable order at the single instruction level.

        That said, I am not familiar with callv, but this seems odd to me, as everything should be sequential (in order one after another). In any event, yield is weird, and I almost wish it wasn't even in the language, because it doesn't do what you think.

        Outside of advanced asynchronous scenarios, like an MMO server or some sort of database visualization client, you probably never want to use yield.

          cybereality

          I agree that what I said was wrong, I might not have thought of this long enough, indeed the functions are most likely called and handled sequentially, my problem is more that each of these functions need some time to finish based on a specific condition for example I have the player walk to a specific position before I want some other event to occur (like a sound to play), of course when calling this function it takes time for the player to reach this position of which time I do not know (so a timer might not be the right solution here), but I guess I could emit a signal when one function is done, I will try that before posting again.

          duane I will try just that, using signals. Signals have worked for me many times. I just thought that yield might be working better in this case but I guess that is not the case ...

          Ok, so I tried to emit a signal when one function is done but I guess that is just the same, function executes and finishes as fast as it can making it look like all functions execute at the same time ... I cannot use a timer, since as said I do not know exactly when each function will be done and the times might differ .... any options I have here?

          You would use signals for this. But you wouldn't still call every function. You only call the first function, and then the signals handle the rest of the sequence.

          Or you could use AnimationPlayer to change an object's properties, without creating a method to do that. The original post doesn't explain much about the overall result that's desired.

            20 days later

            I wanted to make an automated way of allowing for some actions to happen based on a textfile I have created, I define my actions in the text file like as soon as you reach this area, do the following by calling this function, play a sound by calling that function, show a text by calling this function, walk to this spot by using this part of the code, play another sound etc. etc., I thought I could easily handle it by calling functions automatically using callv (which does work fine using a text file) and then use a yield or any other method to play one function after the other when they are finished (which does not work whatsoever ...., this is where I am stuck) (similar to callbacks or async function in any programming language where you have to pull data from a server ...), anyways this does not seem to work in a satisfiable manner, reason for me to do this is because I want to make it easier and automated for myself to create complete story scenes where stuff is moving around or stuff is being said or done without me having to create for that each time my own scene, add different nodes to it add texts or dialogs to it aso. aso. that is my reason for this, so if anyone has any good solution to build something like this without having to use yield or callv, I am all open

            Yes, you would use signals, as I mentioned. If you want to do it generically (e.g. not define a new signal for each function) then make a signal called "next_call". Then you have some sort of manager than connects to "next_call" and calls the next function in the array. At the end of each function, you trigger "next_call" which the manager will be listening for and then call the next function. I think this would be the easiest way to do it.

              cybereality Ok I see, I could try that. It seems like a bit more work than I initially expected but I will try it this way and see if it will work as expected. I tried using signals within the function itself already but somehow that did not work too well. I will try to make a signal manager and see if I have success with that, thank you!

              Well the standard way to do this is to define signals for each function. Signals can take an arbitrary number of parameters, so they are essentially the same as calling a function, just asynchronously.

              And your JSON or text file could be in the same format, but instead of using callv, you just trigger the signal. This is basically the same thing, so not really any benefit feature-wise, but more likely how it is done in Godot.

              Though, either way, you'll still need some sort of manager to sequence the function calls, as you won't know ahead of time how long they take.

                a month later

                cybereality Good day! So I looked at this and I simply cannot wrap my mind around this really ... I get what has to be done in theory but I do not understand how I can setup a manager that handles signal calls in sequence, would you perhaps be able to give me a tiny bit of example code to get me started? That would really help ...