QTE Dev Log #2 - Core Loop
I’m making a recreation of the Excite QTE minigame from the Shenmue series of games. In the last blog post, I discussed my plan for finishing this game. In this one, I will focus on getting a working prototype of the game’s core loop.
I’ve created a simple design document for the game. While I could have managed this project without one, I wanted to complete this game in the same way I would want to complete a larger project. This isn’t a game jam, so I have the time to follow the process instead of rushing into things. That being said, I also don’t want to spend all my time on the design phase getting it perfect when I can work on a prototype. I’m treating the design as a working document with certain aspects of the game being more developed than others.
Core Loop

I didn’t need any graphics to start with. By printing to Godot’s console, I could create a loop of prompting the player with a specific input, then awaiting the player’s input to determine whether it was correct or not.
The biggest problem I needed to face was to do with handling joystick input. Joysticks emit values between -1 to 1 for each axis. It’s not as simple to detect whether an input has turned on or off, which is likely why the Shenmue series of games only supported the D-Pad. Godot helps alleviate this problem by allowing a programmer to bind a specific joystick movement to a given action. These actions are universal, so I can detect whether an input is pressed or released - regardless of whether it’s a joystick or a button press.
However, an input event is sent every time the joystick is moved - many times a second. If the input was bound to, say, a character’s movement, this wouldn’t be a problem. For QTE, however, we are requesting specific inputs from the player, penalizing them if they get them wrong. When the player moves their joystick, they may correctly get the current prompt correct, but then another input would be detected. The game would detect this as a response to the following prompt against the player’s intentions.
I came up with caching inputs as a solution to the problem. In Rust, I can store a HashSet<JoyAxis> of what joysticks are currently pressed, and in what direction. Whenever they are released, I remove them from the set. Only if a joystick is pressed and not currently in the set do I recognize the input as a response to the prompt. Now, duplicate inputs are no longer a problem!
Putting It Together

After getting a working version in the console, I created some graphics to turn it into a full gameplay loop. All of my graphics are SVG files, meaning I can adjust the size at any point without losing visual fidelity. The graphics are subject to change, but I do at least like how the input prompts turned out.
Overall, I’m happy with the fact I was able to get this aspect of the game done so quickly. However, there’s still quite a bit to go. The next steps involve implementing a scoring system which makes the game harder as you score more points.