Oliver's Planes
Arcade flight sim. Thread the rings, buy faster planes.
Tip: click Fullscreen for the best experience.
Eight rings, and you start already in the air
There is a runway under the plane at the start and you never use it: you spawn at 80 metres already doing 55 m/s. It is scenery I built and then flew straight over.
Read the build notes ↓About this project
An arcade flight simulator built in Godot 4 with zero external assets. Every plane, world, and HUD is generated in code. Fly through glowing rings across five themed worlds, earn cash, complete quests, and upgrade your aircraft in the garage. Plays on desktop and phone.
Built with
How to play
- Hold left or right mouse button, then move the mouse
- Steer the plane. Sideways rolls it, forward and back pitches it; let go of the button and it flies itself straight and level.
- W / S (Shift / Ctrl do the same)
- Ramp the throttle up or down; it never falls below 30 percent, so the engine is never dead.
- A / D or Left / Right arrow
- Roll left or right from the keyboard, without touching the mouse.
- K / Down arrow and I / Up arrow
- Pull the nose up (K or Down) or push it down (I or Up).
- Q / E
- Kick the rudder left or right. Optional, since banking already swings the nose round.
- R (or the round R button, bottom right, on touch)
- Reset the plane to the start of the course straight away.
- G / M (or the GARAGE and MAPS buttons, bottom centre, on touch)
- Open the garage or the map picker; the same key closes it again, and Esc closes either.
- Enter or Space (on touch, tap a card once to select and again to confirm)
- Buy and equip the highlighted plane, or fly to the highlighted map.
- Drag anywhere in the left 42 percent of the screen (touch)
- A stick appears under your thumb and steers the plane; lift off and it levels itself out.
- Slide the rail at the right edge of the screen (touch)
- Set the throttle, which stays where you leave it so your thumb is free.
Build notes.
Eight rings, and you start already in the air
There is a runway under the plane at the start and you never use it: you spawn at 80 metres already doing 55 m/s. It is scenery I built and then flew straight over.
Eight glowing rings, taken in order. The next one is yellow and pulsing, the ones ahead are blue, the ones behind go dim green. Only the active ring scores; flying through the others does nothing. Each ring pays $50, finishing all eight pays $300, and 4.5 seconds later the lap resets itself. A clean loop is $700.
The rings drop as you go: the first sits around 84 m, the sixth around 21 m. When the next one is behind you the HUD marker becomes an arrow pinned to the screen edge, distance underneath.
You can only crash into the ground. The mesas, pines and skyscrapers have no collision. They are plain meshes. Below 2.2 m you count as crashed and respawn 1.6 seconds later.
Everything you see is drawn in code
No model files, no textures. The planes are stacks of boxes. Trees and mountains are cylinders with the top radius set to zero. The ground is a 64x64 checkerboard written pixel by pixel at load and tiled a thousand times across an 8 km plane, so a grid line goes past every 8 metres. The HUD, the garage and the map picker are draw_rect and draw_string calls.
The five airframes. High-wing trainer, low-wing sport, radial warbird, twin-tail jet, delta rocket. Come out of the same box-stacking code with different numbers. The three propeller planes spin a hub and two crossed blades at 4 plus 60 times throttle radians a second. The jet and the rocket get glowing nozzle blocks instead.
That is why the game data file is 112 KB. The 39 MB sitting next to it is Godot's WebAssembly runtime, not my game.
Maps are data too: sky colours, fog density, sun angle, scatter counts. All five are generated from one seed, 20260620. Scenery is scattered before the ring course is placed, from the same random stream, so Alpine Snow with its 120 pines and Sunset Coast with its 16 islands end up with different gaps between their rings. Same for every player, different in every world, which I only noticed writing this.
The flight model is not aerodynamics
Thrust pushes along the nose, gravity pulls down at 16, lift pushes along the wing's up vector in proportion to forward airspeed, drag is quadratic plus a small linear term. Then the part that matters: every frame the velocity vector eases toward wherever the nose points, at a rate of 2.6. Without it you fly a brick that slides sideways through its own turns.
Banking swings the nose at 1.45 times the bank angle per second, which is why the rudder is optional, you turn with roll.
Underneath sit assists I would rather admit to than hide. Throttle never drops below 30% (35% in the trainer). The airspeed used for lift never falls under 5.85, so slow flight mushes down instead of dropping. Below 14 m, if you are sinking, the game quietly adds lift and raises the nose. Let go of everything and the wings roll level and the nose returns to the horizon.
Getting it to work with thumbs
The phone controls are a stick that appears wherever you press in the left 42% of the screen, and a throttle rail down the right edge that stays where you leave it.
Three things went wrong. The auto-level check tests roll == 0.0 exactly, so the touch axes have to snap to literal zero on release, not to something small. Godot was synthesising mouse events from touches, so every tap drove the hold-mouse-to-steer path and fought the joystick. One project setting, switched off. And is_touchscreen_available() reports false in a web build until the first interaction, so the controls stayed hidden on real phones. The first screen touch now reveals them.
The one that cost me an evening: picking a new map reloads the scene, and a reload inherits the paused flag from the menu that triggered it. The new world came up frozen. Unpause first, then reload.
What to try
The garage is G. Planes cost $350, $1,100, $2,600 and $5,500; the top one, the Vortex-X Apex, is capped at 208 m/s. 749 km/h against the trainer's 403. Speed costs agility: handling runs from 1.25 on the trainer down to 0.82 on the Apex.
Eight quests pay $2,600 between them. Ace Pilot wants the course in under 40 seconds for $600. Not a Scratch wants a lap with no crashes for $400, and the only thing you can hit is the ground.
Money, planes, quests and your map save to a config file after every transaction, not on quit. On the web a quit never fires. Close the tab mid-lap and the cash is still there.