Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[$200+ Bounty] Asynchronous events #2975

Closed
10 tasks
arthuro555 opened this issue Aug 26, 2021 · 9 comments · Fixed by #3852
Closed
10 tasks

[$200+ Bounty] Asynchronous events #2975

arthuro555 opened this issue Aug 26, 2021 · 9 comments · Fixed by #3852
Labels

Comments

@arthuro555
Copy link
Contributor

arthuro555 commented Aug 26, 2021

Description

Asynchronous events are events that do not stop the execution flow of the events sheet. Instead, they will continue to run in the background while the game continues running the game loop. Once the action finishes its task, the object context at the time of its execution is restored and actions and subevents after that action are run.

They are used in the event sheets like normal actions but have a clear visual clue and links to documentation to explain their difference from normal ones.

You can find a complete discussion about the feature here.

Tasklist (edited by @4ian)

Tasks required to claim the bounty

  • Add asynchronous actions to the core and JavaScript platform (.SetAsynchronous() that can be called on actions/conditions when declaring them, code generation, etc)
  • Add a way to back up and restore (without deleted objects) the object context.
    • Investigate if other stuff should be included in this context. Objects are a central part of the events metaphor in GDevelop, so they are for sure included.
  • Add a "wait" condition/action that resolves after the time passed as a parameter.
  • Verify how asynchronous actions behave when used in custom behaviors or events based functions.
    • Notably, a deleted object should probably result in any of the "wait" related to it (i.e: launched in a behavior method) to be discarded.

Additional tasks

  • Convert existing asynchronous actions to that system (Network, Firebase, Filesystem...)
  • Add asynchronous conditions
  • Add support for creating events based asynchronous actions.
  • Add an action that accepts asynchronous actions as subinstructions that runs them all at once and continues once they are all finished (equivalent to JavaScript Promise.all)
  • Add action that runs all subinstructions asynchronous actions and continues once any of the finishes (equivalents to Promise.any)
  • Check if it's possible to add asynchronous expressions?

Alternatives considered

You can find a discussion about alternatives on the forum.

@arthuro555 arthuro555 changed the title Asynchronous events [25$] Asynchronous events Aug 26, 2021
@arthuro555 arthuro555 changed the title [25$] Asynchronous events [$25 Bounty] Asynchronous events Aug 26, 2021
@rysolv-bot
Copy link

4ian has contributed $200.00 to this issue on Rysolv.

The total bounty is now $200.00. Solve this issue on Rysolv to earn this bounty.

@4ian 4ian changed the title [$25 Bounty] Asynchronous events [$200+ Bounty] Asynchronous events Aug 27, 2021
@arthuro555
Copy link
Contributor Author

arthuro555 commented Aug 29, 2021

Note that ultimately this could allow for much powerful features such as first class functions by making a condition that accepts a variable, sets the variable to a uid, maps that uid to a resolver function, and then having an action that takes that variable, gets the resolver from the uid and calls it to effectively call the function.

@4ian
Copy link
Owner

4ian commented Aug 29, 2021

Thanks for opening this! 👍
I've reordered a bit the list of tasks to:

  • Add "Verify how asynchronous actions behave when used in custom behaviors or events based functions.". It's important I think to be able to add an action like "Wait X seconds" inside a behavior method. In this case, the wait should also be added to a list of "things waiting to be resolved", but this should be scoped to the behavior. If the behavior is deactivated or destroyed, all these "waiting" things should be discarded.
  • Add that the "Wait X seconds" is mandatory to consider this done. It is the killer feature we want to achieve. It's so natural to use this in natual language that it is the reason why we're adding this (and to an extent, to things like filesystem/network - but "wait" is really the important thing here).
  • Specify that in terms of API design, we have enough of AddAction/AddCondition/AddExpression (and AddExpressionAndCondition[AndAction]), we would rather add a ".SetAsynchronous()".

Probably that also any events based behavior method or function having a wait should become automatically asynchronous ("asynchronicity" is a viral property).

@4ian 4ian added the 🙇‍♀️Careful thinking/design or refactoring needed Needs a bit of studying to come with an elegant solution label Aug 29, 2021
@arthuro555
Copy link
Contributor Author

I am fine with those changes to the task list and would confirm my bounty if this new task list is used instead.

@MorphicDreamer
Copy link

Seeking interest in this bounty. Have no experience with Asynchronous code, but willing to learn!

@4ian
Copy link
Owner

4ian commented Jan 6, 2022

Careful, this is "very hard" task, in the sense that you need knowledge of C++, JS and spend a lot of time understanding the code generation done by GDevelop, how it works, how to adapt it.
If you're starting, I strongly suggest going with a "First good issue", because I won't be able to explain everything that must be done.

@MorphicDreamer
Copy link

Yeah, I think I will start with some "First good issues" and maybe will try this later

@arthuro555
Copy link
Contributor Author

I'm looking into it right now, hard task indeed, I'm still trying to analyze what solution would be the cleanest...

Small question: To resolve an asynchronous action on the JS platform, should I rather make it return a promise and make the code generator .then it, or should I pass in as the first parameter a callback to run the next events?

@4ian
Copy link
Owner

4ian commented Jan 21, 2022

To resolve an asynchronous action on the JS platform, should I rather make it return a promise and make the code generator .then it, or should I pass in as the first parameter a callback to run the next events?

Good question, I think this is roughly similar but maybe a promise is a bit more idiomatic and can help in the future write "asynchronous" actions in JS as easily as making a async function + declaring the function async :)

But the promise should be stored and then-ed so that the game engine knows when it's solved, and start again the execution of the rest of the actions after restoring whatever context was saved (i.e: picked objects mainly!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants