• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!
  • Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Discussion Will it be possible to get a "script_execute_async" function?

K

Khaibit

Guest
I ask because some tasks should just be run in the background as they take a while, and this could allow us to capture the progress and display a real time (adjustable) progress bar and not lock up the UI thread. I would assume we would need our own async event to handle this as well.
 
Last edited by a moderator:
N

NPT

Guest
No.

Currently GM is not thread safe, but for the existing async functions.

They plan on working on making GM thread safe, but I wouldn't count on a script_execute_async, instead according to Russell expect task libraries, basicly a bunch of targeted async functions.

The reason that I don't expect a script_execute_async, is that would be to problematic to impiment without the users introducing non-thread safe code and race conditions.

Russell's quote:
https://forum.yoyogames.com/index.p...ass-for-gml-threading.12243/page-2#post-84269
We plan on making the VM thread safe in the future which will allow us to add a task library (which is our preferred method for multi tasking), but until then we will not be supporting anything like that.

Russell
 

kburkhart84

Firehammer Games
There are ways around this issue, especially if it is something you can break into chunks. For example, my kbinput asset when you are selecting what input to use for something, it does an input search until you press a key(or it times out). Since I can't have a separate function running at the same time, I simply do it with scripting. In the step event of an object, If "searching" do the search. The search loops through all the keys to see if any are pressed. It does this once a step. You could do something similar if you were importing a bunch of resources at run-time. I would have a list of what they are, and each step, import 1, updating variables in order to show a loading bar. Most tasks can be divided like that, allowing your game to not freeze while you do everything so you can show progress bars.
 

Hyomoto

Member
It's unfortunate that GM doesn't currently support parallelism in the broadest sense. It's a case of the users introducing non-thread safe code and race conditions being a fault of the user, and therefore it's acceptable to say, "Okay, this exists but if you break it, that's your issue." Sort of like using ANY functions incorrectly. Still, as @kburkhart84 mentioned, you can write code in a way that it isn't entirely processed in a single step. For example, A* pathfinding can be expensive, especially when lots of objects are relying on it. Therefore what I do is allow objects to queue up a request, and limit the number of cycles that can be dedicated to each calculation. In-game this can translate to a fraction of a second delay between when you wanted the path and when the path was returned, but I think as a general case it works fine. When it comes to your example, the way I implement loading is to do it over a series of cycles. Since you can get delta timing, you can always make a determination to free up the program and continue at the next cycle.
 
I've done this myself and programmed a general "async*" tasking system, but I found the tricky part was determining just how much to do each step. The best place to run this kind of code would be in one of the final draw events, simply because everything else will have been done by then, but at the same time, it just feels icky to do non-drawing related code in draw events. In the end, I created a threshold variable that the system would measure the 'step time' against and terminate execution if it went over that value, but this still caused problems.

*Note: It wasn't really asynchronous, but rather relied on my breaking up things I wanted to do into smaller pieces that could be added to a queue.
 
K

Khaibit

Guest
Yeah, I also did this myself but the problem comes with scale I suppose. I am generating a very large world utilizing simplex noise, ridged multifractals, and gradients. The problem here is that I would like to keep the game running at 30fps while the generation happens in the background.

Right now it becomes a game of "Make the player wait quite a while or use static imagery during loading". So either bad or boring, those are my options right now. I even tried pumping up the room speed, which did help but it just feels hackish (and I mean... some devices would not handle that as well as a higher spec computer would).

I agree, code that is not written in a thread safe way is the user's fault. If users writing bad code was such an issue we would not have GML to begin with because we can still write bad code as it stands, haha.

Guess I will have to put this project on the shelf until the task library comes into existence... unfortunate. Oh well, still great software. Keep up the great work, YoYo Games.
 

Hyomoto

Member
I think @DukeSoft is right, there has to be a work around for that. Even code running in parallel has limitations on speed. If it's really that intensive it might be difficult to break it up, but even if you are only doing one calculation per frame it should still be possible to do so.
 

kburkhart84

Firehammer Games
Some tasks are better suited and work better if you just go ahead and pre-process them. Players won't generally mind a few seconds of loading, and depending on how long it takes, it could be disguised under the level transitions. Trying to work around the pre-loading can make things take longer to do due to all the overhead of tracking progress, so if what you are doing is like that, maybe skip it altogether and just do the task all at once. Note that this doesn't literally apply to everything, for example dynamic level loading, because you don't know where the player is going so you only load/unload the chunks where the player is close enough, and maybe the direction the player is moving to.
 
Top