GODOT: Create a game
Calvin Robinson explores game development engine Godot, and reveals how to script a user interface for a 2D video game.
Calvin Robinson explores the game development engine Godot, and reveals how to script a user interface for a proto 2D video game.
Godot is a free (as in beer) and open source video game engine. It’s an impressive toolset provided at no cost and with liberal licencing that enables people to create their own video games without spending months first creating the engine.
The idea is very similar to Pygame, a Python module we’ve used often in games programming tutorials in this magazine, in that an advanced toolset is compiled that includes most of the groundwork one would need to create a game. Things like sprites and physics are taken care of, so the programmer can get straight onto designing their video game.
Godot uses an MIT or Expat licence that grants programmers the permission to use Godot for any purpose: study how the engine works; change the engine itself; and redistribute versions of Godot with or without changes. Programmers are even free to commercialise custom versions of Godot under a different license, provided a notice of the original Godot is distributed in the documentation. That’s a very free (as in speech) licencing scheme.
Of course, any game or software created with the Godot engine is the sole copyright of you, the developer. While it’s important to include a copyright notice of the engine used in your documentation, anything you create in Godot belongs to you to do with as you please. These are fair and incredibly permissive terms.
Being FOSS, Godot is cross-platform, with versions for Linux, Windows, Mac OS X and BSD. Additionally, it’s also multi-platform, working on IOS and Android devices, as well being able to deploy games for the Nintendo Switch, Playstation4, Xbox One and HTML5.
How to Godot started
First of all, Godot supports both 2D and 3D visual rendering, making it easy to design games for either perspective. The interface itself is user-friendly enough for projects of scale, and ease of use seems to have been a contributing factor to the design of this engine.
While Python support in Godot isn’t ‘official’, there is community support available for it. Officially endorsed options are C# or C++ for the more advanced programmers. For those just starting out, or with limited programming experience, Godot offers a high-level scripting language called Gdscript, which is pretty similar in syntax to Python, with influences from Java. And if coding isn’t your forte, there’s also a visual scripting interface built in. The visual editor is contextsensitive and WYSIWYG (what you see is what you get).
Built with Object Oriented Programming methodology in mind, Godot games are created with Nodes, which suppose instancing and inheritance, making it easier to implement levels/scenes and objects. There’s also a funky feature called Persistent Live Editing, which enables changes to be made in realtime and saved even when the game is stopped. The ability to modify the game while it’s running, even on mobile devices is a real USP for Godot. Meanwhile, Scenes make it possible for creatives to work on their own sections of the game without getting in each others’ way. For example, someone could be developing levels while another person is working on characters.
Godot uses Github for collaborative coding, so teambased projects will work just as with most other opensource projects.
Alternatives
Yoyo Games’ Gamemaker Studio has been an industry standard in this area for some time now, offering multi-platform publishing for desktop, web, mobile and console. Gamemaker features a visual drag-anddrop editing platform as well as a scripting language called GML.
However, Yoyo Games’ free offering is now limited to 30 days. Starting at $39 for a creator, $99 for a developer and $799 for the ability to export to games consoles, Gamemaker Studio is potentially pricing itself out of the market for first-time indie game developers. Games produced with GMS include Hotline Miami,
Nidhogg, Undertale and Shovel Knight.
Unity Engine is arguably the most well-known, providing a completely free solution for any person earning less than $100k revenue. Unity is great for building console, PC and mobile games, as well as augmented reality and virtual reality software. Some well-known titles produced in Unity include Ori and the Blind Forest, Cities Skylines, Kerbal Space Program and Monument Valley 2.
With Godot being the newest entry to the indie developer platform scene, we’re yet to see any hugely commercially successful titles released that have been built in this engine. That means there’s always a chance yours could be the first!
2D vs 3D graphics
2D games might be the best place to start. The built-in tile-map editor has auto-tiling, rotation, with multiple layers and custom grid sizes. While Godot enables editing on a pixel-by-pixel basis, there’s scalability to match any resolution and aspect ratio. There’s some basic lighting, collision detection and physics to work with, but what’s really interesting is the animation system. Godot can be used to animate sprites either on an object basis, or broken down to limbs and joints. For the newbies there’s a helper tool to assist with the animation of skeletons. Using transitions and tweens means animating sprites in Godot is similar to Adobe
Flash, for those of us old enough to remember.
Of course if you really want to blow ‘em away you’re going to want to play around with the 3D renderer. Godot supports full MSAA (multisample anti-aliasing) settings, with subsurface scattering, refraction and reflections. Combined with some decent lighting (global illumination) and post-processing effects that support HDR, bloom and depth of field, we’re able to create something that’s reminiscent of today’s top games. In 3D mode it’s also possible to import 3D animations, which will come in handy for more complex animations.
While Godot is available on a whole host of systems and has downloads available on its website, we found the simplest and most straightforward way of getting Godot downloaded, installed and kept up to date is by using Steam. A simple sudo apt-get update && sudo apt-get install steam should get Steam sorted on a Debian-based distro. There’s also a .deb installer at
Steampowered.com. Run Steam for the first time, accept the terms and conditions and install the font packages, sign up and sign in, and you’re ready to go.
On the Steam store page, search for Godot, install it for free and it’ll appear in your library. Depending on your Steam settings, Godot should now stay up to date at all times. Use the library to launch Godot. You can add a desktop and/or Start menu shortcut by right clicking and going to Properties.
Hello world
The first thing we see when booting up Godot is the Project Manager. By default it’ll display a list of demo projects. The menu over on the right-hand side presents the options to either start a new project or import one from elsewhere. We’re going to start off by selecting New Project.
We’ll need to give our project a name and choose somewhere reasonable to save its progress. We also get
the option to choose which version of Opengl we’d like to use to render our game in. This decision affects the amount of resources available to us. For anyone on an older or slower computer we’d recommend sticking with Opengl ES 2.0. However, if you’ve got a decent spec computer there’s no reason not to go with Opengl ES 3.0 and have the full feature set available to you. Only 3.0 supports High Dynamic Range (HDR).
Now, along the left we have our main menus, on the right our playtest buttons, and the big grid in the centre is the workspace. By default it’s a 3D environment. In the bottom-left corner we see our Filesystem – this will keep track of all assets used by our game. In the top right we’ve got our Inspector menu. The Inspector controls the properties of our scene and its content, for example our classes and the properties. The toolbar above our workspace will change to reflect the type of environment, be it 2D or 3D, but this is how we’ll navigate said environment. At the very bottom of our screen we have the debugger.
Choose your node
With everything loaded up, we’ll need to select the type of Node we want to begin with. Our options are the Root Nodes on the left; 2D Scene, 3D Scene, User Interface and Other Node. We can, of course, have multiple Nodes in our game. Often times we’ll want to use begin with a User Interface and progress to a 2D or 3D Scene, depending on the type of game we’re building. The easiest way to switch between the 2D and 3D workspaces is by tapping F1 or F2 on your keyboard. F3 takes us into the script-editing mode. This is slightly breaking convention, because F1 is usually reserved for Help in most applications. In Godot, Help can be found with Shift+f1, where there’s a helpful searchable index of the documentation.
Now, we’re going to make our first Scene. A Scene is a collection of Nodes (these are items/objects within our game). Select the 2D Scene or press F1 and click the little + icon to add a Node. Type ‘label’ and hit Create. There we’ve got our first text label in our new 2D environment. On the right we can type in the text ‘Hello World!’ and should see it immediately reflected in the workspace.
Press Play or hit F5. Godot will prompt you to save your current scene. Perhaps name the scene Helloworld, keeping the default extension. The game world should load up in a new window with a grey background and the words Hello World! in white text. We’ve successfully created our first game. Well, kind of. It’s not really a game until there’s some interaction, but we have at least initialised our first executable program.
Let’s look at adding some functionality to our interface. Click the + again to add a child Node. This means we’re creating a new item (Node) that belongs to the same scene. This time, we’ll go with a button – something more interactive. Once the button is spawned we can alter its size by dragging the transformation box surrounding it, or we can look at the properties in the Inspector module on the right-hand side of the screen. Change the ‘Text’ dialogue from blank to ‘Click Me’ or something similar.
Our button doesn’t do much at the moment, other than look pretty. In order to control it, we’ll need to create our first script. Right-click the top node, the parent node, and select Attach Script. Give it a name, save it and the script editing window should appear.
Make the connection
We have a button and a script. Now we need to connect the two. Select the button on the left-hand Scene menu and switch to the Node tab on the right-hand Inspector module. Press Signals and scroll down to pressed() .A dialog window will pop-up asking what we’d like to connect our button to. Since we only have one script at the moment we won’t be able to change anything here, so just click Connect and the script will be linked to the button. We’ll see a new function in our script code, called _on_button_pressed() .
The two functions in our script will need a line of code each to get the working as intended. _ready will
need get_node("button") to link with the button and _on_button_pressed will need get_node("label").text = “You clicked!" which will change the text of our label (the first thing we made) from Hello World! to You clicked!.
Save the game, hit F5, we should now have a basic 2D user interface that says Hello World!, with a button reading Click me! that, once pressed, changes the aforementioned text to You clicked!. Well done!
The full code as it stands:
extends Control
func _ready(): get_node("button") get_node("button").connect("pressed”, self, “_ on_button_pressed") pass
func _on_button_pressed(): get_node("label").text = “You clicked!” pass
Bearing in mind that if we ever change the name of our Nodes (Button and Label), we’ll need to also alter this code. Best practice would dictate that we name these something more appropriate, it’s poor form to name a Node after the type of item that it is.
Set up automation
We can display text on the screen and interact with our environment through user actions. However, we haven’t yet implemented any automated events. Godot handles automation through the inbuilt _process function. Let’s experiment by creating a timer to demonstrate how long our program has been running.
Create a new label with Ctrl+a or + on the Scene menu. Give it a name, this time, by double-clicking Label2. Move the new label in the workspace, so that it’s not sat on top of “Hello World!”. Now, create a new script by right-clicking the new label in the Scene menu and pressing Attach Script again. Then insert the following piece of code: var num = 0
func _process(delta): num += delta text = str(num)
Here we’ve created a variable. Godot likes variables to be declared with var before them, like Java. We’ve made a float called num and initialised it at zero. Next we’re using the process function to perform a calculation with num by adding delta to it (we’ll get to that in a moment) and finally we alter the text of the label to display the result of num . You may notice we changed num from a float to a string with the str tag. This is called casting, and Gdscript handles it in exactly the same way as Python.
Some background knowledge to understand what we’re doing with delta. The _process function of any Node is executed between frames. This means that if our game is running at 60 frames per second, the code will be processed 60 times in a second. delta is a parameter that monitors the time between seconds as a double/float. This might come in handy when the game’s framerate fluctuates, or as in our example, when we want to monitor the time our game has been running. If everything is working as intended now, pressing F5 should save and load our game, which will have a running timer.
Godot gives us the ability to group nodes together, so that we can alter multiple objects at once. This could be useful for example, when we want to spawn several bad guys simultaneously. To familiarise ourselves with this function, switch back Inspector to Node on the righthand module and change from Signals to Groups. Add a new group for our labels, perhaps calling it labelgroup
in this instance. Now, returning to our scripts (F3) add add_to_group("labelgroup") to the _ready function of both labels. Now if we were going to test this, we could, for example, use our button to change both labels at once, or add another button to wipe them clear. An example of this implementation might be: func _on_clear(): get_labels().call_group("labelgroup”, “Reset")
We could also use a variable to list all nodes within a said group with var enemies = get_labels().get_nodes_ in_group("labelgroup") the possibilities for this are endless. There’s a GUI for handling which labels are or are not in a group, by hitting the Manage Groups button.
Next issue we’ll return to Godot and build on what we’ve learnt here to develop our first video game.