Jitter
Ever wished you could you play along with your favourite streamer? Jitter fulfilled this wish in two ways:
1. Jump into the game as a member of the gourd horde.
2. Interact with the Twitch extension to affect the game.
Jitter was built using Morpheus, an extension to UE5 which enables thousands of concurrent players in the same server.
Leading the technical team, my responsibilities on Jitter were:
- Integrate Twitch interactions into the gameplay experience
- Develop gameplay features
- Build control panels for live game-balancing
- Extensive scale and performance testing
Overview
Studio
Improbable / Imporium
Role
Senior Technical Designer
Platform
PC & Mobile
Date
2024 - 2025
Key Skills
Gameplay Systems
Web Integration
Optimisation
Technical Leadership
Massively Multiplayer
Twitch Integration
The goal was to bring the streamer and their audience closer together than ever before.
Early tests used a Twitch chat listener which responded to specific emojis or text. With our web team, I expanded upon this to include voting via Twitch polls and interactions from the Twitch extension.
I made polls for chat to vote on the next power.
When a game round was being played, I set up a system to regularly request a Twitch poll to let chat decide what power the Defender would next use.
This was handled in Blueprints by making a HTTP request to an endpoint set-up by the web team. From Unreal, I could:
- Start a poll.
- Set the poll format, including header and voting options.
- Poll for the result, and apply it to in-game systems.
- Respond if the poll was cancelled by the streamer.
Chat tactically utilised this voting, helping their streamer out of some tough situations, or leaving them stranded in others.
I integrated the Twitch extension so chat had in-game impact.
Chat could slow down the horde's advancement by interacting with obstacles on the extension, to slow the progression of in-game obstacles. They could also blow-up a random barrel of TNT in the level, sending any nearby players flying off.
I worked closely with the external partner who built the extension to handle the game-side connection to the WebSocket through JSON messages sent via Blueprints, including:
- Connecting securely via a generated auth token.
- Resetting the extension state on a new game round.
- Relaying in-game obstacle state (unused, used, completed).
- Applying debuffs to the appropriate obstacles.
- Choosing and exploding a barrel of TNT.
- Live monitoring of connection state.
- Auto and manual reconnection.
- Capturing analytics.
The extension was so popular with the chat, they overloaded and crashed the WebSocket on the first test!
Gameplay Features
I gave the Defender powers to keep themselves safe.
I implemented several powers, each with a different gameplay impact:
Gust knocked players back.
GlitterBOOM sent players flying radially from the impact.
Glue trapped players in place until they jumped free.
Landmines inverted the player's controls.
Bolt of Shrinking made the players small.
Bubbles were completely useless.
And let those powers be adjusted live.
I built a control panel which allowed the Streamer to adjust the size, speed, power, and duration of each individual power.
My favourite streaming moment was DougDoug's reaction when he first increased the size of the GlitterBOOM.
I set up manual and automatic rounds,
I detected whether or not the Streamer was connected to the game, and set the game flow accordingly.
When they weren't connected, the system auto-ran via the default rules; selecting a random person to be the Defender, increasing the round by 30 seconds for every time the Defender successfully avoided capture, and then selecting the person who eventually caught them to be the next Defender.
When the Streamer was connected, they had access to the Game Flow Controls panel, allowing them to run the rounds.
I also extended the system for if the Defender left mid-round, a new Defender would be chosen and teleported to their last position, reducing trolling and disruption through quitting.
Taught players how to play,
To teach players controls and game rules, I placed a series of helper gourds around the level. They:
- Showed one message at a time, based on camera direction.
- Used the relevant icons for the detected input device (mouse, gamepad, mobile).
- Played animations to emphasise their taught actions.
- Could differentiate between the Horde and the Defender, and display different messages to each.
And kept players safe with moderation.
Similarly to the Twitch extension, I integrated GGWP (moderation software) via their WebSocket connection, allowing for real-time moderation of the in-game chat.
Scale Testing
I learnt very quickly the importance of scale testing,
Every gourd in that gif is a player. There's over 2000 of them.
To work at scale, there's a lot to Morpheus networking:
- Cleaning up state of pooled render targets (the closest 35~ characters displayed in full fidelity).
- Making state client authoritative where-ever possible.
- Minimising server load by running calculations on the client.
- Accounting for late joiners.
- Not having every client make a server call at the same time.
The day before our first event we ran a scale test for the first time, and caught that last one. It was 10 hours of stress, figuring out why, fixing it, testing it, repackaging and pak-embedding a new build, and hoping we'd hadn't missed anything.
The event was very successful, but I said "never again".
And embedded scale testing into our process.
After that event, I worked with our producer to build scale tests into our sprints. For general dev sprints, we'd scale test during our polish week. On the run-up to events, we'd scale test when we hit content completion, polish completion, and release candidate.
With this new format we caught and resolved issues early on. It also provided a learning opportunity for the tech team to come together and discuss the causes and solves, to avoid similar problems in the future.
This paid off, as in my last scale test we had 17,000 bots running around the level. There's something quite magical in there being vegetables as far as the eye can see.