Guide to making an extension

I’m going to write a guide that I hope will help people who are new to making extensions. Also to help future me when I’ve forgotten. Someone in another post asked for help and I thought it best to start a new post that I can add to later. Of course, you should read the wiki, but I’ll try to explain things in terms of decisions to make. It’s not going to be a complete guide but it will get you started .

Please note, I am not an expert in GDevelop, I just do what I need and there are many things I don’t know.

Part 1

Firstly, some extensions are behaviors and some are functions. A behavior is something you add to an object and usually it’s for something you want to happen most or all of the time.

For example, the Sticker extension is a behavior. You add it to an object and then it sticks to something all the time until you tell it not to.

Do you want the user of the behavior to have settings that they see in the object properties behavior tab?

The Sticker behavior has two settings, Destroy when the object it’s stuck to is destroyed and Only follow position.




If you click on the name of your behavior, a new window will appear, one of the tabs is for Behavior Properties. This is where you’ll add your settings. Both the Sticker properties are Boolean variables.




The Rectangular Movement behavior has some number properties like height and width. These properties let the user of the extension change it to what they want.




But what if you want the extension user to be able to change things dynamically in events? That’s where functions come in. You can add different kinds of functions to your behavior. How do you know which type to add? If you want the user to change settings in their event actions then you need an Action function.

The events in the function are where you define what you want to happen for that action. The Fire Bullet behavior has a Fire function where it creates an action using x and y position, angle, speed etc. These values in a function are called parameters. Every function has a default Object parameter. This is the object that the behavior is added to. Here are some of the Fire parameters, each one has a name, type and label.




And here is an event in the Fire function using some of these parameters and others as well. All the names in the green circles are parameters.





Why does the Bullet parameter look like the default Object parameter? Because it’s a parameter of type object. It’s the gun object that has the behavior but every gun needs a bullet. The parameter is how the extension user picks their Bullet object.





An important thing in the Function Configuration panel is the Sentence in Events Sheet section. This is the sentence the extension user sees in their event action. Even though you gave the parameters names, you need to reference them by their number in the event sentence. So, for the second parameter, XPosition, you will need to type _PARAM2_ and make a meaningful sentence so that it makes sense in the event sheet. Here’s what the Fire parameter sentence looks like in the function and how it looks like in the scene events action.






But what if you want the extension user to check something? For example, in the Fire Bullet extension, it makes sense to check if there is any ammo left. It does this with a function called IsOutOfAmmo. This function is a condition function. And because a condition checks whether something is true, you will need to have a condition. But what do you have in the action? This is where you give the function a result, is it true? To do this you go to Event functions and select Set condition return value.


This is how it looks in the function event and how it looks in the scene events.

That’s it for now.

Part 1
Settings - behavior properties, event sheet parameters
Actions and condition functions
Event sheet sentences

Part 2
Lifecycle functions that run every frame - doStepPreEvents and doStepPostEvents

Part 3
Variables and Expressions

Part 4
Other parameter and property types
Lifecycle function limitations
Extension variables

Part 5
Functions external to a behavior
Function extensions
Shortcut functions (my name for them)

Part 6
Get your extension ready for export

Part 7
Cheat sheet

8 Likes

Needed this. Thanks.

2 Likes

Hi @Bubble!

It’s very nice from you to do this tuto! :+1:

I’m going to put all these explanations away to study them later. :wink:

Thanks again.

PS: it would be interessant that the GD’s Team put in the documentation of GD, a link to this type of explications as Bubble did.

A+
Xierra

3 Likes

Very good. Thank you.

1 Like

Part 2
Some lifecycle functions

Let’s say your scene events has an event like this -
Condition, Enemy is near Castle guard | Action, Close Castle Gate
That action doesn’t happen all the time, it only happens if the enemy is near the castle guard. If you don’t have that action in your events, it’s not going to happen. The same goes for the extension functions we’ve looked at so far. Action functions like Fire from the Fire Bullet extension will only happen if they are in your scene event sheet and as we saw in Part 1, it lets you change the bullet speed, angle etc.

