I’m building a 2d platformer in Godot, and it’s my first time with the engine.

I’ve followed the First 2D Game tutorial as well as a few others (Brackey’s videos and some others) and have a decent grasp on building out a level as well as decent physics for how I want my player character to control.

So far, everything was made underneath one main Scene called “Game” and I’m at the step where I want to start having a Main Menu, a Level Select Menu, and logic on starting/completing a level rather than just one big “Game” Scene with a bunch of stuff I slapped together to test out the platforming.

I’d love some input on how I should be structuring my project and changing scenes around. I’ve found examples in tutorials but they all differ on some details and I’m not sure what is best. I’ve built a simple Main Menu and Level Select Menu and am able to go in and start the “Game” scene from it.

This is a big ask, I admit :).


  1. I’ve created a new main Scene titled “Main”. It’s jsut a plain Node with this script so far:
class_name Main extends Node


var main_menu_scene: PackedScene = preload("res://scenes/main_menu.tscn")

func _ready() -> void:
	add_child(main_menu_scene.instantiate())

func exit() -> void:
	get_tree().quit()

I’ve done this partly to follow an example that I found, but also due to how I want the background to work. In some Valve games, the Main Menu background is based upon the level you’re at in the campaign. I want that. If you start the game up the first time, I want the background to be the 1st level background. If you’re on world 10, I want it to remember and show that background. When the level launches, the background can stay the same as it was on the Main Menu.

I don’t have backgrounds started in at all, yet.

  1. My Main Menu scene is a PanelContainer. Above, Main loads the MainMenu scene and adds it as a child. This works but I don’t know if it’s the best way. Script:
class_name MainMenu extends PanelContainer

@onready var main_scene: Main = get_parent()
var level_select_menu_scene: PackedScene = load("res://scenes/level_select_menu.tscn")
var options_menu_scene: PackedScene = load("res://scenes/options_menu.tscn")

func _on_play_button_pressed() -> void:
	main_scene.remove_child(self)
	main_scene.add_child(level_select_menu_scene.instantiate())

func _on_options_button_pressed() -> void:
	main_scene.remove_child(self)
	main_scene.add_child(options_menu_scene.instantiate())

func _on_exit_button_pressed() -> void:
	main_scene.exit()

This lets you exit (works by calling the Main scene function) go to Options, and go to the Level Select scene as well.

  1. Next is the Level Select Menu. It’s similar to the MainMenu. Script:
class_name LevelSelectMenu extends PanelContainer


@onready var main_scene: Main = get_parent()
var main_menu_scene: PackedScene = load("res://scenes/main_menu.tscn")

func _on_back_button_pressed() -> void:
	main_scene.remove_child(self)
	main_scene.add_child(main_menu_scene.instantiate())

func _on_level_1_button_pressed() -> void:
	main_scene.remove_child(self)
	main_scene.add_child(load("res://scenes/game.tscn").instantiate())

func _on_level_2_button_pressed() -> void:
	# main_scene.remove_child(self)
	pass

Here you can go back (works) to the MainMenu, or move forward and start the “Game” scene I mentioned above. I intend to build a few levels and stick them in here in a similar fashion, replacing game.tscn. That will get me to the pre-pre-pre-alpha stage of my game and I hope to get feedback on how the platforming “feels” from there.

My thought is that the Main scene would handle the backgrounds, and always be the main parent Node in the Scene Tree. The Menus and Levels get swapped out as the child node of Main.


Questions:

Does this look ok to any of you Godot veterans?

Any code smells?

All of my scenes are in a /scenes directory. All of my scripts are in a /scripts directory. No sub-directories in either. This is quickly getting messy and I’d also love tips on folder structure.

  • spacemanspiffyOP
    link
    fedilink
    English
    arrow-up
    5
    ·
    11 days ago

    This is immensely helpful, thank you!

    I do indeed want a pause screen with similar behavior so that tidbit is perfect.