Cutscene Refactor: The Other Pieces


Moving On

Yesterday's post title was maybe a little misleading. Technically, I finished the refactor of the cutscene player itself, but there is still more work to be done in relation to this refactor. Today's task is to move the cutscene player instantiation and management from my game manager into my UI manager. Hopefully, it won't be too hard since I can start by copying the way some of my other systems are handled by the UI manager.

Today is also going to be a weird one. I'm starting my work on the game really early. But I'm also going to be interrupted constantly today. I have 7 separate meetings at work today. I'll be doing my best to get as much done between meetings as I can. The interruptions will definitely be a source of trouble and may even prevent me from doing what I want.

The first step was adding a variable to my UI manager to hold a reference to my cutscene player's scene. That was probably the easiest part. Next up, I added a couple of new placeholder functions to show and hide the cutscene player. Well, that was the plan, but instead I just copied the dialogue system functions and modified them to do what I wanted.

In that process though, I'm seeing some things that don't quite look right to me. So, I took my UI manager and fed the script into a fresh new Gemini chat to have it looked over. It actually found a couple of things I hadn't noticed. I'm not sure at this point if I want to actually change this though. At the moment my UI manager is hiding some UI elements and completely freeing others. I decided that I first wanted to finish what I started with the cutscene player. 

So I raised an issue about the UI manager freeing some scenes and I'll come back later to make the necessary corrections. During this process I actually identified two other issues to raise! I have a couple of "all overlay" functions that are not affecting all my overlays. There's also a weird bit where I have a signal connection from managed UI pieces on close that change the game manager's state, which may or may not be an issue so I have to investigate that further at a later time. But, as it turns out, I already had an issue raised about those "closed" signals.

The next part is the really hard part, moving the cutscene management out of the game manager. I think I have everything I need at this point in my UI manager to handle all the actual cutscene player but there's so much that happens with cutscenes in my game manager. I think this is going to be another instance where I need to look over and document the way things are currently done so I can see what exactly needs to change.

How It's Currently Done

Let's start at the beginning. My city scene calls start_cutscene on my game manager with the path to the individual cutscene (prologue) as a parameter when it is a new game. From there, the game manager verifies there isn't already a cutscene playing, and if not, it sets the game state to cutscene, then loads and instantiates the cutscene player as a child of the root node. There's some checks in there to make sure everything is happening the way it should. Once the scene is instantiated it calls the start_cutscene function on the cutscene player. 

The cutscene player itself then takes over and in the end it signals cutscene_finished, which triggers the _on_cutscene_player_finished function in my game manager. That function then frees the cutscene, returns the game manager to the previous state, and emits its own cutscene_finished signal, which triggers _on_cutscene_player_finished in my city scene that then sets the player free. 

How It Should Be Done

I think I should still be starting my cutscenes from the game manager, but obviously it shouldn't be working so hard. So, I want to call start_cutscene with a parameter of the cutscene ID to use. The game manager will then set the cutscene_to_load variable then change the game state to cutscene (similar to how I'm handing dialogue). 

Then the UI manager will detect the change of state to cutscene and call its internal function _show_cutscene_player which will instantiate or show the cutscene player. I think I'll need the UI manager to also connect to the cutscene finished signal, it's already connecting to "closed". This means I need to relay that signal through my UI manager (which doesn't have any signals yet). Once the cutscene player is visible I will then need to trigger start_cutscene on the cutscene player.

At that point, the cutscene player takes over and does its thing. Once the cutscene is finished it will signal and the UI manager should then take over again. That signal triggers my cutscene finished, which calls the function to hide the cutscene player, tells the game manager to return to the previous state, and emits another finished signal for my city scene to listen for and do it's thing.

Building It Out

I think I've figured out the proper logic for this. I hope I have! Looking at the logic I came up with, I'm running into a small issue getting the order of operations just right for closing the cutscene player. I was planning changing the state and hiding my cutscene player when the UI manager receives the signal that the cutscene is finished. But, the state detection in my UI manager is setup to hide the cutscene player when the state is no longer active, which is duplicated effort. 

So, instead, I've setup my UI manager to relay the signal and change the state, thus allowing the state itself to control showing/hiding the cutscene player. I decided to keep my previous code in place but commented out and completely rewrote the game manager's cutscene functionality.

At first, things weren't working right, my cutscene player was loading, but none of the cutscene was playing. Turns out I totally skipped a setup and forgot to call start_cutscene on my cutscene player. Once that was fixed, I ran into another issue where the game state wasn't set correctly. After a bit of head scratching I decided to ask for some help. I fed my three scripts (UI manager, game manager, and the cutscene player) into Gemini and had it take a look.

The source of the issue was identified, but Gemini got the fix all wrong. In my city scene, after the cutscene ended, I was setting the state of the game correctly. But as part of the UI manager, I was also telling the game manager to return to its previous state. That second bit was the problem, after a cutscene the state needs to be forced to the correct state (at least in this case) because the game was never in the correct state to return to!

What's Next?

That is a loaded question . . . There is still so much to be done. Right now I have 12 open issues to address. But there's still so much more that I need to accomplish. What's important? That's what I should focus on. I still need to add an inventory screen and a quest log. Those are two very big pieces that I'm missing.

I have begun the localization work, but right now there is only English, and there's no way for a player to even set their preferred language. There's still a lot of gameplay stuff I haven't even started on, such as the farm, factory, shipyard, space, etc. Heck, I still haven't even designed the city. I've also got to get to work documenting my game lore and related stuff. But, that will all come in time. I think the real, big, most important thing to work on next is going to be player death. 

Player death was an idea I originally didn't include. The idea was that the game would be super-cozy with little or no negative consequences. I made a slight design change, and instead want to include player death and make it a larger piece of the game. The game will start with a very roguelite gameplay loop that transitions over time (by way of player progress) into a more cozy experience.

Leave a comment

Log in with itch.io to leave a comment.