Godot Tips and Best Practice

Godot Tips and Best Practice


QRChat

Here are some of my best Godot tips, that I think you should at least give a thought. Surely, all Godot tips listed here may not always work out for you. Or maybe the better solution to a given problem is to not use them. But in general, I did find them very useful. Keep in mind that everything on this site is just my preference. And it is totally fine if you do it your own way.

Tips when structuring your game

The more you think about and plan the structure of your game in advance, the lesser the chance, that you have to start over or make major changes to your structure during the development. One time I was working on a game in Godot. I just went from prototyping the game to building on top of it. As the project grew in scope realised, that the structure of the prototype was not really convenient any more.

S,o I started over with a fresh project. And I worked on the new, better structure. But soon I figured out, that at some point I would like to add multiplayer to the game. But I would have to make major changes to the structure again in order to make it work. So I once again started to build the project new. Of course, some of the know-how of structuring a game comes with experience. But I would argue, that if I would have better thought out the structure in advance, it would have saved me some time. So here are a few tips in Godot to structure your game.

Use more than one scene

Look at Scenes in Godot Engine as a part or object of your game, that regularly can show up. Of course, you can decide for yourself, what a scene should consist of. Even though it is not advised, you could cram in your whole game into one big, single scene. But a much better approach is to split up your game into different scenes: So, for example, you could make a separate enemy-scene. Then, every time this enemy shows up, you can just instantiate this enemy-scene. 

One scene can also be made out of different scenes. So, for example, if you have a player-scene, it can consist of the body-scene and the weapon-scene. As you can see, the scene-system in Godot is a very flexible and versatile way of building your game objects and game worlds.

Your scenes should be able to run, even without the rest of the game

A good practice is, that you build your scenes in a way so that they can run independently from the rest of the game. If you have a player-scene for example, it would be very convenient if you could use that same player-scene in a completely different game. Just by copy-pasting the scene into the other game folder. This is possible, if you do not make connections via the SceneTree, but rather make the use of Signals and let them communicate that way.

Use signals

Signals are a very handy way to send a notification, that something did happen. A lot of Nodes already have built-in signals. You can find them in the Node tab (beside the Inspector – check the screenshot). From there you can connect them with your code. One of the most basic usages is connecting a button click to a function.

Signals and Groups - Godot Tips and Best Practice
Signals and Groups

A big advantage of using signals is, that you can let instances of scenes communicate with each other. But you are also able to run the scene on its own without breaking the game (you will get notified, that a signal is not connected though).

You can also build custom signals and connect them in your code. For more information check out my post about signals (also the official documentation here and here can help you understand signals)

Make use of groups

Right beside the signal tab is the groups tab (Check the screenshot again). There you can add a node to a group. Groups function a little bit like a tag system. You can also add something to a group in your code:

add_to_group("players")

Once a Node or Scene is in a group, you can check if that object is in a given group at any time like this:

is_in_group("players")

This is very useful if you want to check for collisions with a specific group for example. Check out this link, if you want to learn more about groups.

Use inheritance

Inheritance is a powerful way to structure your game. Even though it does sound like an advanced method, it is not that difficult to understand. And actually, it is very common in object-oriented programming. Imagine you have three different types of enemies in your game. All three enemies have characteristics, that they share, and characteristics, that are unique to each enemy. Let’s say that the enemies look the same, except, that the first is green, the second red, and the third is blue.

So one way to make that is by creating three unique scenes where you build those three enemies. One green, one red and one blue. Great, job is done. But if you want to change something about your enemies, you have to change it in every one of those unique scenes.

Make Inherited Scene
Make Inherited Scene

The second way is to use inheritance. So first, you would make a parent scene. In our example, this parent scene would consist of an enemy with no colour.  Then you would make three inherited scenes (check screenshot) of that parent scene and just change the colour of the enemy in each scene separately. So now you also have three enemies. But if you ever want to change that enemy scene, you just have to make that change in the parent scene. The inherited scenes will be changed automatically. Have a look here for more information on inheritance.

Godot tips for coding

Even though I mostly follow the rule “write dirty and write fast” I also think, that you should keep some things in mind, when you code in Godot Engine. Those Godot tips and tricks will help you with coding.

Write localisation-ready

Even though you may not consider localising your game right away, it is good practice to build your game and write your code what I call localisation-ready. This means that you have everything already in place, in case you want to translate your game at some point in the future. It is very easy to make that happen and it can save you a lot of time afterwards.

The only thing you have to do is to connect your in-game texts to your spreadsheet, rather than hard-code every line of dialogue or UI element into the script. Check out this post on localisation, to learn more about how to do that.

Use comments in your code

Use comments to write about what is going on in your code. Even though you might exactly know right now, what every part of the code does, it may not be like that one or two years later down the line, when you may think about making an expansion, or some changes to your game. Also, it is a lot easier that way, if you code in a team and someone has to understand what your code does. To make a comment in GDScript, just use #.

func _ready():
   #This line is just a comment
   pass

Naming your functions

This one is not really that important, but it may help to make your code more readable. Try to name your functions in a way, so that you later easily understand what it does. I myself try to name functions dependent on what they do or what they return. For example, if it returns a Boolean, I would start the function with is_. so if I want to check if the inventory is open I would call that function is_inventory_open(). Or if I have a void function that should purge the inventory, I would call it do_, so it would be called do_purge_inventory or something along those lines.

Even though GDScript does not have private functions, I start my private functions with an underscore: _my_private_func(). It is just my personal way, but I would recommend to you, that you find a naming convention that suits you. Once you have found one, try to stick to it since it makes reading your codes much easier.

