How To Structure Your Godot Project (so You Don't Get Confused) (2024)

This is a guest post by KP, whom I found by a very detailed and thoughtful comment he posted on Reddit /r/godot. If you like the post, make sure to check out his Youtube channel

A tale as old as time. You just started to get familiar with Godot, and your project is starting to get huge. You have a mess of folders with scenes and nodes and resources and images and audio files and every time you look at the 'FileSystem' tab you feel totally lost. You went here and left feeling unsatisfied.

Don't worry! I have some tips for you that will make all your problems melt away. This is just how I do it. Some of it is based on Godot's best practices, but as far as I can tell there isn't a consensus on how to set up your FilesSystem in the way there is with Java for example. So we're all on our own. But it doesn't have to be this way!

Setting up your file system

I like to have a 'scenes' folder, an 'assets' folder, and a 'src' folder (for autoload scripts).

How To Structure Your Godot Project (so You Don't Get Confused) (1)

For more complex games, I also include a 'utils' folder at the top level for any type of menu that is used for development but isn't going to be part of the main game. That way you can easily exclude it when exporting. Also you'll have an 'addons' folder here if you install any plugins.

Personally I think the top level part is mostly preference, so do whatever makes sense to you. But do think about it early and stick with your structure, because moving stuff around can break things. If you do need to move stuff around, (especially important because I know some of you are going to be applying this to your already large messy projects) right click on the file in the file system and use 'Move To...'.

How To Structure Your Godot Project (so You Don't Get Confused) (2)

Dragging and dropping works too, but I often find that the 'FileSystem' tab isn't very clear on where it's going to put stuff and I end up moving things to some folder that I can't see and have no idea where my stuff went. Either way, when you move stuff in godot it does some things in the background so it doesn't lose track of where things are, but you'll still probably have to fix some things if you're moving a resource and are referencing it somewhere.

How To Structure Your Godot Project (so You Don't Get Confused) (3)

Even if you think you've done everything right, be careful; if you reference a path anywhere in your code using a string, you'll have to go through every script and change it, and Godot won't help you. It'll just throw an error at runtime when it can't find the file. In this case I reccomend using a text editor to find and replace on all of your files. This is a big reason to reference scene and resource paths using export var resource_inst : Resource rather than using Strings.

Whatever else you do, don't move files around outside of Godot. You'll wish you handn't I promise. I'll explain why later.

Making a main scene, and telling Godot where to start

It's good to have somewhere to start and set everything up. Make a scene called 'main.tscn' in the 'scenes' folder with a generic node object called 'Main', and attach a script called 'main.gd'. This node will always be around, and you can use it to set things up when your game starts. If your game has a main menu, you will probably want to start with that, so make a control node that is a child of the Main node.

How To Structure Your Godot Project (so You Don't Get Confused) (4)

You can set this as the 'Main Scene' in project settings. This tells godot where to start when you click the 'play' button, and this is the scene that will start first when you export your application.

How To Structure Your Godot Project (so You Don't Get Confused) (5)

How To Structure Your Godot Project (so You Don't Get Confused) (6)

If you don't already have one set, you can also do this from the right-click menu in the 'FileSystem' tab.

How To Structure Your Godot Project (so You Don't Get Confused) (7)

There's something important you should know about this though. When you set a scene as the main scene, Godot will load it when the application starts. Meaning the Godot application, not your game. Meaning if you do something to the main scene that prevents Godot from opening it, (Like moving stuff around outside of Godot, like I already told you not to) Godot will not be able to open your project. To fix this you can open the project.properties file in a text editor and delete this line:

How To Structure Your Godot Project (so You Don't Get Confused) (8)

You might be wondering; "Why not just put the stuff that should stay around in an autoload?" One word; Encapsulation. Autoloads are accessable from everywhere, and you don't want this stuff to be accessable from everywhere, you just want it to be around. Globals can be dangerous, and are a fantastic way to get confused when things go wrong.

Names and why they're important

Styling is important when thinking about project structure if you want to keep yourself from getting confused. Refer to Godot's style guide for best practices about scripting style and file naming conventions.

From the Godot documentation:

Use snake_case for file names. For named classes, convert the PascalCase class name to snake_case:

# This file should be saved as `weapon.gd`.
class_name Weapon
extends Node

# This file should be saved as `yaml_parser.gd`.
class_name YAMLParser
extends Object

This is consistent with how C++ files are named in Godot's source code. This also avoids case sensitivity issues that can crop up when exporting a project from Windows to other platforms.

This applies to all types of files. Scenes, scripts, resources, everything. Note that Godot automatically suggests filenames as whatever the root node is named, which should be PascalCase (like camelCase but first letter capitalized). So you should always rename them to snake_case for readability, and in some cases, system compatibility. Do use PascalCase when naming nodes and classes, and snake_case for properties and functions. That's how the engine does it and you want things to be consistent, again, so you don't get confused.

A quick sidebar while we're on the subject of naming; You should always rename every new node you create. Try really hard not to leave them with the default name. The reason for this is that node names are keywords in GDScript. So if you leave all your sprites named "Sprite", in your scripts "Sprite" and "$Sprite" mean two very different things. And what if you have more than one Sprite in a scene? You want to know which one is which. If you leave them as their defaults it won't break anything, but you're just asking to get confused.

As you start making more and more scenes, you're going to want to make some sub-folders. I like to put main.tscn at the top level of the scenes folder along with any scenes that are going to be autoloaded, or used by Main but don't have any children. Then for everything else, I roughly break things into 'levels', 'characters', 'menus', and possibly 'items' (I'm tempted to use 'objects' instead of 'items' but since an Object is an actual type in Godot it's not a great name for a folder). 'network' goes at this level if the game needs it. Of course what folders you use and how you name them depends on the type of game you're making, but that schema is pretty generic I think.

When making scenes, the ones that mostly stand alone go at the top level of their sub-folder, and any that contain sub-scenes or have inherited scenes get their own sub-folder. If a scene uses resources that are very situational that are saved as files and only ever used by that small group of scenes (themes and button groups for menus are a good example), they go in their own 'resources' sub-folder alongside the highest-level scene that uses them.

I usually also have a '_debug' folder in the 'scenes' folder, prefixed with underscore so it gets sorted to the top of the folder. This is where things like debug overlays or testing levels go. You can also exclude that folder in your export configuration as long as you don't change your mind and reference your debug code in your actual game :^)

For assets I group roughly into 'sprites' (or something like 'models' then 'meshes', 'textures', and 'materials' for 3D), 'audio', 'fonts', and 'json'. I also put my custom resource scripts here in a 'custom_types' folder. I do this for two reasons: First, because I want any additions I'm making to the engine to be in one place at a very high-level, and second because many of the custom resources I make will also get their own sub-folder in this assets folder. (Since assets are also loaded as resources it does make sense, to me anyway). I'm not totally sure I like that yet, but I think it's too late for me to change now :^) :^) :^)

Dividing your content into scenes, running scenes on their own, and why you should NEVER use get_parent()

Any group of nodes you want to have more than one instance of should be its own scene. For instance, the player should be its own scene, areas should have their own scene, enemies should have their own scene, and bullets should have their own scene. Dividing things up like this has implications for how you structure your file system, because you might need to reference the path to other scenes. So it's good to keep scenes that are instances of other scenes in sub-folders and group them in whatever way makes sense.

How To Structure Your Godot Project (so You Don't Get Confused) (9)

Sometimes this isn't possible, because some scenes need to be referred to all over the place. That's fine, just try to keep it to a minimum if possible. Even if only because it makes things less confusing.

You can run scenes on their own with the 'Play Scene' button at the top right of the editor. Try it and watch the remote tab. Godot will treat it as though the scene you have open is the main scene. Your autoloads will still be there, but none of your other nodes.
This is why you should try to avoid using get_parent(). If your nodes only know about their children that are guaranteed to exist at runtime, you can break any branch of the tree off into its own scene and run it to test things out without any problems.

If you use get_parent(), your logic will behave differently when running the scene on its own versus running your actual game. Sometimes that's okay, like if you want to add a child alongside the node that has the script attached, because what the parent is doesn't really matter. In that case you're just adding a child to it which is possible with any type of node so it'll behave the same way no matter where you're running it from. Even then I still try to avoid that whenever possible.

The lie of the change_scene() function, what it actually does, and how to think about scenes

Once you're running your game, your scenes aren't really scenes that are 'running' anymore. Scenes are definitions of a group of nodes that can be instanced. When you run a scene in the editor, Godot starts the scene tree with the root node of your scene as the main node. When the game is running, you aren't ever 'in a scene'. You're in the scene tree, and within the scene tree, your scenes are instantiated and now you have instances of the nodes they contain.

When you use change_scene(), Godot frees the main node and replaces it with the nodes in whatever scene you pass it. You can watch the 'remote' tab to see what's happening.

How To Structure Your Godot Project (so You Don't Get Confused) (10)

So if you want to 'change scenes', you can use change_scene(), but know that it is replacing everything you have loaded other than autoload singletons. No matter where in the tree you called it from. That's fine in simple games, but it doesn't scale well. The bigger your game gets, the more data you will need to pass between scenes, and storing and passing tons of data between scenes isn't something you want to be doing with AutoLoads (How to use AutoLoads effectivley for large projects is a whole other topic.) Personally I never use change_scene() because I always want the Main node around to pass data between things, and there's usually a player node I want around all the time.

I like to have a 'main_menu' and a 'game_world' scene, the first being a Control node and second being Node2D or Spatial for 3D. Then when you want to go from your main menu into the game, you can free the main menu node and make an instance of the game world.

export var game_scene : PackedScenevar game_world : Node2Dfunc start_game(): $MainMenu.queue_free() game_world = load(game_scene).instance() add_child(game_world)

Voila! You have 'changed scenes', from the main menu to the game world, but you still have your "Main" node. This has the added benefit of letting you do any other setup you want in between changing scenes, which wouldn't be possible if you had freed the entire scene tree. For instance, you can have a transition that fades to black and fades back in that exists in the main scene, and reuse that when you start the game and when you change levels in the game.

Once you're in the game, we can use this same construct to change "room" or "level" scenes or whatever you want to call them without losing our player node. Keep the player node as a child of the game world, and when you want to move to a new room, have the game world free the current room and instance the next one.

Inheritance, sharing and extending scripts, and editable children

There are a bunch of ways to have scenes and nodes share properties and behaviors, and they all have implications for how you organize your project. A very common one is the 'inherited scene'.

How To Structure Your Godot Project (so You Don't Get Confused) (11)

This creates a new scene with instances of all the parent scene's nodes, except all but the main one are greyed-out.

How To Structure Your Godot Project (so You Don't Get Confused) (12)
How To Structure Your Godot Project (so You Don't Get Confused) (13)

When you start it that way, it's exactly the same as its parent. You can add nodes, change properties on the children, and 'extend' the scripts they're using. The one thing you can't do is delete nodes that are children of the parent.

You can also have the scripts in your inherited scene add their own specific logic to the parents' scripts using the 'extend script' option in the right-click menu of the scene tab.

How To Structure Your Godot Project (so You Don't Get Confused) (14)

This creates a new script with 'extends "parent_script.gd" at the top, and it will have access to all the functions and variables of the parent.

How To Structure Your Godot Project (so You Don't Get Confused) (15)

You can add functions that will replace the functionality of the functions in the parent. To run the parent method in the extended script, you can call it like this:

func my_function(): .my_function()

So that the parent's function will run and then your new code will run after.

When extending these scripts, I like to keep them alongside the scene that is instancing the child, or in a sub-folder depending on how many there are.
Try to name them similarly to the script they're extending so it's more obvious what they're referencing and what they do.

Another thing that behaves very much like inherited scenes is 'editable children'. It is an option that is available when you instance a scene in another scene. This basically creates a one-time inherited scene that is local to the scene you are using it in, so you can make changes to that one instance.

How To Structure Your Godot Project (so You Don't Get Confused) (16)
How To Structure Your Godot Project (so You Don't Get Confused) (17)

The things you can do to an editable child are basically the same as how you can interact with the nodes of an inherited scene. You can add children, change anything on the node's children, and extend any of the scripts of the children, but you can't delete any of the instanced scene's children (the greyed-out ones).

Yet another way to re-use stuff from one scene to create another is 'Duplicate...".

How To Structure Your Godot Project (so You Don't Get Confused) (18)

This creates a new scene that is seperate from the scene you duplicated, but still has the same nodes as the old one. Any changes you make to the old one won't be applied to the duplicate. However, the duplicate Does not create new resources if they are referencing an external file. Any resources loaded into the original will also be referenced in the duplicate. This is a good thing! Image textures are resources. If you make a duplicate of a bullet you don't want it to copy your bullet png, you're going to already have the new texture you want and tell it which texture to use yourself. This includes scripts! Sometimes you want to keep the script attached, and sometimes you might want to make a new script. Also, stuff like shape resources applied to collision shapes might be shared if you saved any of them as a file. This does not apply to sub resources, (Resources that aren't saved as files) since sub resources are fully contained within the scene file.

How to get nodes, and why you should never use get_node("PathToNode")

There are a couple ways to reference child nodes in a script. Two very common ones are:

get_node("PathToNode")$PathToNode

There's a better way to use get_node() though:

var path_to_node := NodePath("PathToNode")get_node(path_to_node)

Although using "$" is usually still preferable when you know exactly which node you want.

Any text typed out in quotes is called a "String literal" in the programming world. The problem with using string literals is that they are imperfect. You can type in anything you want and the compiler/interpreter will accept it until it has to deal with with your messy typos and by then it's already too late. get_node("PathToNode") and $PathToNode operate basically the same way in the background, but the $ operator has the bonus of identifying the nodes that you are accessing directly via their name, which helps you not get confused. The use of "$" isn't a string literal, but it isn't checked by the compiler either, it just converts everything after it into a node path object and calls get_node() during runtime. In my oppinon, it enforces good programming practices. As an example, you can't pass a string literal you defined somewhere else to the $ operator. However, it's even better to avoid referencing nodes by their names at all! The name of a node isn't always something that is set in stone. If you duplicate a node, add the duplicate as a child of the parent and free the original, the duplicate will be named something else. You can even just change a node's name using get_node("PathToNode").name="NowIDontWorkAnymore". It's better to figure out the path to the node you need in some other way like using an exported NodePath variable, and then keep a reference to it like this:

export var path_to_character : NodePathvar character : KinematicBody2Dfunc _ready() -> null: character = get_node(path_to_character)

Since you might want to refer to different characters here, you have to and should use get_node.

Oh yeah and whatever you do, don't you EVER EVER EVER use get_node("/root"). I'm not gonna explain myself on this one, I feel like you should be able to figure it out by now.

You might be asking yourself, "How is any of this relevant? I only care about where to put my files". Hold your horses, I'm getting there! The reason all of that node naming stuff is important is that the way your scripts interact with their children has big implications for splitting branches of your scene off into their own scenes. And splitting branches off into their own scenes is very very helpful for keeping your project well organized.

How To Structure Your Godot Project (so You Don't Get Confused) (19)

How To Structure Your Godot Project (so You Don't Get Confused) (20)
How To Structure Your Godot Project (so You Don't Get Confused) (21)
How To Structure Your Godot Project (so You Don't Get Confused) (22)

Try to make sure your nodes only interact with their direct children, or at least very near children. If you can keep everything that way, you can always break any branch of the scene tree off into its own scene and have its logic fully contained in that scene. When a node's behavior depends on its parent, it will behave differently when you run it on its own and when it's instantiated in other places. In other words, making sure that your nodes only interact with their near children promotes modularity and encapsulation which is very important in any language that is even remotely object-oriented (which Godot is. Nobody's perfect.)

When you absolutely need to deal with distant children, use signals or groups.

So instead of

$Me/World/Level/House/Room/Guys/Enemy1.hp -= 100$Me/World/Level/House/Room/Guys/Enemy2.hp -= 100$Me/World/Level/House/Room/Guys/Enemy3.hp -= 100

Put the enemy nodes in a group, give them a take_damage(dmg:int) function, and use something like:

func explode() -> void: get_tree().call_group("enemies", "take_damage", 100)

or

signal exploded(damage)func _ready_() -> void: for enemy in get_tree().get_nodes_in_group("enemies"): connect("exploded", enemy, "take_damage")func explode() -> void: emit_signal("exploded", 100)

This way, it doesn't matter if the enemies exist or not or if there's even a house or room or level. It will just throw the signal to explode into the void and keep doing its thing.

Of course, the platonic ideal of a godot project would only ever interact with nodes by using get_children() or exporting node paths or putting things in groups, but at some point you're going to have to reference nodes by their names. There's really no way around it. When you do have to, just try to make sure it's a node that is guaranteed to be in the scene and won't ever be freed, moved, or duplicated.

So anyway...

I should say that other than the Godot style guide stuff and use of signals and groups, I don't think any of this could be called a 'standard'. It's what works for me, and informed by my experience as a software developer. A lot of my statments about what you "should" and "shouldn't" do are very debatable. Lots of people use change_scene() just fine. I'd be willing to hear arguments about keeping image and audio resources in the same folder as the scenes that use them instead of splitting them off. In any case, if something works for you, by all means keep doing it. But hopefully something I said can help dispel some confusion.

I put together a small template project that you can find on my github. This is based on a demo game that's a more fleshed out, showing some examples of the more complex structes I talked about, like changing levels while keeping the player node around. The link to that github is here, and you can play it on itch.io.

If you want to see a video on how to use the template, here is a simple example:

And finally, if you made it this far but also hate reading, consider checking out my youtube channel where I post devlogs and go in depth on some more intermediate Godot topics.

So what are you waiting for? Get to work!!!

Shantnu: We have planned more in Godot articles, sign up below to know when they are out.

How To Structure Your Godot Project (so You Don't Get Confused) (2024)

FAQs

How do I change my project path in Godot? ›

Unfortunately you have to set the default path manually at the moment. Open any project, in the menu bar click Editor → Editor Settings. In the settings navigate to FileSystem → Directories. There you will find a setting for the default project path for the project manager.

What are the 5 parts of a game? ›

Here are the five most critical components of outstanding Learning Games:
  • Goals and objectives:
  • Rules and/or Instructions:
  • Interaction:
  • Conflict (and/or competition, challenge, opposition)
  • Outcomes and Feedback.

What is a basic game structure? ›

Though there are many different types of video games, there are a few properties that are constants: Every game requires at least one player, every game gives the player at least one challenge, Every game uses a display, Every game has at least one method of input/control.

Can you sell games you make with Godot? ›

Godot Engine's license terms and copyright do not apply to the content you create with it; you are free to license your games how you see best fit, and will be their sole copyright owner(s).

Can you use both C# and GDScript in Godot? ›

Godot allows you to mix and match scripting languages to suit your needs. This means a single project can define nodes in both C# and GDScript.

How do you make a unique Godot? ›

There are a couple ways of making a Resource unique:
  1. Right click over it in the inspector and click on Make Unique.
  2. Enable Local to Scene in the Resource . ...
  3. Calling Resource.
Nov 10, 2023

Can you reverse engineer a Godot game? ›

GdTool is a standalone commannd line tool for reverse engineering games made with the Godot engine. It has both a compiler and a decompiler for all release GdScript versions (before GdScript 2.0, which is currently unreleased).

How do I set a project path? ›

  1. The 'Settings Path' Field is used to designate a new target path for a setting.
  2. When 'Activate Setting' is off it will show the currently applied setting path of your project.
  3. By entering a $BASE variable you can set a path relative to the path defined under 'Base Path'

How do you organize new game projects? ›

How can you organize game code for large projects?
  1. Modular design. Be the first to add your personal experience.
  2. Naming conventions. Be the first to add your personal experience.
  3. Code comments.
  4. Code formatting.
  5. Code refactoring.
  6. Code organization patterns.
  7. Here's what else to consider.
Sep 28, 2023

How do you set up a game project? ›

Creating and Managing a Computer Game Project
  1. Step 1: Make Initial Decisions. ...
  2. Step 2: Planning (story/style) ...
  3. Step 3: Detailed Planning. ...
  4. Step 4: Concept Time. ...
  5. Step 5: Model and Textures. ...
  6. Step 6: Assembly Time. ...
  7. Step 7: Level Making. ...
  8. Step 8: Distribute.

How do you structure a game idea? ›

You'd want to list what key features you want to have, how the game is played/controlled, what mechanism should be there, types of npc, gimmicks, what sprites you need, which ones will have sound effects, etc. Start off with key ideas then expand from there. Try not to over complicate yourself.

What are the phases of game project? ›

The 7 stages of game development (Planning, Pre-production, Production, Testing, Pre-Launch, Launch and Post-production) are essential regardless of studio size and they allow the production team to stay focused and structured throughout the development process.

Top Articles
France - - Taxation in France
France Corporate Tax Comparative Guide
Spasa Parish
Rentals for rent in Maastricht
159R Bus Schedule Pdf
Sallisaw Bin Store
Black Adam Showtimes Near Maya Cinemas Delano
Espn Transfer Portal Basketball
Pollen Levels Richmond
11 Best Sites Like The Chive For Funny Pictures and Memes
Things to do in Wichita Falls on weekends 12-15 September
Craigslist Pets Huntsville Alabama
Paulette Goddard | American Actress, Modern Times, Charlie Chaplin
Red Dead Redemption 2 Legendary Fish Locations Guide (“A Fisher of Fish”)
What's the Difference Between Halal and Haram Meat & Food?
R/Skinwalker
Rugged Gentleman Barber Shop Martinsburg Wv
Jennifer Lenzini Leaving Ktiv
Justified - Streams, Episodenguide und News zur Serie
Epay. Medstarhealth.org
Olde Kegg Bar & Grill Portage Menu
Kellifans.com
Banned in NYC: Airbnb One Year Later
Four-Legged Friday: Meet Tuscaloosa's Adoptable All-Stars Cub & Pickle
Model Center Jasmin
Ice Dodo Unblocked 76
Is Slatt Offensive
Labcorp Locations Near Me
Storm Prediction Center Convective Outlook
Experience the Convenience of Po Box 790010 St Louis Mo
Fungal Symbiote Terraria
modelo julia - PLAYBOARD
Poker News Views Gossip
Abby's Caribbean Cafe
Joanna Gaines Reveals Who Bought the 'Fixer Upper' Lake House and Her Favorite Features of the Milestone Project
Tri-State Dog Racing Results
Navy Qrs Supervisor Answers
Trade Chart Dave Richard
Lincoln Financial Field Section 110
Free Stuff Craigslist Roanoke Va
Wi Dept Of Regulation & Licensing
Pick N Pull Near Me [Locator Map + Guide + FAQ]
Crystal Westbrooks Nipple
Ice Hockey Dboard
Über 60 Prozent Rabatt auf E-Bikes: Aldi reduziert sämtliche Pedelecs stark im Preis - nur noch für kurze Zeit
Wie blocke ich einen Bot aus Boardman/USA - sellerforum.de
Infinity Pool Showtimes Near Maya Cinemas Bakersfield
Dermpathdiagnostics Com Pay Invoice
How To Use Price Chopper Points At Quiktrip
Maria Butina Bikini
Busted Newspaper Zapata Tx
Latest Posts
Article information

Author: Neely Ledner

Last Updated:

Views: 6093

Rating: 4.1 / 5 (42 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Neely Ledner

Birthday: 1998-06-09

Address: 443 Barrows Terrace, New Jodyberg, CO 57462-5329

Phone: +2433516856029

Job: Central Legal Facilitator

Hobby: Backpacking, Jogging, Magic, Driving, Macrame, Embroidery, Foraging

Introduction: My name is Neely Ledner, I am a bright, determined, beautiful, adventurous, adventurous, spotless, calm person who loves writing and wants to share my knowledge and understanding with you.