Skip to content
DimensionWarped edited this page Nov 9, 2023 · 3 revisions

Levels in Godot are just scenes. And a scene is just a collection of objects. Sonic Worlds Next levels can be as simple or as complex as you want in terms of structure, so this article is mostly just to provide some helpful tips.

Making a new level

If you want to make things easy on yourself, duplicate the BaseZone and delete all the of the nodes below 'Player'. You now have an empty level with nothing but the necessary hud elements, your player start position, and a skeleton of a parallax background.

Setting your level's name

Select the 'HUD' object and give your stage a name by editing your script variables in the Inspector tab. 'Zone Name' is the phrase on Top, 'Zone' is the bottom word (usually 'Zone' going from the context of the main trilogy of Genesis Sonic games). You can set whatever you want for both of them of course. Lastly you can give your stage an 'Act' number by tweaking the 'Act' variable. You can even set it to 0 to just not have an act number.

Next Steps

From here, it's on you to decide what is going to go into your stage. It is recommended that you start with a tilemap similar to what you see in the 'Default' node of BaseZone.tscn -- the tilemap is generally going to form the majority of the terrain in most levels.

Making your level playable

In order to make your level playable, you need to first load into the scene. You can of course play the scene from Godot using the 'Play Scene' button or F6, but you probably want to be able to get there from either the level select tool or by completing another level.

Level Select Tool

Chances are, while you are starting out, you'll just want to use the UI functionality that Worlds includes out of the box. For the sake of this example, we'll assume your level is named "Overused Hill Zone Act 1" and it lives in 'Scene/Zones/OverHillZone.tscn'

In order to add your level to the character select tool...

  1. Open res://Scripts/Level/CharacterSelect.gd
  2. Navigate to the 'levelLabels' array variable. Add your level's name to the list. If you aren't simply appending it to the end of the array, make a mental note of what position in the list your level's name occupies.
var levelLabels = ["Base Zone Act 1", "Base Zone Act 2", "Chunk Zone Act 1", "Overused Hill Zone Act 1"]
  1. Navigate down to the 'match(levelID) statement. Add a new match value and have it set your Global.nextZone value just like the other items.
            match(levelID):
                0: # Base Zone Act 1
                    Global.nextZone = load("res://Scene/Zones/BaseZone.tscn") # unnecessary since it's arleady set
                1: # Base Zone Act 2
                    Global.nextZone = load("res://Scene/Zones/BaseZone.tscn") # Replace me! I don't exist yet!
                2: # Chunk Zone Act 1
                    Global.nextZone = load("res://Scene/Zones/ChunkZone.tscn")
                3: # Overused Hill Zone Act 1
                    Global.nextZone = load("res://Scene/Zones/OverHillZone.tscn")

Now if you load into the game normally, Overused Hill Zone will be selectable from the list and picking it will take you to your new level.

Setting it as the follow up to another level

For the sake of this example, let's assume you like BaseZone.tscn enough to want to keep it in the game as your first level. Simply open BaseZone.tscn, select your primary node 'TestScene' the Scene panel in the top left of the screen. 'TestScene' uses the 'Level.gd' script which conveniently sets up important aspects of your level for you, among them 'Next Zone'. With 'TestScene' selected, look to the inspector (right side of the screen), and you will see that 'Next Zone' is selectable. Click on the down arrow to the right of 'Next Zone' and select either 'load' or 'quick load' to be brought to a screen that will allow you to select the .tscn file associated with your level.

Now when you either reach a level-ending signpost that you dropped into the stage or pop the capsule following the BaseZone's boss, you will automatically transition to your new Overused Hill Zone.

Of course, you can use whatever conditions you want to load into your new zone and can totally ignore the built-in stuff that queues up levels if you want. After all, changing the scene is as simple as figuring out a condition and calling...

    Global.main.change_scene(myNextSceneVariable)

Though you may want to check that function in Main.gd to see what else you can put into it.

Music

You might have noticed this back in the previous step, but the root node of the level ('TestScene' in BaseZone) also lets you pick the level's main song.