Common mistakes (discussion)

Another common mistake is putting conditions inside a loop event like a for each object This doesn’t always cause an unexpected behavior but does affect the efficiency. It’s extra important to be efficient when every millisecond counts.

Examples <click to open>

For each object
----mouse is down

While this will work, it’s checking the mouse condition each time. The mouse state won’t change during the loop or even the frame.

A more efficient way is

Mouse is down
----for each object

Now, the loop won’t happen if the mouse is released and when it is down, it will be only be checked once not one time for each objects.

Another involves object filtering.

For each object
—object is visible

This will go through the loop and check each object separately.

Object is visible
----for each object

This will pick the visible objects using 1 condition and then use that list to loop through only the visible objects.

4 Likes

That For Each Object usage example is spot on. Reduce the working set of objects, then iterate.

The same can be applied to multiple conditions in one event. Order them by the conditions that either reduce the list or working set of objects the most, or that are least likely to occur.

3 Likes

Most cardinal mistakes i see other users make
Are
At beginning of the scene
Which ppl believe mean
Start at beginning and keep going
Where it means start ONLY at beginning

Other is not understanding that event is meant for condition and action to run
And not be bunch of both and engine will magically understand what you want to achieve by doing this

Where my own mistakes are
I often copy paste Object.CenterX() to not type it again for Y
So i copy paste it to Y and change X to Y
Yet i do not sometimes rename X to Y
And i end up with Object.CenterX() Object.CenterX()
I was victim of this mistake way too many times
And it happens to me even now and not just when i was starting

3 Likes

A critical but deceptive mistake that I used to do a lot before and I see many people fall for it, is using “trigger once” inside a For Each Object event.

It may seem like it makes the event triggers once for each object. But what actually happens is that if the conditions are met for any of the objects, the event triggers only once and stops after that. It’s confusing even when trying to explain it!

3 Likes

“At the beginning” is a little vague. I think I might have originally thought that. It also helps to put all of the “At the beginning” events at the beginning under a single event. There’s no need to mix it in with other events since it only executes once. It makes the rest of the events leaner and easier to read.

1 Like

Another commonly misunderstood action is wait . I originally thought it caused the entire project to pause instead of just the child events and sub-events.

Honestly, I personally try to avoid wait. It has it’s uses but often times I prefer to use a timer.
A lot of events also have their own completed conditions like tween, animation and sound. It’s more efficient to use them than it is to guess how long it might take. wait does make for a cleaner and more streamlined event sheet but it can cause unexpected actions and once set you can’t delete waits.

Also, you need to make sure the waits don’t build-up. It’s important to use some form of trigger once. Otherwise, you can have 60 waits added every second and x seconds later they all start to expire. Sometimes, wait is more like a delay if you don’t use some form of trigger once. You have the initial wait and then a constant release of additional waits like a red light turning green and all of the built-up cars being released.

Examples of tween, animation and sound

2 Likes

Here’s a link to an explanation about how the trigger once works (and excuse the poor repeat for each object events - it was written before I knew any better)

2 Likes

Also sometimes is better to use the repeat 1 time event instead to trigger once something that needs to not be triggered just once…to me it happened when using the homing bullet extension

I’m honest i’ve this in my project.
I used it to check a fast collision eg when a whip it the enemy to create a fast combo (bcs the whip was ofc still on the enemy the next step)

1 Like

I’m not sure how Repat 1 event would be any different than just using a normal event, if the Repeat 1 event is triggered on every frame or repeated for each object.

i’m gonna post a screenshots here , maybe you gonna notice something i have not…
but in short words i have a repaet for each object event…
now … if you use trigger once in a subevent that events will works for one instance of that object…will it works instead with the repeat one event cos it will pick all objects cos there is no trigger once…
i’ve a conditions that works only like this…(now that i remember better i think it was cos a timer, i binded a timer for each enemy than i noticed that with trigger once only 1 enemy was shooting an homing bullet to player at chosen time, than i tried with repeat 1…issue gone)

I’m a bit confused myself. How is a repeat any different than just not having any conditions? Or a parent event to the for each object that has some form of trigger once. That way it prevents the for each object from being triggered multiple times.

