A:\dventure Dev Log: Improving Scene Transitioning

ProgDozer
4 min readSep 27, 2018

--

One of the first things that any game developer will run into once their game’s complexity reaches a large enough size is Scene Management. Being able to logically compartmentalize aspects of your game into discrete scenes that are presented to the user in a stateful manner is pretty key to not just game development but application development as well. Godot does a great job at making it easy to change your root scene thanks to utility functions on its tree. However, even in Godot’s own docs it states that the default implementation has some drawbacks and you’ll want to make it fancier by doing background loading, add some progress bars, and do other things. In fact, right in the tutorial their first example of how to use Singletons is a how-to make your own scene manager.

So if all of this is basic information available in the tutorial, then why write about it? Well, from a graphical implementation, there’s some details that the tutorial doesn’t really touch on, plus there’s some neat things I did with my simple animation that I feel is a good starting place for others. So, I’m gonna show you how I did it in A:\dventure, some tricks I added, and even give you the code so you can drop it into your games!

First things first, since this scene manager is going to have some cool graphical effects, we need to make it so it can actually render on top of everything. Since the change_scene function on the SceneTree class will replace the last node in the root, that means any autoloaded elements will render before and under everything by default. To fix this, the scene manager I use is actually a CanvasLayer that renders at a higher level than all other elements on the screen. This makes it so the fader will always render on top, as will its children.

I initially took a brute force approach, using my scene manager to add and remove the transition node to the scene tree before unloading and after loading a scene. This singleton approach significantly less complicated and probably obvious to someone who knows their way around Godot better than I did at the time. Also notice that the Pause Mode is set to Process, which is due to our script using the standard SceneTree.paused property to freeze our game. This will allow the loading animations to animate while pausing everything else (assuming all your interactables respect the paused property as well).

Even though the scene manager I made doesn’t do async loading, I did add a simple flag that can be toggled if your new scene has plenty of processing to do at the beginning. Before transitioning to my dungeons, since they start off with some time consuming procedural generation, I pass a hold value to the new change_scene method. This informs the scene manager that it should not automatically fade back in when the new scene loads. After the dungeon is generated, I just need to tell the scene manager that things are ready and then it’ll perform the normal fade back procedure.

Our simple synchronous scene manager that does transition animations

In addition to the actual scene management aspect, the transitioning needs to be something nice to look at. Something like those classic PowerPoint transitions. RPG Maker had a nice way of doing this by using greyscale images that it’d roll through to fade the screen in and out. You could even provide your own images to make custom transition effects. I had a bunch laying around from my formative years, plus they’re still plentiful online if you know where to look. Any greyscale image will work; you could even use that black and white photo of some train tracks you took when you were going through your “photography phase.”

To get that feature working, I added a small shader material onto the “Fader” image node. It’s not that complex, really, and uses the image node’s own resource. This makes it easy to change from GDScript and as well as preview the fader directly in the editor immediately.

The AnimationPlayer in the scene manager will actually perform the tweening of the shader’s “transition” value, which will either render black or transparent depending on the pixel’s value relative to the transition position. This allows for a smooth effect for transitioning, at the cost there being a hard edge which might or might not be noticeable depending on the filtering of your image. The AnimationPlayer is triggered automatically when using the change_scene function, as well as when its is_ready state is changed after loading the next scene. In this simple implementation, it’ll fade out with the image, then play the same animation in reverse to fade back in. In the end, you’ll get a result like what we just saw when testing out the shader. However, what’s really neat is seeing it in action in a game.

The scene manager made here doesn’t do anything fancy like asynchronous loading, but it does add some pizzazz to your visuals. If you’re like me and are using Godot after having used RPG Maker, this should help fill one of the small but memorable gaps in the feature set that you might have been missing. In my opinion, this effect is a leaps and bounds improvement in my game’s presentation compared to what I had before, and it retains the retro aesthetic I’m going for. It’s really great for low-res games.

You can download the complete .tscn file, which has script and shader embedded, and add it to your Autoloads to immediately start using it. Be sure to change any of your get_tree().change_scene references to go through the SceneManager Singleton instead

--

--

ProgDozer

Disgruntled and opinionated writing about programming and the state of software. @nhydock