Pop Goes the Jester
Game Description
A collection of rhythm mini games themed around a jester trying to keep the king happy! Developed during the 2024 Global Game Jam
What I Worked On...
For this project I composed original music, did the sound design, implemented all sounds using Wwise, and programmed them into Godot using GDScript. Additional consulting on the rhythm game programming.
Music Composition
Main Menu Music
The main menu theme featuring harpsicord, lute, and recorders invoking feelings of the before times.
Lute Hero
A short theme for recorder and classical guitar melody with drum and viola da gamba accompaniment.
Go for the Juggler
A jig with an out of character tuba for comedic effect.
Music Systems
Lute Hero and Juggler System
For the rhythm games, we wanted the player to have direct control over the soundtrack. In Wwise, I separated the composition into individual stems. On the melody stems, I had a state mute and unmute the tracks. On a separate, random container, I placed about a dozen "mistakes" that I made from whatever instrument was being muted.
In the Lute Hero mini-game, randomized sprites were generated and placed into a long line. The whole group would then travel down the neck of the lute and when they passed over the bridge, the player would have to try and press the right key at the right time. If they failed to press any key, an AkState node was triggered and would mute the melody. If they pressed the wrong key at any time, the mistake container would trigger. If the pressed the right key at the right time, the melody would unmute.
#in lute note detection script func handle_press(action): if not is_active: return if active_pips.has(action): InputManager.good_note.emit() else: InputManager.bad_note.emit() func _on_area_exited(area): if not area is pip: return if not area.has_been_hit: InputManager.missed_note.emit() active_pips.erase(area.action_name) #in wwise siganl script func _ready(): InputManager.good_note.connect(good) InputManager.missed_note.connect(miss) func good(): $AkMelodyOn.set_state() func miss(): $AkMelodyOff.set_state()
For the Juggler mini-game, I put the mute/unmute state on the tuba part and wrong keys would trigger tuba mistakes instead of lute. Since the same function was called for both the juggler and lute hero mistakes, I placed the mistakes in a switch container and set the appropriate state at the start of the individual levels.
Since the mistakes could be played at anytime, that means they could be played out of rhythm, adding to the chaotic nature of messing up.
In and Out

The two games had slightly different triggers for the main music. Both pieces have a short intro played with the title/instruction pop-up with coroutines set to the same length of the music. For the Lute Hero mini-game, we placed the AkEvent call on the animation so it synced precisely with the rhythm objects.
However, in the Juggler where the timing was less important, we called it in the script.
#Wwise Script func _ready(): InputManager.juggle_intro.connect(juggle_intro) InputManager.juggle_music.connect(juggle_music) func juggle_intro(): $AkJuggleIntro.post_event() func juggle_music(): $AkMelodyOn.set_state() $AkState_JuggleLevel.set_state() $AkJuggleMusic.post_event() #in juggle scene func start(): InputManager.juggle_intro.emit() await get_tree().create_timer(2.0).timeout await get_tree().create_timer(3.0).timeout InputManager.juggle_music.emit()
At the end of the game, the points manager would decide of the titular character kept his head or not, and two different ending stingers would play appropriately.
Sound Design Systems
Wwise and Godot

For this project, we used the Wwise and Godot integration from Alessandro Famà . All audio assets were implemented into Wwise, and the events and states were triggered using the provided Ak nodes and GDscript.
Since the game was all in one scene and we had a limited number of event calls, we put all of the Ak objects into one parent node (including the listener and the bank loader) and posted them in functions connected to signals that controlled all the triggers for the game.
func _ready(): InputManager.bad_note.connect(flub) func flub(): ak_lute_flub.post_event()
Juggling SFX
For the Juggling mini-game, I also provided sound effects for the throwing and catching sound. Both were random containers with several variations of the desired sound, and the catch sound was dependent on the success of the player pressing the right key at the right time.