Unless, I’m missing something.

I don’t know…maybe it was cos i had an extension action in the event…gemme time . when i’m back home i’m gonna post a screen. it may help to improve my game.

2 Likes

Ok so keep in mind that you may notice bad things since it’s a test version…
anyway i’ have this external events called Ai which is the base to trigger different enemies state.


Now this is where i noticed that enemies were not attacking the player in a randomized way. I tried conditions with trigger once a lot without success. (only one enemies and 1 timer were taken into consideration)
With repeat 1 everything works fine i guess because timers aren’t influenced or probably bcs something written in the homing extension that i don’t want to dig now… or probably cos the trigger once is already called by the previous event
I tricked it cheking the animation. so if the animation not end it will not consider the timer and trigger the bullet while still in the same animation. I don’ know, maybe it’s hard to explain…
I had so many problems about this that i decided to add a text above enemies to check timers and ai value.

HAHAHAHAHAHAHA, I’m sorry, Keith, but this is so funny! :joy:

Same here. I even created a topic with this question asking for some help.

I always forget to mark the scene whenever I open Gdevelop and every first preview is in the wrong scene.

I keep finding old things in my code which leads me to believe that when I make changes to the code I always forget something…

Sometimes I click wrong and close the scene’s events tab and have to open again and drag the events tab next to the scene tab.

I don’t know how to write exactly expressions involving arrays and variablechildcount. I always need to copy from somewhere else in the events or I’ll end up doing it wrong.

1 Like

Ok here’s one. If you are using a Text Input object, do not set up a Key Released event such as “Return key released” to trigger a set of actions supposed to occur after the player is done inputting text.

If you do not use Text Input objects much, you will probably spend 10 frustrating minutes trying different methods and changes to figure out why your variables and save events are not working. You will just be on the verge of concluding that GDevelop is broken, when you will realize that you are the one that is broken, because with the Text Input still in focus, of course the key release is not even registering because it’s counting as text input. You will then click the mouse somewhere else in the preview to take the focus off the Text Input, hit the return key, see everything working and feel that this was not one of your finest moments.

I also struggle with variable case too.

That’s why I love development interfaces in which variables are not case sensitive, but adaptable.

