Game Maker Language
This article does not cite any references or sources. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (August 2009) |
Game Maker Language (GML) is an interpreted programming language developed for use with a computer game creation application called Game Maker. It was originally created by Mark Overmars to supplement the drag-and-drop action system used in Game Maker. However, in the latest versions, all the drag-and-drop actions translate to GML rather than being separate from it.
GML is heavily integrated with the Game Maker environment. Usually, elements such as sprites and sounds are all organized within the Game Maker IDE (though they can also be loaded from external files). Game Maker's architecture is designed to handle such things as event detection, level design, and object configuration without the need to code them manually, minimizing code verbosity with intuitive interface features.
A common misconception is that languages such as Pascal and C++ can be directly used in GML. This is incorrect, and is a common mistake due to GML's ability to utilise Pascal and C++ style syntax (e.g. "&&" is interchangeable with "and").
Libraries
In Game Maker, a set of drag-and-drop actions is called a library. In the GM interface, these libraries are displayed as tabs containing icons called actions. Each action is a GML script or function that user can use in the game. Game Maker comes with a default set of libraries that contain the common actions used by most games; it is also possible to create libraries using the Library builder provided separately from Game Maker. There are many libraries that a Game Maker user may download to avoid using GML to achieve certain tasks. For example: If a user wants to make a simple 3D game but has no experience with GML, they can download 3D Library.[1]
GML syntax and semantics
GML is structurally similar to C-based languages in its use of code blocks, function calls, variable assignments, operator syntax, and so on.
GML makes a difference between statements and expressions. For example g < 1;
is not a valid statement and GM will return an error. Also, variable assignment is always a statement in GM, and cannot be used in an expression.
GML also allows increment/decrement operators. For example, the code
g += 1;
is the same as
g = g + 1;
The same function applies to the operators -=
, *=
, and /=
.
Game Maker does not allow ?: syntax. GML statements can be separated by semicolon, but Game Maker does not force this.
The code
sprite_index=spr_player;
is not the same as
spr_player=sprite_index;
Functions
Game Maker has a large library of built-in functions available for basic functionality. The programmer can also create scripts which are called in the same way functions are. The drawing functions in GML make use of the Direct3D API.
GM also has built-in functions for calling external DLLs. Any feature that is not provided natively through Game Maker can be added using DLLs.
Variables
Normally, GML does not require that variables be declared as with many other programming languages. A variable is created whenever a programmer first assign a value to it, as with foo = "bar";
.
GM has many built in variables and constants. Each instance in the game has a set of built-in local variables such as "x" and "y". There are also some built-in global variables such as "score" which exist independent of individual instances.
User-defined variables can be either local or global. Local variables are the default; they are primarily used by the instance to which they are assigned. In order for another instance to use them, they must use the appropriate prefix, such as "(100001)." or "ball.". Global variables use a "global." prefix for all instances. In certain cases this prefix may be dispensed with: either if the variable has been initialised with "var" or "globalvar" statements, or if it is a built-in global variable.
Arrays may also be declared in GML and may be 1 or 2 dimensional. Arrays may contain a mix of strings and real values, but not arrays themselves. Arrays may not be passed to a function and may not be returned from a function in GML. GM also has built in limits on index sizes. Indexes may not be bigger than 32,000 and any single array may not contain more than total of 1,000,000 values. GML also features functions used to create and edit six simple data structures. These functions are only available to users who have the Pro version of Game Maker. The data structures available are Stacks, Queues, Lists, Maps, Priority Queues, and Grids.
Types
For the sake of simplicity GML only has two variable types. Every variable may hold each type of data without any type declarations.
- Strings are sets of ASCII characters that may be of any length. Because GM prefixes string sizes to the strings as a 4-byte integer, strings may not be longer than 4,294,967,296 characters. If a string exceeds this limit, 4,294,967,296 characters are cut from the beginning until the string is under the limit. However, most situations will use far shorter strings, so this limitation is rarely encountered.
- Real values are signed floating point numbers. Since version 6.1, GM has also allowed hexadecimal representation of real values in code (preceded by "$"). In version 6 real value handling had a bug which limited real value accuracy to be smaller than intended (which caused inaccurate results when calculating with large real values). The issue still exists in GM7, but it has been mitigated with greater precision.
Because GML has no boolean values, statements that require boolean values, such as "if" will evaluate any value larger than 0.5 as true, and 0.5 or any smaller value as false. The constants "true" and "false" may be used in place of 1 and 0 in GML.
Scope
In GML, there are two types of variable locality: locality to an "instance", and locality to a "script" (or any other piece of code that has its own container). Being local to an instance means that a variable is tied to that particular instance and can be called only with a prefix identifying the instance; being local to a script means that a variable can only be referenced within that script (and expires when the script finishes processing), since scripts do not have identifiers that are accessible to the user. When the term "local" is used without further specification, it usually refers to instance locality.
By default, a variable is local to an instance but not local to the script in which it is used. To make a variable accessible for all instances, it can either be accessed through the global namespace (global.foo = bar;
) or declared explicitly in the form globalvar foo, bar;
. With the former route, the variable must always be referenced with the global.
prefix; the globalvar
declaration allows a global variable to be accessed without the prefix. To make a variable local to the script in which it is used, the keyword var
is used, as in var foo, bar;
.
Variables that are local to an instance can be accessed outside of that instances actions by prefixing the variable name with an instance identifier (instanceReference.varname
). If multiple scripts are on the processing stack at the same time, there is no way to access script-local variables in one script from another, unless the variable is passed on to the other script as an argument.
The current instance namespace can be changed using the "with" construct. For example, the following piece of code, placed in a collision event, could be used to destroy the other instance involved. In generating a collision event, Game Maker automatically creates the variable "other" as a reference to the other object involved.
with (other) { instance_destroy(); }
Note that when a variable is declared local to a particular script, it loses its association with the instance that called the script and becomes instance-independent. For example, the following code would work correctly even though the variable foo
is not defined for someOtherInstance
.
var foo;
foo = "bar";
with (someOtherInstance) { show_message(foo); }
A common gravity statement is one such as this.
if place_free(x,y+1) {gravity=0.5} else {gravity=0}
Memory allocation
GML automatically allocates memory for variables on demand, and uses dynamic typing so that assignments with different types of values are possible. For example, one can create a variable as an integer, and change its type to a string in two lines:
intNumber = 1;
intNumber = "This variable now contains a string";
Unfortunately, there is no command for releasing a variable to free memory. When an instance is destroyed or a script finishes processing, however, any variables local to that instance or script are released. Hence, to conserve memory, it is advisable that one use variables local to either instances or scripts to store information rather than global variables.
For storing and manipulating larger amounts of data more efficiently, Game Maker has some built in data structures, such as stacks, queues, lists, maps, priority queues and grids. These structures are created, modified, and destroyed through built-in functions. There are also functions for sorting these structures, respective to each structure type. This can be particularly beneficial for speed optimization since the pre-compiled functions avoid the need to cycle through many loops of interpreted code.
Instances and resources
Game Maker does not support pointers to reference locations in memory. Thus, each resource and instance in Game Maker has a unique ID number, which is used to reference that particular resource or instance. This ID number can be used by scripts and functions to reference a particular instance or resource. Upon creation of a resource in GM the name of the resource is defined as a constant which references that resource (for objects the first instance is referenced). The ID of a particular instance of an object can be found using the variable "id".
When creating resources or instances at runtime, its unique ID is returned and may then be passed to other variables and functions.
3D in Game Maker
Although Game Maker was originally created for two-dimensional programming, the Pro version also has 3D functionality. The standard action library does not cover 3D programming, so users must either use GML code or download additional libraries. Game Maker uses Direct3D (D3D) for both 2D and 3D drawing.
Code examples
Here is a simple piece of code that would display "Hello World!" in a popup message box.
show_message("Hello World!");
Another example that would display the same text in the game window instead. Note that by default Game Maker redraws the background continuously, so using the default setting this code would need to be attached to the draw event for drawing to work properly.
draw_text(0, 0, "Hello World!");
Here is a piece of code from a game using GML:
// This is a comment
/* this is a C-Style comment. */
/* temporary variable declaration.
A temporary variable will be released at the end of a script.
Note that this doesn't declare it to be of a specific type! */
var xx, yy, nn;
// A conditional. It can also be shortened to "if (can_shoot)".
if (can_shoot = true) // "=" and "==" can be used interchangeably in conditionals
{ // This begins a block of code. You can also use "begin" as with Pascal.
/* Here we are setting the variable to false. This could also be written as "can_shoot = 0;"
since Game Maker doesn't distinguish between integer and boolean types. */
can_shoot = false;
/* Here you are setting the 0th alarm to five steps. The alarm
variable will automatically count down to 0, and when it hits 0,
the alarm0 event will be triggered. */
alarm[0] = 5;
/* Here the temporary variable xx is defined implicitly as an integer,
and the lengthdir_x function is used. */
xx = x + lengthdir_x(14, direction);
yy = y + lengthdir_y(14, direction);
//This function creates a obj_bullet and then returns its instance id to nn.
nn = instance_create(xx, yy, obj_bullet);
/* The with statement allows you to access the fields of an object directly,
without having to write statements like nn.speed or nn.direction. */
with (nn)
{
speed = obj_tank.speed + 3;
direction = obj_tank.direction;
}
}
GML supports many variations in syntax. As a demonstration, the previous example could also be written like this:
var xx, yy, nn;
if can_shoot = true then begin
can_shoot := false
alarm[0] := 5
xx := x + lengthdir_x(14, direction)
yy := y + lengthdir_y(14, direction)
nn := instance_create(xx, yy, obj_bullet)
with nn begin
speed := obj_tank.speed + 3
direction := obj_tank.direction
end
end
Here is an example of basic keyboard-controller movement. The motion_set function takes two arguments: direction (degrees) and speed (pixels per step). Calling this function will assign an instance with a "speed" and "direction" (both built-in local variables), which Game Maker uses to update the instance's position automatically each step (an instance's position can also be modified directly using the built-in local "x" and "y" variables).
if (keyboard_check(vk_left)) motion_set(180,4);
if (keyboard_check(vk_up)) motion_set(90,4);
if (keyboard_check(vk_right)) motion_set(0,4);
if (keyboard_check(vk_down)) motion_set(270,4);
if (keyboard_check(vk_nokey)) motion_set(0,0);
Here is an example of a more complex script from a platform game. Using this, the player can walk over hills and bumpy terrain.
if (!place_free(x-4,y))
{
if (place_free(x-4,y-4))
{
x-=4;
y-=4;
}
else if (place_free(x-3,y-5))
{
x-=3;
y-=5;
}
else if (place_free(x-2,y-6))
{
x-=2;
y-=6;
}
}
else
x-=4;
Here is a piece of code that draws a simple 3D floor (the function d3d_start()
must be called beforehand).
d3d_draw_floor(0,0,0,500,600,1,background_get_texture(background1),.01,.01);
Manual
The manual that accompanies Game Maker is a document that has information on all the built-in functions and variables available in Game Maker, with the exception of action functions (the direct GML equivalents to drag-and-drop actions), and deprecated variables and functions left in for backward compatibility, such as image_scale, which has been succeeded by image_xscale and image_yscale.
A notable example of a deprecated variable is image_single, which when changed to a sprite's subimage, will set image_speed to zero automatically, as well as setting image_index to the value image_single is set to.
Criticism
Common criticism towards Game Maker is its odd typing system, where variables can only be strings or real numbers, yet also be indexed like arrays. There is no way to make a variable hold an array, the name of the array implicitly accesses the first element. As such, there is no way to pass an array as a script argument. The other data structures are not very well integrated into the language, requiring a type unsafe index handle to the data structure, and requiring explicit deallocation (which has the potential for memory leaks). As well, they are only available to registered users.
The loose syntax of GML makes it easier to program in to an extent, but has the potential to cause very hard to read source code. The following is an example of what is possible:
switch 0begin case 0:x=0break}
if a=0then begin b=1}else if a==0{b:=1end
Although not directly a part of the language, another common source of criticism is Game Maker's creation of .exe files that consist of a runner and the textual GML source, waiting until the end user runs the game to parse into an Abstract Syntax Tree. This facilitates decompiling, and causes much slower start up times than necessary.
External links
- Official GML documentation
- YoYo Games official website
- Game Maker discussion forums
- Game Maker wiki
- GameMaker Programming Video Tutorials
- Gamemaker news, comment, discussion, opinion and community news
da:GML es:Game Maker Language fr:Game Maker Language it:Game Maker Language nl:Game Maker Language no:Game Maker Language pl:Game Maker Language pt:Game Maker Language sk:Game Maker Language fi:Game Maker Language
If you like SEOmastering Site, you can support it by - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 and more...