Skip to content

Events based behaviors 🚀#1049

Merged
4ian merged 45 commits intomasterfrom
feature/runtime-behavior
May 19, 2019
Merged

Events based behaviors 🚀#1049
4ian merged 45 commits intomasterfrom
feature/runtime-behavior

Conversation

@4ian
Copy link
Copy Markdown
Owner

@4ian 4ian commented May 7, 2019

Ground breaking feature ahead 🔥

GDevelop has always being based on the idea of allowing anyone to create simple, advanced or very ambitious games. Behaviors have been very helpful as they allow to quickly add features to objects.
I'm taking this one step further by allowing GDevelop users to create their own reusable behaviors using the classic events system.

  • For advanced users, it's a way to factor logic of the objects inside behaviors ("encapsulation"), and to keep a simple, easy to read events sheet in the scene.
  • For beginners, this will allow them to reuse behaviors created by other users.

For the full help page, read here: http://wiki.compilgames.net/doku.php/gdevelop5/behaviors/events-based-behaviors 👀
I would need your help to fix grammar/typos and to tell me the part that are not clear.

This is still a work in progress but I hope to be able to ship this sooner than later. As far as I know, this is something that was never done in any other game making software with visual programming :)

Still to do:

  • Refactoring when behavior function renamed.
  • Refactoring when behavior renamed.
  • Refactoring when extension renamed (add behaviors and their custom functions)
  • Refactoring of expressions when an expression events function is renamed (need to parse expressions, identify behaviors that are of the proper type, and if the function is the one renamed, change its name)
  • Prevent renaming a behavior function to a lifecycle method name.
  • Prevent the object type to be changed if objects of multiple times are using it.
  • Copy/paste behaviors and extensions
  • Check button to open function works for behavior functions
  • Update help buttons

Then asap:

  • Easy Import/export
  • Sharing/crowdsourced library of behaviors.
  • Work to improve composability of behaviors

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 7, 2019

cc @blurymind @ddabrahim @Wend1go @Bouh @PascalLadalle @zatsme or others, if you have a bit of time to read the wiki page, would be very helpful to see if it's properly explained and fix typo/grammar :)
It's quite advanced, but the idea is of course to still have the help accessible for anyone to understand this new feature.

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 8, 2019

WOW !
I compiled this feature to use it, and it's easy to handle, amazing !
Now i need read the wiki for understand every details.

  • Some of the current behaviours may have arguments.
    I don't see that for personalized behaviours. (Maybe i've miss this point, it's late at home )

    Taking again the Destructible example of the wiki I imagine each instance of my "wall" object with a Destructible behavior and I put a different limit value for each instance in the behavior.
    And to go further I could change the limit value for a particular instance via the events.

--
Edit : Oh second point is already on your checklist.

I've spotted a little thing :

  • When we rename behavior the Behavior list, the type for "Parameter#1 Behavior" in parameters for custom function are not refresh.

@Wend1go
Copy link
Copy Markdown
Contributor

Wend1go commented May 8, 2019

Pure awesomeness! This will bring object orientated programming to GD. I can hardly imagine all the possibilities this will give us. 🎉 🚀 🎉

The event based behaviours will be useful for about any game object that has some kind of interactivity.
Personally, I'd build my whole games around this feature.

Disclaimer: I haven't yet tried this branch on my pc.

Some thoughts:

  • I'm pretty sure this will become the main part where game logic is defined, so it should be possible to hide the panels to the left and right side for having the full width to work in. (or being able to reduce their width at least)
  • A medium to large game will probably have over a hundred behaviours listed inside the "add behaviour to object" dialog. We'd need at least a search box or a tree widget here to keep the list tidy.
  • The themes should be adjusted to make the widgets more compact. Like the top row in the event based behaviour editor ("configuration","parameters","object group") and their entry fields.

There are also some grammar mistakes in the wiki article and the lifecycle method descriptions. Will take a look at it when I come home.

@blurymind
Copy link
Copy Markdown
Contributor

I am particularly excited about the prospect of community shared reusable objects/behaviors 😸

@ddabrahim
Copy link
Copy Markdown
Contributor

Love it, looks great. With custom functions It is going to be a huge game changer! A real hit. Thanks a lot! 🎆

@Wend1go
Copy link
Copy Markdown
Contributor

Wend1go commented May 8, 2019

Fixed some grammar mistakes in the wiki article. (One image seems to be missing somehow)

Another idea for this function:

  • Let the user choose an image from the ressources to be used as an icon for the event based behaviour. That would make it easier to differentiate between them.

Copy link
Copy Markdown
Contributor

@Wend1go Wend1go left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some typos