As an example, Visual Basic in Visual Studio (I don’t remember now if C# works the same in Visual Studio, or which ones does it in Visual Studio Code). Not the best or most versatile language, but I love how you can write (name) the variable with any case, and the engine will automatically understand it’s the same variable.

It even automatically updates the case for all other instances of the same variable based on how you write it the last time you name it (oganizationalIy wise, I cannot think of a good reason to keep different variables with the same spelling, but different case, in the same project).

That makes the variable system so precise and fast to work with it; but flexible, functional, and accessible to all kinds of users.

Also, there you can choose if variable declaration is strict or not.

In a beginner-friendly but powerful system, that also should apply to the use of commas and semicolons in situations like RGB color codes.

I have struggled with this too. Sometimes I’ve discovered a ‘For each object…’ loop is not needed since the actions seems to be applied to all instances of an object, even if I have just make a reference to a specific instance before in a condition or an action of the same block.

1 Like

A common mistake I made when I was a beginner in GDevelop is how to correctly toggle a boolean variable between true and false for case-specific selections.

The challenge arises when attempting to ensure that only one specific block executes based on the current state of the boolean variable. If not managed properly, modifying the boolean variable inside conditional statements can lead to unintended consequences, such as triggering multiple blocks sequentially when only one should execute per cycle.


Expected behavior:
When ‘selector’ is true, specific actions are triggered, and then ‘selector’ should switch to false. Conversely, when ‘selector’ is false, different actions are triggered, and ‘selector’ should toggle back to true. This may ensure that actions alternate based on the current state of ‘selector’ during each cycle (frame).

To try to achieve this behavior (and in lack of a dedicated case-selection block/module for this), usually a beginner will obviously jump to this approach:

simple_selector_issue

Obviously for non-beginners, the problem with this approach is the “False Case” will execute immediately after the “True Case”, since ‘selector’ changing to ‘false’ in the “True Case” immediately triggers it.


This get even worse when the expected behavior is to execute a specific case based on the value of a non-boolean variable, and the executed actions requires to set the stage for the next case changing the ‘selector’ value.

multiple_selector_issue

While this may seems a logical setup to achieve this kind of behavior in the eyes of a beginner user, this setup will only trigger a chain reaction that will execute all cases at once.


Of course, you can resolve these issues by introducing an additional boolean variable to track whether a case has been executed in the current cycle or not:

simple_selector_solved

multiple_selector_solved

But this is not obvious to a beginner user, the forum is crowded with questions about this same issue, and this would be easily solved with the inclusion of a case-selection block (like “Select Case” or “Choice” blocks).


̵I̵’̵m̵ ̵a̵w̵a̵r̵e̵ ̵a̵ ̵b̵o̵o̵l̵e̵a̵n̵ ̵a̵l̵t̵e̵r̵n̵a̵t̵i̵n̵g̵ ̵a̵c̵t̵i̵o̵n̵ ̵w̵a̵s̵ ̵i̵n̵t̵r̵o̵d̵u̵c̵e̵d̵ ̵a̵t̵ ̵s̵o̵m̵e̵ ̵p̵o̵i̵n̵t̵ ̵t̵o̵ ̵s̵o̵m̵e̵w̵h̵a̵t̵ ̵s̵o̵l̵v̵e̵ ̵t̵h̵i̵s̵ ̵i̵s̵s̵u̵e̵ ̵i̵n̵ ̵b̵i̵n̵a̵r̵y̵ ̵c̵a̵s̵e̵s̵ ̵(̵n̵o̵t̵ ̵i̵n̵ ̵m̵u̵l̵t̵i̵p̵l̵e̵ ̵c̵h̵o̵i̵c̵e̵ ̵c̵a̵s̵e̵s̵,̵ ̵a̵n̵d̵ ̵a̵l̵t̵h̵o̵u̵g̵h̵t̵ ̵i̵t̵ ̵s̵t̵i̵l̵l̵ ̵n̵e̵e̵d̵e̵d̵ ̵a̵ ̵s̵p̵e̵c̵i̵f̵i̵c̵ ̵s̵e̵t̵u̵p̵ ̵t̵o̵ ̵w̵o̵r̵k̵)̵.̵ ̵H̵o̵w̵e̵v̵e̵r̵,̵ ̵i̵t̵ ̵s̵e̵e̵m̵s̵ ̵d̵e̵p̵r̵e̵c̵a̵t̵e̵d̵ ̵s̵i̵n̵c̵e̵ ̵t̵h̵e̵ ̵v̵a̵r̵i̵a̵b̵l̵e̵ ̵s̵y̵s̵t̵e̵m̵ ̵c̵h̵a̵n̵g̵e̵d̵.

Moreover, while it’s possible to resolve this issue with an additional check variable in the setup, I don’t understand why this process is unnecessarily difficult for beginners and time-consuming for advanced users, rather than simply including a ‘Choice’ logical block.

NOTE: please correct me if there is an intuitive, beginner-friendly, and accesible way to achieve this in GDevelop.

1 Like

Yeah, I like to call it the domino effect or chain reaction. I miss If… Then… Else like other languages have.

If you’re talking about toggle, it’s still there. It’s just been moved to the setting action.

1 Like

I see. Thanks for letting me know that the boolean toggle option was moved into the action settings.

However, this doesn’t resolve the issue of handling multiple choices.

Introducing ‘ElseIf’ or ‘Choice’ statements would make the engine automatically more intuitive for beginners and more efficient for everyone in terms of workflow.

1 Like

Yes. A Boolean toggle only helps with 2 choices.

I use your method with a changed variable. You can also wait until all of the choices are evaluated before changing the variable if it’s a simple sequence.

A=1 do something
A=2 do something
A=3 do something

If a >= 1 and a <= 3 then set a+1

There are other times when you can use a formula, a group or for each object or each child or use an object variable of a colliding object or even an array or structure to reduce it to just a couple of events.

You want to try to reduce repeating the same events when possible. Extension are another tool. Even when the extension doesn’t reduce the number of events it makes the main event sheet easier to read.

I’ve never used external events. For me, they break up the flow. It makes it harder for me to follow the execution.

1 Like