Inspiration
JETBREAK started with a simple question: What if a Jetpack Joyride-style game actually let you fight back?
We liked the immediate accessibility of endless runner games, but wanted the player to have much more control. Instead of only moving up and down and avoiding everything on screen, we wanted the player to fly with one thumb and aim and shoot in 360 degrees with the other. That became the foundation of JETBREAK. But the game changed a lot after people actually started playing it. Throughout development, we gave builds to friends, family and paid testers and watched them play. We asked where they got confused, what felt frustrating, what they enjoyed and what made them want to play another run. A surprising amount of the final game came directly from those sessions. We slowed down the early enemy pacing, added clearer attack telegraphs, changed how rewards were presented, adjusted the difficulty curve and fixed several UI and gameplay problems because testers showed us where the game wasn't working. So while the original idea came from wanting to build a different kind of endless runner, the game we are submitting is really the result of repeatedly putting the game in front of people and listening to what happened. There is also a personal reason we became so focused on correctness in the architecture. My professional background is in mainframe and enterprise systems, where transaction integrity, traceability, duplicate processing and failure handling matter. I brought that mindset into JETBREAK. A mobile arcade game does not need enterprise architecture just for the sake of saying it has enterprise architecture. But once the game started handling purchases, subscriptions, rewarded advertising, virtual currency and cloud progression, the same principles started to matter. We wanted the game to be fun on the surface, but also trustworthy underneath.
What it does
JETBREAK is a 2D endless jetpack survival shooter built around simultaneous movement and combat. The left side of the screen controls the jetpack. The right side controls a 360-degree plasma weapon. That creates a different gameplay rhythm from a conventional endless runner. You are constantly deciding whether to:
- dodge an incoming attack
- turn and destroy it
- collect a reward
- take a risky near-miss
- maintain your combo
- or concentrate on surviving The game currently has five environments, procedural encounter patterns, enemy drones, ground bots, turrets, missiles and laser barriers. There are also shield, magnet, rapid-fire and slow-motion power-ups, a combo system, missions, Workshop upgrades, cosmetic skins, leaderboards and cloud progression. One mechanic we became particularly attached to during testing was the near-miss system. A player can deliberately fly close to hazards instead of simply avoiding them. Successful near-misses build the combo multiplier, creating a risk/reward decision that becomes increasingly important as the run gets harder. JETBREAK also includes an integrated monetization system using RevenueCat and AdMob, including in-app purchases, a PRO subscription and rewarded advertising. The important part is that monetization was not treated as something bolted onto the game at the end. It became part of the architecture.
How we built it
JETBREAK is built using TypeScript, React, Canvas 2D and Capacitor for Android. We deliberately built the gameplay layer ourselves rather than using a traditional game engine. The project has separate systems for the game loop, player controller, collision management, projectile pooling, enemy encounters, enemy firing, power-ups, progression, environments, audio, economy and UI. That separation became especially important once we started adding monetization.
RevenueCat
We integrated RevenueCat as part of the actual game architecture, rather than simply adding a purchase button to the shop. JETBREAK supports:
- one-time crystal purchases
- a starter pack
- a PRO subscription
- RevenueCat entitlements
- rewarded-ad rewards
- server-verified reward redemption
- virtual currencies for monetized rewards RevenueCat is connected to the player's identity, with the Firebase UID used to maintain a consistent identity between authentication, cloud data and RevenueCat. This was particularly important because the game has multiple types of economy state. A player can earn rewards through gameplay, purchase currency, receive monetized rewards and have subscription-based entitlements. We did not want those systems becoming independent sources of truth.
AdMob + RevenueCat rewarded advertising
The rewarded advertising system is one of the parts of JETBREAK we are most proud of. We deliberately avoided building the monetization around constantly interrupting gameplay with forced ads. Instead, rewarded ads are used when the player has a meaningful choice. For example, after losing a run, the player can voluntarily watch a rewarded ad to receive a Revive. There is also a Double Rewards flow where the player can voluntarily watch a rewarded ad to ultiply the rewards from a completed run. But the important part is what happens after the player watches the ad. We did not want the client to simply say:
"The player watched an ad, give them a reward." The flow is:
AdMob Rewarded Ad ↓ RevenueCat Server-Side Verification ↓ RevenueCat Virtual Currency Transaction ↓ Firebase Reward Verification ↓ Server-Side Redemption ↓ Firestore Redemption Ledger ↓ Game Reward This means the client does not decide whether an ad reward is valid.
RevenueCat handles the server-side reward verification and virtual currency transaction, while Firebase provides the backend layer used to securely consume the verified reward.
We also implemented idempotent reward consumption, so the same verified reward cannot accidentally be consumed twice.
For us, this was more important than simply making the rewarded ad button work.
Economy architecture
The economy was designed as a proper system rather than scattering coin and crystal changes throughout the game.
The game tracks rewards earned during runs, purchased currency and monetized rewards separately, while server-side validation protects the reward flows.
We specifically tested:
- normal run rewards
- rewarded revives
- double-reward flows
- purchases
- cloud synchronization
- duplicate reward attempts
- failed transactions
The goal was simple:
A player should not be able to break the economy because of a duplicated request, a client-side mistake or an unexpected network condition.
That principle comes directly from the way I have approached enterprise systems professionally.
In an enterprise environment, "it probably only happened once" is not a sufficient answer.
The same mindset made us ask the same questions in JETBREAK:
Was the transaction actually processed? Can it be processed twice? Can the client lie about what happened? Can we trace what happened afterwards?
Firebase
Firebase handles authentication and cloud persistence.
Players can start as guests and connect their account using Google Sign-In. Persistent progression and player records can then be synchronized through the cloud.
Firebase also provides the server-side layer for our reward flow.
The client does not directly control the final reward redemption. Instead, a Cloud Function handles the verified reward consumption, checks the player's reward balance and records the redemption.
We also keep a server-side redemption record in Firestore.
This gives us an audit trail and protects against duplicate consumption.
We deliberately keep temporary gameplay state separate from permanent player state.
A power-up belongs to a run.
A Workshop upgrade belongs to the player's account.
A RevenueCat entitlement belongs to monetization.
A rewarded virtual currency balance belongs to the monetized reward system.
Keeping these boundaries separate made the project much easier to maintain as the game grew.
Challenges we ran into
The hardest part wasn't getting a character to fly across a screen.
It was turning that prototype into something designed for real users, real purchases and real Android distribution.
Making the game fun
Our early versions were too difficult.
Testers were dying before they had enough time to understand the controls. Some enemy attacks felt unfair because there wasn't enough warning. Other parts of the game were technically working but simply weren't interesting.
We repeatedly went back to the game after watching people play it.
A lot of the difficulty curve was shaped by those sessions.
We learned that something being obvious to the developer who built it doesn't mean it is obvious to somebody playing it for the first time.
Monetization and reward security
Getting a purchase button to work is one thing.
Making sure purchases, subscriptions, rewarded ads, virtual currency and the game's own economy all agree with each other is another.
We had to deal with RevenueCat identity, Firebase identity, server-side ad verification, duplicate reward protection, cloud saves and transaction state.
The hardest part was not implementing any one of those systems individually.
It was making sure they agreed with each other.
For example, a rewarded ad should not become an unlimited source of client-controlled currency. A verified reward should not be redeemable twice. A subscription entitlement should not depend on a local flag. A cloud save should not accidentally overwrite important permanent progression with temporary run state.
Those are the kinds of problems I am used to thinking about from my mainframe and enterprise background, and they influenced how we designed JETBREAK.
Production Android testing
We also had to deal with the less glamorous parts of shipping a real mobile game:
safe areas, touch handling, different screen sizes, Android signing, Play App Signing, production Firebase configuration, AdMob production IDs, RevenueCat production configuration and release builds.
At one point, Google Sign-In worked in development but failed in the Play-installed version because the production signing certificate was different.
We had to trace the actual Play-installed application, identify its signing certificate and configure Firebase accordingly.
That was a good reminder that the build we test locally and the application Google Play ultimately delivers can involve different signing identities.
It was exactly the kind of production issue that can be easy to overlook when everything works on a development device.
Accomplishments that we're proud of
The biggest thing we are proud of is that JETBREAK grew from a hackathon prototype into a release-ready mobile game.
It has a complete gameplay loop, progression, multiple environments, cloud saves, authentication, missions, leaderboard functionality, monetization and rewarded advertising.
But the part we are particularly proud of is the architecture behind the monetization.
RevenueCat is not just a payment screen in JETBREAK.
It is connected to the game's identity and economy, handles our purchase and subscription layer, participates in our rewarded-ad virtual currency flow and provides server-side verification for monetized rewards.
Firebase provides the authentication, cloud persistence and server-side layer needed to validate and consume rewards safely.
AdMob provides the actual rewarded advertising experience.
The three systems work together rather than existing as isolated integrations.
The architecture can be summarized as:
Gameplay ↓ Progression ↓ Economy ↓ Authentication ↓ Firebase Cloud Data ↓ RevenueCat Monetization ↓ AdMob Rewarded Advertising ↓ Server-Side Reward Verification ↓ Firestore Redemption Ledger That separation made it possible to test individual systems without making the entire game dependent on a single tightly coupled implementation.
We are also proud of the amount of testing that went into the release build.
We built automated coverage around the major monetization, reward, cloud-save and account-linking systems, alongside visual and asset integrity checks.
And then there is the less technical accomplishment:
people actually played it and influenced what it became.
The final game contains many decisions that came from somebody saying:
"This part is confusing."
"This is too difficult."
"I didn't understand what that did."
"Why did I die there?"
Or simply:
"I want to play again."
That feedback loop is probably the most valuable part of the project.
What we learned
We learned that building a game and designing a game are two very different things.
As developers, it is easy to focus on whether a system works correctly.
A player doesn't care about that.
They care whether they understand what to do, whether the game feels fair and whether they want to play another round.
Our testers taught us this repeatedly.
We learned to watch what people actually do instead of relying only on what they tell us.
If several people struggled with the same part of the game, it usually meant the game needed to change rather than the player needing to "learn" it.
We also learned how interconnected a mobile game becomes once you add real monetization, authentication and cloud data.
A small change to one system can affect several others, so testing the complete flow became just as important as testing individual features.
My mainframe background reinforced that lesson.
In systems where money, transactions or persistent records matter, correctness cannot simply be assumed.
A successful-looking response from the client is not the same thing as a verified transaction.
That mindset ended up influencing everything from reward redemption to cloud saves to account identity in JETBREAK.
Most importantly, we learned to keep improving the game based on evidence rather than adding features simply because they sound impressive.
Watch people play. Then build what the game is actually asking for.
What's next for JETBREAK
The current release is not where we want JETBREAK to stop.
Our next major gameplay direction is giving players more meaningful choices during a run.
The current game already has permanent Workshop progression and temporary power-ups.
The next step is to experiment with temporary run builds where players can choose upgrades during a run and develop different versions of their weapon and playstyle.
For example, a player could build toward faster firing, heavier plasma, multi-shot projectiles or piercing attacks, with some upgrades potentially combining into stronger effects.
We are deliberately waiting to add that system until the current release has gone through its release cycle.
After that, we want to do what we have done throughout development:
put it in front of players, see what actually happens, and build the next version from that feedback.
The goal isn't to keep adding features just to make the feature list longer.
The goal is to make the next run more interesting than the last one.
Built With
- canvas
- capacitor
- react
- typescript
Log in or sign up for Devpost to join the conversation.