description={
<Trans>
Events that will be run at every frame (roughly 60 times per
second), for every object that have the behavior attached,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for every object that has the behavior attached

description={
<Trans>
Events that will be run at every frame (roughly 60 times per
second), for every object that have the behavior attached, after
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again "for every object that has the bahavior ..."

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 8, 2019

I wanted to do a behavior to create a usable text field.
I created a custom behavior on a text and I wanted via the OnCreated behavior to create a rectangle with an image that encapsulates the text.
But via events it is impossible to create an object other than the object that uses the current behavior.

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 9, 2019

When we rename behavior the Behavior list, the type for "Parameter#1 Behavior" in parameters for custom function are not refresh.

Yup, this should be included in the latest commits :)

I'm pretty sure this will become the main part where game logic is defined, so it should be possible to hide the panels to the left and right side for having the full width to work in. (or being able to reduce their width at least)

At the least the panel on the right can be closed, and the one on the left reduced. I think it should be enough?

A medium to large game will probably have over a hundred behaviours listed inside the "add behaviour to object" dialog. We'd need at least a search box or a tree widget here to keep the list tidy.

True, I'll start thinking about how to rework this list. I want at some point to include here a search amongst behaviors that are shared somehow by the community :)

The themes should be adjusted to make the widgets more compact. Like the top row in the event based behaviour editor ("configuration","parameters","object group") and their entry fields.

You can manually resize the top part to reduce its size, but I agree, I'm not totally satisfied with this for now.

Fixed some grammar mistakes in the wiki article.

Thanks!!

Let the user choose an image from the ressources to be used as an icon for the event based behaviour. That would make it easier to differentiate between them.

Yeah at some point I'd like to have custom images. The only thing is that I have to see if I can somehow embed it in the behavior, so that sharing is a matter of copy/pasting the content of the behavior (rather than having to share resources too).

But via events it is impossible to create an object other than the object that uses the current behavior.

Yes, it's because behaviors don't know anything about your game, and so can't access objects in your game (remember they should be reusable, and are generated like traditional behaviors).
Though you might be able to create a custom function in your behavior (call it Init or something like this) which is an action taking the object to create as parameter. Basically, you're asking the user of your behavior to call by themselves some actions at the beginning of the scene or regularly to pass the object as parameter.
Your behavior stays reusable this way - even if a bit more of a pain to use (because you have to remember to call the proper actions in the events sheet).

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 9, 2019

Also concerning customization:

Some of the current behaviours may have arguments.
I don't see that for personalized behaviours. (Maybe i've miss this point, it's late at home )

For now these custom behaviors don't have properties (like builtin behaviors can have). I'd like to expose that later, but for now you'll have to use variables of the object. It's less clear but I'll add support for properties later :)
I'll also want to make behaviors more composable, by allowing some behaviors to be plugged in to others. This won't be available immediately, but something that I'd like to work on later.

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 9, 2019

Thanks, it works! And in the control panel, the sentence for the event sheet gives me an error about _PARAM3_
I've created a custom function in my behavior. I have 3 Parameters :

Parameter #0  Object
Parameter #1  Behavior
Parameter #2  obj_to_create

if i wrote _PARAM3_ for the sentence in event sheet nothing is displayed.

@4ian 4ian force-pushed the feature/runtime-behavior branch from 7d6edf0 to eeeafff Compare May 18, 2019 16:15
@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 18, 2019

You're all having too much ideas compared to the speed I can build things 😄Seriously speaking, I agree with most of what you suggest. In an ideal world, we would have a full featured sharing system with automatic upload, votes, favorites, featured extensions and a powerful search.

For now, here is a quick overview of the sharing capabilities:

Search for new behavior directly from the "New behavior dialog":
image

A similar dialog to search for extensions, accessible from the project manager, or import an extension from file:
image

Extensions have now a button to be exported to a file, and also a button to create an issue on GDevelop-extensions repository with a template to fill:
image

Extension descriptions are displayed before installing one. Markdown is supported for description, will should enable nice presentation of real extensions:

image

Extensions can also be searched by "tags". Will be useful when we start to have tons of extensions :)
We can imagine tons of things on top of this basis:

  • featured extensions
  • make new extension more visible
  • sort extensions by downloads, popularity, newest first, etc...
  • votes
  • automatic upload linked to your GDevelop account

As with everything, more complex systems = longer to build, harder to maintain. I'm starting with the git repository as it's publicly searchable, open-source, has support for discussions when submitting an extension (through the issues), has near 100% availability, automatic backups, browseable with just an internet browser, infinite scalability for a cost of zero, and moderation consists in approving issues/pull requests (rather than having to delete potential extensions containing illegal stuff 🙃Yeah that could happen). It's also a good basis for the future features based on it and it's easy to migrate to something else later like a "real" DB.

We'll also have more challenges to overcome to make the sharing of extensions reach its full potential but I'm pretty sure we're on a very good start.

