Variables are a core mechanic of all games – learn more about them and what they can be used for.
Variables are used to store information in a running game. This information could be anything – like the player’s health, ammunition or marking a solved quest. You wont be able to create a game without using variables, they’re needed in basically all game mechanics you’ll create.
Using Variables #
A variable consists of 2 parts:
- Variable Key
The key (or name) of the variable is used to identify it. - Variable Value
The value of the variable stores the information.
By default, variables are saved with save games – this can be changed in the Makinom editor (UI > Save Game Settings). When variables are saved, you can optionally exclude defined variable keys from being saved. When not saving variables, you can optionally include variable keys to be saved.
Changing Variables #
Variables are changed using a Change Variables node most of the time, but there are a lot of other nodes that can change variables, e.g. a Raycast node can store the position that was hit into a Vector3 variable or a Store Function Result node stores the return value of a called function of 3rd party scripts.
Beside changing variables in schematics through nodes, you can also change them at other times, e.g. using the Local Start Variables of machine components or the Initial Variables defined in the Makinom editor (Game > Game Settings).
You can create templates for variable changes if you often need the same changes in different schematics and other places. Variable Change Templates are created in the Makinom editor (Templates > Variable Change Templates) and can e.g. be used in the Change Variables node.
Getting and Checking Variables #
Variables can be used in most nodes in schematics and formulas when there is a value to be used, like a position for spawning a prefab (Spawn Prefab node) can also use a Vector3 variable as position.
Checking variables is usually done in a Check Variables node, but can also be done in other nodes and in other parts of Makinom, e.g. machine components. This is often done using a Variable Condition – which can be also created as a template to be reused when needed. Variable condition templates are set up in the Makinom editor (Templates > Variable Condition Templates).
Variable Origin #
The origin of a variable defines where it’s stored and how it can be accessed. There are 4 different variable origins – when dealing with variables (e.g. changing them, checking them or using their values), you’ll always need to select the origin.
Local #
Local variables are only available in a playing schematic or calculating formula. They’re best used for short lived information, like counting something within a schematic’s run or storing temporary values for use later in the schematic. Local variables can’t be saved with save games.
A crucial mechanic is sharing local variables between schematics and formulas (or schematics and other schematics started by them) that are started/used by each other – this allows passing on information and doing different things depending on where they’re started from.
Schematics #
Local variables in schematics are only available as long as the schematic is playing. The variables are gone when the schematic finished playing.
Machine components can define Local Start Variables to initialize the local variables of a schematic to defined values. Machines and schematics that are started by a schematic can share the local variables, i.e. the newly started machine will have the same variables as the one it was started by, and the schematic that started the machine will also get the changes that where made in the new machine.
Furthermore, schematics share the local variables with formulas that are used in the schematic as well as other schematics it starts.
Formulas #
Local variables in formulas are only available as long as the formula is calculating. The variables are gone when the formula finished calculating.
Formulas that are used in other formulas will share the same local variables. Also, formulas that are used in schematics will share the local variables with the schematic. This can be used to e.g. initialize values for the formula’s calculation.
Examples #
A projectile (collision machine) defines the local int variable change with a value of -5. The used schematic will start a tagged event (tag healthChange) on the player’s game object and shares the local variables.
The player is hit by the projectile, a tagged machine is started by the tag healthChange. The used schematic adds the local int variable change to the object int variable health.
The player’s health will be reduced by 5.
A health item (trigger machine) defines the local int variable change with a value of 10. The used schematic will start a tagged event (tag healthChange) on the player’s game object and shares the local variables.
The player enters the trigger, a tagged machine is started by the tag healthChange. The used schematic adds the local int variable change to the object int variable health.
The player’s health will be increased by 10.
Global #
Global variables are available everywhere and at any time – they’re persistent in the running game, i.e. they’ll be available in all machines/schematics, formulas and other parts of Makinom. Global variables can be saved with save games.
Since global variables are persistent, you can use them to store information that needs to be remembered for longer periods of time, like a switch that was flipped by the player or the player score.
Examples #
An enemy ship is destroyed in a vertical space shooter. The enemy’s destruction is animated by a tagged machine that was called by the tag destroy.
The used schematic adds the object int variable points (set to the value 100) to the global int variable score (the current value is 200).
The player’s score increased by 100 and is now 300. The HUD displaying the score is updated due to the value change.
The player’s pistol ammunition is stored in the global int variable pistolAmmo, the current value is 16.
The player shoots the pistol (e.g. interaction machine using Key Press start type, or a tick machine handling player input in the schematic), the pistolAmmo is reduced by 1. The pistol’s ammunition is now 15.
The player collects more ammunition (e.g. trigger machine), the pistolAmmo is increased by 32. The pistol’s ammunition is now 47.
Object #
Object variables are bound to game objects in your scene by an Object ID. Like global variables, they’re available everywhere and at any time. They can be saved with save games.
Since object variables are bound to objects, they’re mostly used for storing information that is in relation to an object, like the health of the player and enemies.
Object Variables Component #
Binding object variables to a game object is done by adding an Object Variables component to the game object. When game objects share the same Object ID in their object variable components, they’ll share the same variables.
Optionally, the component can be set to be used in a local mode by enabling Local Variables. When used as local variables, the object variables are only available as long as the game object exists and can’t be shared between objects. This is usually used for storing information on not unique game objects, like enemies that are used multiple times.
Schematics and Formulas #
Object variables can be accessed in schematics and formulas in two ways:
- Game Object
Uses an object variables component attached to the game object to get the variables.
If there is no component attached, the variables can’t be used. - Object ID
Uses the object ID to get the variables.
This doesn’t require a game object and allows using object variables without binding them to an actual object.
Using an object ID to access them variables makes the available whenever needed, without a game object. This mechanic can be used to store information
Examples #
The health is stored in the object int variable health.
The player’s health is bound to the player using the object ID player. This ensures that the health is remembered even when the player’s game object is destroyed or a new level is loaded.
The enemy’s health isn’t bound through an object ID, but used in the local object variable mode. This ensures that each enemy has it’s own health – otherwise they’d all share the same health, damaging one would damage all.
The object ID item_1 stores information about a health restoration item:
- int variable healthChange is set to 50.
The object ID item_2 stores information about another health restoration item:
- int variable healthChange is set to 100.
When one of the items is used to restore health, you can access the amount they restore through their object ID. Changing their values will also change them whenever they’re used.
Selected #
Variables can also be stored in selected data. The actual variables used by selected data are still coming from one of the other 3 origins (local, global or object).
Learn more about selected data here.
Lists #
Beside storing single values into a variable, you can also add multiple values to a variable list. Lists are available for local, global and object variables.
If you want to use a list for storing or getting variables, this is also selected in the variable origin – e.g. to access a local variable list, select Local List instead of Local.
Adding to Lists #
When adding a value to a variable list, you can add it at different positions (index) of the list:
- Add
The value will be added at the end of the list. - Insert
The value will be inserted at a defined position.
Values at that position or later will be moved back by one position. - Set
The value will be set at a defined position.
A value currently at that position will be replaced.
If the list is currently not as long as the defind position, it will be filled up with default values (e.g. empty string, false, 0). - Random
The value will be set at a random position in the list.
A value currently at that position will be replaced. - Last
The value will be set at the last position in the list (i.e. the list wont grow).
The last value will be replaced by the new value.
This can be done e.g. using a Change Variables node.
Getting from Lists #
When getting a value from a variable list, you can get it from different positions (index) of the list:
- Index
The value will be taken from a defined position. - Random
The value will be taken from a random position. - Last
The value will be taken from the last position (i.e. the end of the list).
You can optionally remove the value from the list when getting it. This can be done wherever variables are used, e.g. in a Check Variables node.
Removing from Lists #
To remove values from a list, or a whole list, use a Change Variables node and enable Remove. When removing, the list change selection that’s used to add will be used to determine which position (index) will be removed:
- Add
The whole list is removed. - Insert
The value of the defined position will be removed. - Set
The value of the defined position will be removed. - Random
The value of a random position will be removed. - Last
The value of the last position will be removed (i.e. the end of the list).
Examples #
The global Vector3 variable list positions is used to store grid positions in the scene.
A schematic fills the list for a 8×8 grid by going through the rows and columns in a loop, i.e. (X=0, Y=0, Z=0), (X=1, Y=0, Z=0), (X=2, Y=0, Z=0), …, (X=0, Y=1, Z=0), (X=1, Y=1, Z=0), …, (X=8, Y=8, Z=0).
The positions list now contains all positions of the grid and can be used to place game objects on the grid.
The global Vector3 variable list positions (see previous example) contains all positions of a 8×8 grid.
A schematic uses the positions list to randomly place game objects (e.g. enemies, items, blocks) on the grid using a Spawn Prefab node (allows using variables as positions for spawning). Using the Random list origin and enabling Remove From List will get a random position and remove it at the same time.
The game objects are placed at random positions on the grid, each position only contains one object, since the used positions have been removed from the list.
Variable Values #
Variables can store different types of values. A variable key can store one value and one variable list of each type.
String #
A string value is simply a text, e.g. ‘sample’, ‘another sample’ or ‘yet another sample’ (excluding the ‘ characters). They’re used to store more complex information.
When changing string values, you can set the variable to the new value, add a string to the front or back of the current value or replace parts of the current value with the new value.
The default value is an empty string (i.e. no characters).
Bool #
A bool value is either true or false. They’re mostly used to store simple flags/states, e.g. if a quest has started or a switch was flipped.
The default value is false.
Int #
An int value is a whole number, e.g. 0, 1 or 42. They’re mostly used to store attributes (e.g. health, damage) or count things (e.g. player score or collected items).
When changing int values, you can set the variable to the new value or use math operators to change the current value of the variable with the new value, e.g. add the new value, multiply by the new value, etc.
The default value is 0.
Float #
A float value is a floating point number, e.g. 0.0, 1.2 or 4.5678. They’re mostly used to store attributes (e.g. health, if you don’t want to use whole numbers), time or for mathematical purposes.
Float values can be used as timers to automatically count them up or down over time – this is done using the Timer nodes.
When changing float values, you can set the variable to the new value or use math operators to change the current value of the variable with the new value, e.g. add the new value, multiply by the new value, etc.
The default value is 0.
Vector3 #
A Vector3 value consists of 3 float values (X, Y, Z). They’re mostly used to store positions or rotations.
When changing Vector3 values, you can set the variable to the new value or use Vector operators to change the current value of the variable with the new value, e.g. add the new value, scale using the new value, etc.
The default value is (X=0, Y=0, Z=0).
Axis Vector3 #
An axis Vector3 isn’t a separate variable value, but allows accessing the individual axes of a Vector3 variable as float variables.
Using this, you can individually change a selected axis of a Vector3, e.g. adding 10 to the X-axis or dividing the Z-axis by 2.
When changing axis Vector3 values, you can set the axis to the new value or use math operators to change the current value of the axis with the new value, e.g. add the new value, multiply by the new value, etc.
The default value is 0.