-
Notifications
You must be signed in to change notification settings - Fork 319
Common Mistakes
This page contains some commonly made mistakes and their solutions when working with logic nodes. If you encounter weird behaviour in your logic node traits, first make sure that it isn't caused by anything explained on this page.
Imagine that you have a trait that spawns a cube every second. The game starts with one cube and this cube has the trait attached to it so that it can spawn further cubes. After a few seconds your game will slow down substantially. Why is that?
The reason for that is that you have accidentally created exponential growth. The first cube will spawn another copy of itself, so now there are two cubes in the scene:
[Cube] --- spawns ---> [Cube]
Because the spawning trait is applied to both cubes (remember that the trait spawns the same object on which it is applied), in the next second the trait will be executed twice and will spawn two additional cubes:
[Cube] [Cube]
| |
spawns spawns
| |
v v
[Cube] [Cube]
The now existing four cubes will then spawn another four cubes, and so on. After a less than a minute you would have more cubes than bytes on your hard drive and if you wait a bit longer, you would create more cubes than atoms in the observable universe. But don't be afraid to accidentally fill every corner in the universe with cubes, your computer will crash much sooner than that ;)
Do solve this, simply put the trait to another object that isn't spawned multiple times. Then, only one new cube is spawned each second because there is always just one trait that spawns the cubes.
If you add or delete elements from an array while iterating over it, the indices of the objects inside the array might change. This can lead to hard-to-find bugs where some elements are skipped or used twice. This problem does not only exist in logic trees, it can also happen in Haxe scripts (and in any other language).
There are a few ways around this issue, some might work better than others in different cases. Some of them are:
- Add another array with all elements to add/delete. Then iterate over the new array instead.
- If the order of elements is not important, you can append/remove from/at the first or last index for each element. This is faster than (1) and needs less memory.
If you store a value inside a variable with the Set Variable
node or pass it to a function, the value might not get copied in memory depending on its type which can cause unexpected side effects. This is because of two different kinds of types, mutable and immutable types.
-
Objects of Immutable types can't be modified after their creation. If you change the value(s) of an immutable object, a new object is created instead, so a change doesn't affect other places where this object is used. This has the same effect of a copy, independently of whether there actually is data copied in memory or not. Primitive types like
Bool
,Float
andInt
are immutable. TheString
type is immutable as well in Haxe, thus also when using logic nodes. -
Objects of Mutable types can be modified after they are created, and when storing them in variables or passing them to functions, there is no copy made by default. This means that if you change their values in one place, it will also change in every other place where this value is used. A common mutable type is the
Array
type: if you add an object to an array, it is also added to all other places where that array is used because it is the same array in the same place in memory.If you want to work on two different instances of an array or another mutable object, make sure to copy it first. For an array, this can be done using the
Array Slice
node withIndex
set to 0 andEnd
set to the length of the array.