I should merge this branch soon and start working to add behavior/functions to the "registry".

@Bouh:

Actions :
FormatTime seconds to HH:MM:SS
Paste content from clipboard in scene variable

Could you slightly rework these so that these are expressions? I would rather avoid using scene variables because there is no official support for them in functions right now.
For the "featured" extensions that we'll release with the next versions, I prefer to stick with something that is not breaking the conventions of the actions/conditions/expressions of GDevelop :)

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 18, 2019

Note also that exporting/importing extensions as files allow for an "organic grow" of extensions (read: people exchanging/reusing functions using files). This is very fine and will be also a good metric of the success of the Events based behaviors and extensions :)

I've added a first extension by @ddabrahim! :) Feel free to submit issues on https://github.com/4ian/GDevelop-extensions/ even if you don't follow the template/have questions, we can rework the extension before adding them :)

@blurymind
Copy link
Copy Markdown
Contributor

blurymind commented May 19, 2019

@4ian it's starting to look fantastic! 😮

Submit to the community extensions

can be

Submit extension to the community

if

Edit extension options

is just a header, it could just say

Extension options

Just some wording suggestions :)

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 19, 2019

I rework my functions to put them into expressions, I have the impression that the action "Set return value to text" doesn't work.
UTB__ReturnTimeFormated in debugger is "02:00"
String of debug is ""
image

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 19, 2019

I rework my functions to put them into expressions, I have the impression that the action "Set return value to text" doesn't work.

There was an error indeed, the parameter shown in the IDE is shown as a (number) expression, while it should be a string (so in your case, you must use VariableString).
I've fixed this (once latest version of libGD.js is compiled, you should get the fix too). You can also ignore the errors that you get: the IDE will complain but code generation will be made properly.

Just some wording suggestions :)

I've fixed the first, thanks :) For the "Edit Extensions Options", I think I'll keep "Edit" because this is a button, so a verb describing the action is important I think (otherwise you can mistake this as a header - even though GDevelop don't have these - and think it's not clickable).

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 19, 2019

  • Thank for fix, it's working now :)

  • I have a suggestion, i have a behavior and in it I have a condition that I created with the functions.
    My condition is "If object X has an object variable named Y"
    X is the object of my behavior, type of X is Object (Sprite).
    I can retrieve Y with GetArgumentAsString() and pass it to a temporary variable to manipulate Y in Javascript afterwards.
    For X I can't get it back, nor can I manipulate it in Javascript.

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 19, 2019

@Bouh: you can do this already I think by choosing "Object" as the objects to pass to the JS function:
image

Complete example:
image

At least this is working for me:
image

Let me know if that work for you :)

@blurymind
Copy link
Copy Markdown
Contributor

blurymind commented May 19, 2019

damn I wish we had some simple way to import libraries from the project folder easily. Seeing you guys write extensions like that straight into the embedded monaco editor makes it more and more apparent that is the way forward with how we write and distribute extensions. If I could just write
import someClass from 'myFolder/someLibrary.js'
in monaco.. while myFolder is placed in the root of the project folder. Then when you export the extension, it could somehow bundle all the imported libraries within the extension file itself.

Any simple way to achieve that within the ide would be amazing

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 19, 2019

I see the idea, though I don't think that would go through import/require support (that would need GDevelop to actually parse the JavaScript, something that you probably don't want at all, or at least complex bundling with webpack/other bundlers). But I see the idea of having external files bundled with the project.
For now though, let's see how things are going with these events backed extension. The idea is still to make the most of events - which is GDevelop primary "language" :)
If lots of extensions are implemented using JS, we can think again about it (but also keep in mind that if later GDevelop has a new export based on a native language like C++/Kotlin/Swift/Objective C/Java/WebAssembly/whatever, all these extensions using JS would not work).

@4ian 4ian force-pushed the feature/runtime-behavior branch from cab1572 to 7fe3fa1 Compare May 19, 2019 21:20
@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 19, 2019

This should be good enough to merge and have this in the next version :)
I think we'll need quickly to add properties to the events-based behaviors (properties that can be set form the object editor), I've created a card on the roadmap for this: https://trello.com/c/lEpgrCPN/283-allow-custom-behaviors-to-have-properties-that-can-be-set-in-the-object-editor

@4ian 4ian merged commit e737ab2 into master May 19, 2019
@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 19, 2019

I have a few ideas of simple yet useful behaviors, for example:

  • Animated counter text (when set on a text, the text will animate itself to go from 0 (or whatever is the current value) to the new value). Can be done using a variable.
  • Making an object flash (possible property in the future: speed of the flash)
  • Sine movement (would need to have properties, because lots of things can be customized: direction, amplitude of the movement, speed).
  • Behavior that force an object to stay on screen (should be doable without properties - but we could actually adding some margins later)
  • Objects that move back and forth (property in the future: speed, initial direction)
  • Objects with health/damages
  • Bounce behavior: https://trello.com/c/0uMhxCQE/14-bounce-behavior-for-objects

