In this tech blog we want to discuss a couple of features that new users to GameMaker Studio (and even some veterans!) may not be fully aware of: Ghosted Parent Events and Object Variables. These are two powerful features in the IDE related to how you can interact with objects, and while they don't change anything fundamental with how objects work, they are definitely quality-of-life improvements that make using objects easier.
To start with, we'll look at the ghosted parent events feature, which is related to those objects that are designated as "child" objects of a common parent. For those of you unfamiliar with the concept of parent objects, we'll start by giving a brief explanation of what a parent is and why parenting (also known as "inheritance") is a really important tool in your GameMaker arsenal.
PARENTING AND GHOSTED EVENTS
Parenting in GameMaker Studio 2 is a way to add events with code or DnD™ into one object (the "parent"), and then choose one or more objects (the "children") to inherit these events. As one example, let's consider something like a simple button in your game's UI. In most games you'll have multiple buttons for things like full screen mode, sound on or off, gamepad rumble, etc... and while they all do different things, they all essentially work in the same way, i.e: they will have a hover state, a pressed state and a released state, as well as a Create Event and probably an Alarm or two. So, we can deal with all of this common behaviour in a parent object and then create child objects for each in-game button we want and the only thing we need to add to these objects is code or DnD™ specific to the button's needs.
To give another brief example of parenting, it can be used to make dealing with collisions much cleaner and easier - Instead of checking for collisions with a load of different enemy objects, you can set a parent for all the enemies and have a single collision check instead, since checking a parent object for a collision will automatically include all its children too. The image below shows an example of this:
On the left we have the parent object and on the right one of its children. In old versions of GameMaker, the child object would only show those events that you add in to it to override (or add to) the parent object, but in GameMaker Studio 2 we have ghosted parent events, which are the events that are greyed-out in the child object. This now permits you to see exactly which events an object has regardless of whether they are inherited or not, meaning you don't have to keep switching back to the parent object all the time to check code, etc...
If you simply click on a ghosted parent event, it will open up a locked code window showing the code or DnD™ that it contains:
You can also use the right mouse button on the event to get more options:
Open Parent Event - This will open the parent object on the event selected
Inherit Event - This will open a code/DnD™ editor with the function
event_inherited()added already, so that you can add further code or actions to the event and still inherit those contained in the parent event.
Override Event - This will open an empty code/DnD™ editor so you can add new code or actions to override the parent event.
So, there you go! We now have a much more visual representation of parents and the events that child objects inherit, as well as a more intuitive and clear way to edit them.
Talking of visual representations, let's now move on and look at the second of the IDE features we want to discuss today... Object Variables!
It's time now to look at the Variable Definitions feature available to all objects in the Object Editor:
Before we actually look at this feature in action, let's take a moment to discuss the concept behind it and how Object Variables fit into the event order. Essentially Object Variables are simply variables added to an object through a visual interface... which doesn't sound too interesting until I tell you that you can then tweak these variables on an instance scope when placed in the room editor, and they can also be inherited from parent objects! Oh, and Object Variables are also initialised before everything else in an instance, meaning they can be used by the Create Event! These three points are what makes this feature so interesting, as it makes level design in the room editor a lot easier - especially if you have a designer/artist on your team who doesn't really want to go searching through a load of code to set a value - and also opens up extra possibilities to make your code more dynamic and reactive.
When you click the Variable Definitions button in the Object Editor, it'll open the Object Variables Editor, which will look something like this:
In this window you can click on the Add button to add a new variable to the list. You should then name the variable and set the type of variable it is to be and adjust its properties:
The type of variables that you can set here are:
Real: A real number is any number that is not a whole integer and can be positive or negative. So, 124.5, 45639.566546456, 0.9, -45.5, etc... are all examples of real numbers. All real numbers are stored as 64bit floating point values, so you may experience slight rounding errors when dealing with these. Note that you can set a range of values for the output real from the Variable Options (see below for more details).
Integer: An integer is a whole number and can be positive or negative, for example 30004, 19, 0, -300. Note that you can set a range of values for the output integer from the Variable Options (see below for more details).
String: A string is anything that you want to be represented as text, for example "fish", "Hello World", or "12345". Note that you do not need to use the quotation marks when entering your variable values - GMS2 will add these for you.
Boolean: A boolean is a value that is either
false. In the Object Editor Variables window, this is simply shown as a box that you check for
trueand uncheck for
Expression: An expression is a mathematical phrase that can contain ordinary numbers, variables, strings, or GML functions as well as one or more operators. For example
sqrt(85 * 6) + 5.5is an expression.
Resource: A resource is simply any one of the resources that you have already created in the resource tree. When you select the resource type, you can then click on the Open Asset Explorer button to open the Asset Explorer and select the resource you require. Note that you can set filters for the assets shown in the Asset Explorer from the Variable Options (see below for more details).
List: Selecting a list type of input means that you can then create a selection of values (these can be strings, reals, expressions etc...) of which you can then choose one or more for the variable to return. To define the items that go in the list you need to add them into the Variable Options first (see below for more details) and then you will be able to choose the item as the default value for the variable in the main window from the drop down menu:
- Colour: The colour type is for you to define a colour value to be stored in the variable. You can input a real number from 0 to 16777216 (and this will have an alpha value of 255), or a hex value in the format of $RRGGBBAA, or you can double-click on the colour swatch to open the Colour Picker and select the colour there.
Once you've added in your variables the Variable Editor will look something like this:
To the right of the above image you can see a couple of extra windows open. These are for setting the Variable Options (as mentioned above), and you can access these by clicking the cog icon in the editor beside the variable. The real and integer data types have an option for setting a range of values and when you check this you can then input a start value and an end value and instead of having a fixed value shown for the variable in the Object Variables window, you will have a slider that is clamped to these values:
The list data type options are slightly different as here you can add a number of different values that you want to be included as possible returns for the list type variable. You simply click the Add button to add the new value (which can be a string, real, integer, or resource name) and then in the object editor Variables window it will appear in the dropdown list for the default value and you can select whichever one is required. If you have checked the option Multi-Select, then the drop down will have checkboxes beside each of the values that you want to have returned by the list variable, and the variable will become an array to hold each of them:
As briefly mentioned above, an important feature of the Object Variables is that they are inherited by any child objects that you have in the resource tree, which means that you can then choose to override or change any or all of them if you wish. When you create a child of an object resource which has Variables defined for it, these will show up as ghosted parent variables in the Object Variables window for the child also, like this:
You can see in the top image that the Parent object has four Object Variables and in the bottom image these are also shown, only now they are ghosted from the parent and have been greyed out to indicate that they have been inherited. These inherited variables can then be edited if you click the Override Variable button, so you can then adjust the range slider or values, or select different items from lists, etc... Note that when you edit a parent variable you can only change the defined value (so, not the name, type, or the options). Also note that you can create additional Object Variables in child objects as well (and in the example image above you can see that "char_type" is a new Object Variable only for the child object).
If you have edited an inherited Object Variable, then you can click the Delete button to remove the overriding value, but the variable will still be inherited from the parent using the parent's default value again. If you need to completely remove the variable, then you must do this from the parent object.
One final important thing to note about Object Variables is that they are also available to you to edit in the Room Editor on a per-instance basis. So, you can define a general value for all objects in the object editor, then when you place an instance of the object in a room and these values can be tweaked, and the change will only affect that one instance:
This makes level design far more intuitive and a lot easier!
Having a visual aid when dealing with abstract concepts and being able to tweak things in a natural way are important when working on any project, and we hope these features go some way to making your workflow easier and cleaner. We want to make using GameMaker Studio 2 as easy and intuitive as possible - especially when working with multiple parent-child relationships or when creating levels in the Room Editor - and think that these features do just that and we encourage you to get used to them and incorporate them into your projects.
Thanks for reading and, as always, have fun making games!