The export keyword

Export is a keyword that you can write in your variable declaration. What it does is, that it “exports” the variable into the inspector block of the Godot Editor. This way you can change the value directly in the editor, not just in the code. In my eyes this is mostly useful for variables, that you expect to change – so mostly for testing and balancing stuff. Check out the following examples. All three are valid forms:

# This would add a variable called "health" to the inspector 
# with default value of 10
export var health = 10

# This would add a float called "chance" to the inspector 
# with default value of 0.1
export (float) var chance = 0.1

# This would add a variable called "damage" to the inspector
# with default value of 0
export (int) var damage
Exported Variable
Exported Variable

You can also use the export keyword for whole scenes or textures if you wish to do that:

export (Texture) var wall
export (PackedScene) var player_char

More Godot tips to consider

There are a couple of other things I would recommend in my Godot tips and tricks post. They are more a personal preference, but nonetheless, I would like to mention them.

Folder structure

When I started using Godot Engine, I ordered my project folder in a very specific way. All the scripts I put into a “scripts” folder. Every scene I put into a “scenes” folder. All of the materials I put into a “materials” folder, and so on and so forth. While this worked well enough in the beginning, I soon realised, that it was getting more and more complicated to navigate through the whole “scripts” folder in order to find that one specific script I was searching for.

So I quickly began to restructure my project folders. The best way for me to this date is to order my folder in a way so that every object has its folder (check screenshot). I then put everything associated with this object into its folder. This way I could always find what I searched for. Even in bigger projects. Godot itself also helps with this structure, since it has different symbols for different resource types. So you immediately can identify the script, or the scene or the material in the folder.

Folder Structure
Folder Structure

Make and use themes

One can not make a post about Godot tips and best practice, and not mention themes. Themes are a very powerful way to change the look of your game. In fact, the whole Godot Engine itself uses a theme to present you its Editor.

Theme in Godot
Theme in Godot

You can use it to make Control Nodes (so your GUI) look in a specific way. Define your theme and use it for your whole UI. To make a theme, just go to any Control Node and create a new theme (check screenshot). Save this theme and you can use it for all your other nodes.

To learn more about how to make your own theme check out my post on themes, or have a look here on the official documentation

Make use of the Input Map

Input Map - Godot Tips and Best Practice
Input Map

Even though you can check which button was pressed by directly write it into your code, it is good practice to use the Input Map. You can find it under Project Settings > Input Map (check screenshot).

There you can define your needed actions and also which keyboard key, mouse button click or gamepad button press can be used for the specific action. Check my post on inputs to learn more about that.

Also this way you can let the player customise the input keys. Check out this tutorial for creating a options menu to customise the key bindings.

I hope I could help you with my best Godot tips a little bit. If you have other Godot tips and tricks, that you want to share, tell me in the comments below. You can also write them to me via mail, and I may add them to my Godot tips post in the future.


To learn more about the Godot Engine I can recommend Godot Engine Game Development Projects by Chris Bradfield. If you are interested, you can follow the affiliate link to also support this website.


Godot Tips and Best Practice
Godot Tips and Best Practice

5 Responses

  1. Hi, thanks for the great post, really learns a lot! Here I have a question in Godot game development: while dealing with the collision between Player with other stuff(like coin or enemies in my little game), should I write functions in Player script or Item script?
    For example:
    In Player.gd: _on_Player_area_entered(): # do something…
    Or in Coin.gd: _on_Coin_body_entered(): # do the samething…
    I found that I have mixed them in my development and it is not so wise.
    Thanks for answering!

    • Hi, thank you for the comment!
      Basically, I would say, that it is up to you.
      I always try, that I have a clear pattern, and don’t mix it up too much. Otherwise, it makes it hard to find the code that I need to change later on.
      But you can either write it inside the player script (and for example check if the collision object is part of the group “coin”) and write whatever you like to do there.
      Or you can write it inside the coin script, do all the stuff there, and if you have to change something inside the player script too, you can call a function in player.gd via body (for example body.add_one_coin_to_player()).
      I would just advise sticking to one pattern in a given project.
      Hope this helps! Best regards Stefan.

  2. Thanks so much for your replay! And I have got your idea, the principles are so useful that I have adopted them to my coin game now. :xD
    And one last game logic in GDScript I wanna to ask you for advice: should I put the AudioStreamPlayer node in Player scene or just do that completely in the Main Game scene? What I encountered in the game there are 2 choices for me to make my game work:
    1. Add several audio nodes in the main game scene, one for each plays an individual auido stream.
    2. Just one audio player node with empty steam setup, but use preloaded audio assets while playing sound.
    What I preferred is the SECOND one, here is my sample code:
    “`
    var audio1 = preload(‘res://…/audio1.wav’)
    var audio2 = preload(‘res://…/audio2.ogg’)
    # …
    $AudioStreamPlayer.stream = audio2
    $AudioStreamPlayer.play()
    “`
    I found that a simple Godot project in GitHub do script with the FIRST one, is my code correct? What do u think? Thanks very much, hopefully you can understand my bad English words. 🙂

    • You are very welcome.
      Well, I think both are viable ways to achieve sounds in Godot.
      As long as the sounds do not overlap (playing two sounds at the same time), I don’t think that you will have a problem with the second approach. But I do not really know if one is better than the other in terms of performance.
      As for where to put the nodes: If you ask me, you can put it into Player, as well as into Main, as long as it is a single player game.
      All the best!

Leave a Reply

Your email address will not be published. Required fields are marked *

Post comment