Gamedev Grievances #15: Cutscenes and the Mannequin Challenge

Cutscenes are, without a doubt, one of the most time-consuming tasks involved in piecing Ambience together. It’s one thing to have a great idea of how a scene’s going to look, but actually putting it into practice takes a whole lot more time. Not that the task is difficult; usually it’s just a little tedious. But as with anything, occasionally strange things start to happen which really put the brakes on development.

Scene 1: The Approach

Different games and different gamedevs inevitably utilize different approaches to cutscenes, but the approach I’m using involves assets which GameMaker: Studio calls “timelines”. Essentially, a timeline is a long shopping list of events and when to perform them. When a timeline runs, the events are performed at the times (or more correctly, frames or “steps”) that you specify. In other words, “At step X, do events Y and Z”.

The beating heart of a typical cutscene.

Naturally, I did a fair bit of tinkering with this basic system to get it to work for my purposes. One such creation that resulted from this was a system that allows a step to be repeated over and over until a certain criterion is fulfilled, such as when an NPC has moved to a particular place – essentially allowing timelines to function like “while” loops.

But, of course, there was a problem.

Scene 2: The Problem

While constructing a new cutscene, I like to test it every now and again to make sure everything’s working fine. At the end of running through what I’ve done, normally the camera automatically moves back to the player character and gives back the player’s control.

Except this time… when the camera returned to the player, the game continued to run but the player remained immobile. Essentially, the game had inconveniently decided to stop being Ambience and start acting like a mannequin challenge simulator.

Note how the HUD doesn’t reappear after the camera returns to the player; instead, everything stays frozen. (There’s also some debug text from the cutscene controller and camera.)

Scene 3: Suspects

When I had been constructing the timeline, GM:S bugged mildly and threw an exception my way. That often happens if you do something really unexpected, such as defining a moment in a timeline to be completed at a step with a negative number. This time, however, I couldn’t work out what was causing this exception, although I suspected it was the reason for the game bugging at the end of the cutscene.

I reloaded GM:S, copied and pasted all the moments over into a fresh timeline (twice!), recompiled – and no luck. The player still remained immobile after the cutscene had ended.

However, something else soon became apparent. When I omitted Sage’s placeholder dialogue by commenting out the code in the relevant timeline moment, the problem magically disappeared.

Control regained!

The bug was caused by the game remaining in a “paused” state, even after the timeline had finished and the camera had returned to the player’s coordinates. Consequently, I added some debug output to the pause script to figure out exactly what was causing the paused state. The textbox was one of the things which could be responsible for this paused state, and this seemed likely given that removing the textbox solved the problem.

“Exit” Stage Right

So, was the textbox responsible? As it turned out, not quite. It was actually Sage’s invisible mugshot, created by the very last textbox, that kept the paused state going.

This output shows that while there weren’t any textboxes (0’s), there was a mugshot present (1) causing the paused state.

That invisible mugshot was due to the fact that the mugshot wasn’t flying off the screen properly once the corresponding textbox had finished. And that in turn was due to… a single, out-of-place “exit” statement in the mugshot creation script.


The offending “exit” that caused the whole debacle.

The reason why I had put the “exit” into that script in the first place was so that the rest of the script wouldn’t run if the mugshot had no sprite, thus saving a little computational time. But in the end, it just wasn’t worth it. And so, after two long and painful hours of debugging, I removed the “exit” statement – and everything finally worked according to plan.

(On the bright side, however, I finally completed the underlying infrastructure for that cutscene! And I also implemented the ability to travel between different towns or “camps” on your journey, which is something I’ve been hoping to do for a while.)

Leave a Reply