But isn’t a behavior something that can happen all the time? It needs to keep going even if the user doesn’t change any settings. But Action functions only happen at a specific moment in the scene event sheet, so where do you put the actual content of how your behavior works?

This is what Lifecycle functions are for. Two of the lifecycle functions that run all the time (every frame) are doStepPreEvents and doStepPostEvents. The names are similar so does that mean they do the same thing? They could be similar but it’s when they happen that matters.

Pre means before, so a doStepPreEvents function runs before the events each frame. Why would you want this? The Rectangle Movement behavior has a doStepPreEvents function that changes the position of the object. The object starts in one place and ends up in another place. Why should this happen before the events run?




Remember the enemy and the castle guard from earlier? Let’s give the guard the Rectangle Movement behavior. It will move in a rectangle in front of the castle gate. And also from earlier, the castle gate will shut if an enemy is near the guard. But where is the guard? It’s not standing still, it’s moving around, remember?

So how can we be sure that our scene event will correctly calculate when the enemy is near the guard? Because the Rectangle Movement of the guard is in a doStepPreEvents function that runs before the events.

What else can happen before the events run each frame? It’s a good time to change the value of variables, reset Boolean variables and start timers. This means the scene events can run with correct and up to date information.

So, do you even need doStepPostEvents functions that run after the events? Let’s say we want the enemy to get angry when the castle gate closes. So we give it the Shake behavior. We don’t want the enemy to shake all the time, only when it’s angry. We’ll give the enemy the Elipse Movement behavior that changes its position in a doStepPreEvents function before the events run.

This is what we have for the enemy
Before events - design the elipse movement
During events - check if enemy is near castle

Because the Shake Object behaviour uses a doStepPostEvents function (after) we don’t have to worry about any visual lag or delay between cause and effect. The enemy shakes at the right time after the gate has closed event, not before.




Next - variables and expressions.

3 Likes

Part 3
Variables and expressions

Remember the behavior properties we looked at in Part 1? They are settings that can be changed in the behavior tab of your object like the Only follow position setting for the Sticker extension. There were also width and height properties for the Rectangle Movement extension. The Fire Bullet extension has properties like MaxAmmo and AmmoQuantity.





MaxAmmo is where the extension user can change how many bullets the gun has. But what good is it to have AmmoQuantity in the behavior settings? Surely that number depends on how much ammo there was and how many bullets have been fired? Exactly. So, let’s see the full picture. AmmoQuantity is a hidden property. This means it is not in the object behavior properties available to the end user. And MaxAmmo is an advanced property so it’s only visible if the user changes the default of unlimited ammo.

Please note, I changed the order of some properties to have them near each other in the pic.


So if the AmmoQuantity property is not even available to the user then why is it there? If MaxAmmo is, for example, 6, then yes, we do need to know AmmoQuantity because at some point it will be zero and then other things have to happen like reloading. Here’s an event from the doStepPreEvents function. It changes the value of the AmmoQuantity variable. So, behavior properties are not just for user settings, they are also used as variables. When you need a variable, add a behavior property by clicking on the name of your behavior and change it to the correct type like number, text, boolean etc.




What if there are multiple weapons in your game? What’s going to happen to that AmmoQuantity variable? Can it hold more than one value? No, I guess not. But, because AmmoQuantity is a behavior property, every object in the game that has the FireBullet behavior will have its own AmmoQuantity variable. All weapons will have their own variables.


Now that we have that all good, what now? How is the player going to know when they’re low on ammo unless they count each shot fired? You could have a text object on screen saying how much ammo is left, that is, the behavior property AmmoQuantity. Okay, great, but how do we make the behavior property available in scene events? Where is AmmoQuantity?




It’s not there, well not directly. Here’s what we can do to make it available, we can make a new function, this time an Expression function. Be sure to change its type to what you need, the default is number. Now we’ll add a set return value action and set it to the value of the behavior property AmmoQuantity. The Fire Bullet extension uses the same name for the property and the expression, both AmmoQuantity, I’ve changed them slightly to make things easier to understand.




And here is how it looks when you access it for your text object/number variable.



