Up until now, every version of this game has lived on a desktop screen. Keyboard controls, a mouse for menus, a desktop window. The game was designed with mobile in mind from day one, but “designed with mobile in mind” and “actually running on a phone” are two very different things.
This week I picked up my phone, opened TestFlight, tapped Install, and played Gridiron Rumble on an iPhone.
Touch controls
Getting touch controls right took three passes.
Pass one: movement. A virtual joystick on the left side of the screen replaces WASD. Drag your thumb and your player moves — simple. Push the joystick past 85% of its radius and your player auto-sprints, so there’s no need for a dedicated sprint button on mobile. It sounds like a small thing, but it freed up screen real estate and made movement feel intuitive immediately.
Pass two: passing. On desktop, each receiver is mapped to a keyboard key. On mobile, each receiver gets an enlarged circular touch target (~70px) that you tap and hold to charge throw power, then release to throw. Tap-to-snap works the same way — tap anywhere to start the play. The core mechanic translates surprisingly well. You lose the precision of dedicated keys, but you gain something that feels more physical — like you’re actually pointing at your target.
Pass three: action buttons. Juke, stiff-arm, style, and pitch are arranged vertically on the right side of the screen. They only appear when you’re a ball carrier, so the screen stays clean during pre-snap and on defense.

The key architecture decision was using synthetic input injection — the touch layer fires the same input events that the keyboard does, so the core gameplay code doesn’t know or care whether you’re on desktop or mobile. Zero changes to Player.gd. That means every gameplay fix and feature I ship for desktop works on mobile automatically, and vice versa.
Getting it on the device
Touch controls are the flashy part. The unglamorous part is everything else it takes to get a Godot game running on iOS.
App icon. Display name. Locking orientation to sensor landscape so the game auto-rotates but never goes portrait. Setting up the export template, signing certificates, and provisioning profiles. Writing a step-by-step export guide so future-me doesn’t have to figure it all out again. None of it is hard individually, but there are a lot of boxes to check and most of them don’t have great documentation for Godot specifically.
![]()
TestFlight
The game is on TestFlight.
That means it went through Xcode, got signed, got uploaded to App Store Connect, passed processing, and is installable on a real device through Apple’s beta testing platform. It’s not in the App Store, but it’s no longer just a project on my laptop. Someone else could install it and play it.
There’s a shift that happens when your game has an app icon on a home screen. It starts feeling real It’s the same game, same prototype art, same placeholder sounds. But holding it in your hand changes something.
Where this lands
Gridiron Rumble runs on a phone. You can draft your team, call plays, juke defenders, and throw touchdowns with your thumbs. The touch controls work. The game doesn’t crash. It fits on a screen you carry in your pocket.
There’s still a mountain of work ahead - animations, sound design, safe area handling for the Dynamic Island, performance optimization on older devices. But the iOS path is open now. The game isn’t desktop-only anymore.
Huge win.
— Jesse