Fold the wings to fit through the gap — an arcade reflex game written in Unity.



TunnelPulse is an arcade reflex game. You fly a ship down a rotating tunnel and thread it between the obstacles coming at you. The controls are two moves: dragging carries the ship, two fingers fold the wings.
There are twelve obstacle types and they do not all want the same thing. The game says which through four action cues, each in its own colour: most need nothing at all (glide), a tight hole needs fold, the pie and chord shapes need roll and follow the opening, and the Slot wants the exact reverse — open the wings and line up.
The same control having two opposite uses is the core of the game. The colour code makes it readable at a glance, but you get well under a second to decide.
When a run ends you see how far you got and how that compares to your best. The menu holds your level, weekly missions and a market with two tabs: ships, and the game’s currency, AMP (from the oscilloscope theme; it is AKIM in Turkish). Score, player and economy services live in a separate server project.
The game is written in Unity and C#. The server side is a separate project: a Fastify API for score and player services, plus an admin panel. AdMob and RevenueCat handle monetisation.
The tunnel, the obstacles and most of the interface are generated at runtime rather than placed into a scene by hand. The practical consequence is that balance values — difficulty curve, obstacle frequency, gap width — can be tuned by changing numbers instead of rebuilding a scene.
That makes it possible to balance by measurement instead of by guess: changing a value and replaying the same run takes seconds.
The game sells ship skins. If each ship’s collision shape came from its own mesh, two things would follow: either some ships would be narrower than others (an advantage you can buy), or every obstacle would need re-tuning for every new ship. Neither is acceptable.
So the collision model is analytic and fixed: thirteen sample points — the centre, eight around the body at 45° steps, and two on each wing. Folding the wings makes the body radius grow (0.40 → 0.62): the price of fitting through a tight hole is a fatter body.
Adding a new ship changes no code; the art is fitted to that fixed profile.
The same collision model felt wrong in two different ways:
⚠️ The wing points were deliberately left on the visual outline: wing contact does not kill, it damages. Applying the same tolerance there would have closed the game’s only “forgiven mistake” channel.
The leaderboard, player records and in-game economy are not left to the client; they are managed through a separate API and admin panel. That also means a balance value can be changed without shipping a new build.
For rewarded ads, the client does not grant the reward: AdMob’s server-side verification calls an endpoint on the server and the balance is written there. In a design where the client grants it, all a player has to do is fool the app.
Purchase refunds also come back in real time from both stores: Play sends Pub/Sub notifications and Apple sends App Store server notifications to RevenueCat, which webhooks straight into the game’s economy.
Runtime generation instead of a hand-placed scene. In a hand-built tunnel, changing the difficulty curve means rebuilding the scene, which makes experimenting expensive and therefore rare.
Moving to generation turned balance into a config problem. The cost is less visual variety than a hand-authored level would have — an acceptable trade in an endless runner.
What you buy does not change how the game plays. The collision profile is identical on every ship; when a new ship arrives, what gets adjusted is the art, not the collision.
The alternative was deriving collision from each ship’s own mesh. That road leads either to pay-to-win or to re-balancing every obstacle for every new skin — both the kind of decision you cannot walk back once it ships.
The rule as written in the code is: what you see is what you hit. An obstacle’s drawn mesh and its collision test come from the same maths, and a validator enforces that for every obstacle type.
You drag to move the ship inside the tunnel and use two fingers to fold the wings. Twelve obstacle types ask for four different things: most just need gliding, a tight hole needs folding, the pie shape needs rolling, and the Slot needs the wings opened and lined up. The goal is to get as far as you can.
The gameplay itself runs on the device. The leaderboard, player records and in-game economy go through a separate server project, and those need a connection.
Because the tunnel and obstacles are generated at runtime, values like the difficulty curve and gap width can be changed without rebuilding the scene. Balance is set by measurement — replaying the same run with different values — rather than by guesswork.
I build products from idea to store release. Reach me by e-mail.