If you were very observant you would notice that the function was not an expression. Well, not quite. It’s an expression that can be used as a condition. If you don’t need to have a condition based on that value then you can leave it as the default expression type.

1 Like

Part 4

Other Parameter types

In part 1, we looked at properties and parameters. Properties hold a static value that is set in your object’s behavior properties while parameters hold a value that you can change dynamically in scene events like angle, speed, position etc. An interesting value type that can be used for both properties and parameters is Color (text). If it’s just text, which it is, then why is it interesting?

Let’s look at the Flash extension. It has a Flash Color behavior where the user can change the flash color in events, so let’s take a look at how it does it. Firstly, it has a hidden property called TintColor. This means that it’s not available to change in behavior properties. The function that does the tinting is called Flash and it has a parameter called NewTintColor, but it’s the TintColor property that defines what color the object will be. The NewTintColor parameter is how we get the user’s input in scene events.



Because the NewTintColor parameter is of type Color(text), when the user selects a flash color they can just pick a color visually. Perfect.



Another useful property and parameter type is String from a list of options (text). Let’s look at the Rectangle movement behavior again. Anything with this behavior will move in a rectangle. We can say whether it should move clockwise or not. But which side of the rectangle should it move on first, that is, what is the starting position on the rectangle? This is where String/Text from a list of options is useful. You’ll have the name of your property and then you can say the name of each option for that property.

Rectangle movement has a property called InitialPosition with an option for each corner, top left etc. This way, when it comes to the user setting up the behavior they can pick which corner to start movement from with a very neat drop down menu.



Something to be aware of with Lifecycle functions

We’ve seen a few times now that action (and condition) functions let the user change an object’s behavior in scene events and often have added parameters like width, height etc. And these functions only run when you call them in scene events. But lifecycle functions like Pre and Post doStepEvents run all the time; they do not get called in scene events. Therefore, lifecycle functions don’t have the option to add parameters to them, they just have the default Object parameter. Does this matter? You can still reference the object itself and behavior properties in your lifecycle events.

The Fire Bullet extension we looked at in Part 3 is added to a gun/weapon as a behavior. Remember in the Fire action function that it used an object parameter called Bullet? Here’s a limitation of lifecycle functions. You can reference that Bullet ‘object’ in an action/condition/expression function but not in the events in your pre or post doStepEvents functions.



Extension variables
These are pretty new and I haven’t seen any extensions use them (I’ve only checked some extensions from GD team members). There’s a few things to remember about them, just like properties, you can’t access them in scene events, you would need an expression function to access their value.

The great thing about behavior properties is that they ‘live’ in the object that has the behavior. And if you have ten objects with that behavior, they all have their own version of those properties with their unique values. So you can think of behavior properties as being like object variables.

And extension variables? Yep, they’re similar to scene variables. In fact they’re actually called Extension scene variables. So, if you want to use a general variable that doesn’t need to be a behavior property, then extension variables might be what you need.

3 Likes

Full and clean guide, thanks @Bubble !!!

2 Likes

Hi!

I think we can say BubbleS because he is multi efficient. :clap:

Message to Bubble: i suppose you regroup all in an unique document to contain all you writed.

A+
Xierra

1 Like

Hi Amigo, thanks for your interest. Do you mean do I have the whole guide in one document somewhere? Yes and no. I write it in Notepad and when I know I want an image I write on a new line ‘Pic of relevant thing’. Then I paste the whole thing into a new post here. For each pic reference I then set up the pic in GDevelop, screenshot it and paste it in to the edit here in the post. Then I read through it all and make improvements/changes as needed.

Which means if you were hoping there was one uptodate document with pics embedded in it ready to make into a pdf or something, sorry, no there isn’t. I’m a notepad kinda person. But I plan to add more pics to what I’ve already done especially when I mention things from previous parts. And I hope to make the final cheat sheet/reference/TLDR very easy to read, no long explanations, just facts, with maybe one or two annotated pics of an entire extension screen.

3 Likes

Hello

Thank Bubble for your answer.

A+
Xierra

1 Like