(feel free to give more ideas - I think we could even have a custom column for this in the roadmap! What do you think?)

Most of them would greatly benefit from having properties to customize them to be really useful. For now we can start with variables, but I'll try to see soon if I can add support for properties for these behaviors :)

I've also added a second function by @ddabrahim to https://github.com/4ian/GDevelop-extensions/ (snap to grid)

@Wend1go
Copy link
Copy Markdown
Contributor

Wend1go commented May 20, 2019

Cool, can't wait to try this. 😍
I just hope it won't lead into an uncontrolled mess. When JS is used in the custom behaviours they might need to be checked/updated when we update any library GD relies on like Pixi or Electron.
Btw, is it possible to add functions to existing extensions? Like adding a function to change the opacity/object colour of Panel Sprites or Tiled Sprites?
I have been wanting to add this for a long time now but always shied away cause it is still in the C++ part of the engine.

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 20, 2019 via email

@ddabrahim
Copy link
Copy Markdown
Contributor

ddabrahim commented May 20, 2019

I've also added a second function by @ddabrahim...(snap to grid).

Actually, "snap to grid" was done by @Lizard-13, I only implemented his work in the function so the credit goes to him. Actually, I prefer not to take credit for any of that. All done by others.

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 20, 2019

All, for your interest:

  • I've added a Flash behavior (to make an object blink)
  • Also pushed some fixes on master to properly allow behavior methods to call other methods from the behavior.

Still a few things that I'd like to iron out before a release.

Actually, "snap to grid" was done by @Lizard-13, I only implemented his work in the function so the credit goes to him. Actually, I prefer not to take credit for any of that. All done by others.

Right, I changed to make him the author. If you prefer, I can just credit "GDevelop Team" for extensions that don't have a proper owner.

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 21, 2019

Dialog windows have a problem We can't use buttons if the description is too long :|
image

  • @4ian It works great thanks, this feature is underutilized :o
  • I have a question about variable naming. If names are identical, GD could mix the values? What do you recommend on variable naming, because in the future the behavior/functions list will necessarily have variables that will collide.

I rewrote the conditions in expressions, and I create new ones, I submitted for review on the repo of extensions, link.

@ddabrahim
Copy link
Copy Markdown
Contributor

If you prefer, I can just credit "GDevelop Team" for extensions that don't have a proper owner.

I would go with "GDevelop Community" considering if the origin of something is uncertain, probably it has been shared by 'someone' on Discord or the Forum. But I leave it up to you, I don't mind.

Thanks.

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 21, 2019

@Bouh:

@4ian It works great thanks, this feature is underutilized :o

Which one do you mean?

I have a question about variable naming. If names are identical, GD could mix the values? What do you recommend on variable naming, because in the future the behavior/functions list will necessarily have variables that will collide.

For now I recommend to use object variables as much as possible (or scene variables if needed), but prefix them by something like the name of the extension, or some acronym (for example Flash_Duration for the duration of the flash, and not just Duration).

Ideally in the future, we'll have variables that are specific to Behaviors or even to the current functions - but not soon so for now let's prefix the variables to avoid collisions between variables of different behaviors (or even to avoid confusing the user that could "break" a behavior by misuing a variable).

We can't use buttons if the description is too long

Can you reproduce it with some game? I can't manage to do it by myself.

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 21, 2019

Which one do you mean?

Passing an object in javascript events.

Can you reproduce it with some game? I can't manage to do it by myself.

I paste "Lorem ipusm" text in fields and button gone far because text area have no limit.
https://youtu.be/i7_QvJw1Gyo

@blurymind
Copy link
Copy Markdown
Contributor

blurymind commented May 21, 2019

looks like a css problem :) max-height +overflow-y:auto? :) trivial to fix

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 22, 2019

Material-UI components, here TextField, should already take care of that. I think the fix is adding rowsMax , so that the text field start scrolling its content after being too large. This is what was done for the Text Editor, seems to work properly.
Otherwise, the Material-UI Dialog is confused because of the content that is changing its size.

@4ian
Copy link
Copy Markdown
Owner Author

4ian commented May 23, 2019

https://github.com/4ian/GDevelop/releases/tag/v5.0.0-beta69 👀

Let me know if there is any major issue!

@Bouh
Copy link
Copy Markdown
Collaborator

Bouh commented May 25, 2019

I can't copy a behavior, I must have misread a commit I thought it was possible :/

@4ian 4ian deleted the feature/runtime-behavior branch August 20, 2019 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants