Why I Chose Godot Over Unity for a Web Flight Sim
I didn't start with Godot. I started with Unity. Three months of Unity, actually, before I made the switch. The project was an online flight sim that had to run in a browser, on a phone, without asking the user to install anything. That constraint made the decision for me.
The SharedArrayBuffer problem
Unity's web export uses multi-threading. Multi-threading in a browser requires SharedArrayBuffer. SharedArrayBuffer requires two HTTP response headers on your server:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corpThese headers (COOP/COEP) break things. Images from external CDNs won't load unless they set their own CORS headers. Iframes from other origins won't embed. Analytics scripts, ad scripts, social embeds — anything not explicitly CORS-opted-in stops working. For a simple portfolio site hosting a game, this was a dealbreaker.
Godot 4.7 with the GL Compatibility renderer exports to WebGL2 as a single-threaded build. No SharedArrayBuffer. No COOP/COEP headers. Just put the files on any web server — static hosting, GitHub Pages, Cloudflare Pages, an S3 bucket, whatever — and it works.
That alone was enough to switch.
PWA on phones
The web export runs on mobile browsers. Chrome on Android, Safari on iOS. And because I added a simple manifest.json and a service worker, it installs as a PWA. Users get a home-screen icon, full-screen gameplay, and offline caching. It feels like a native app but it's a web page.
Unity's web export also works on mobile in theory, but the binary is significantly larger and the SharedArrayBuffer requirement means it simply doesn't work in many mobile browser configurations. I tested it on six phones. It worked on two.
Godot's web export worked on all six, first try.
Binary size
The Godot 4.7 GL Compatibility export for Oliver's Planes — the full game, all five aircraft, all worlds, touch controls, online multiplayer — compresses down to about 5 MB. The equivalent Unity build was north of 20 MB for a simpler prototype.
On a 3G connection (still common in a lot of the world), that's the difference between a 3-second load and a 15-second load. At 15 seconds, people leave.
The scene tree
I build everything in code. No editor scenes, no prefabs, no drag-and-drop. Every mesh, every collision shape, every particle system is created in _ready() with add_child(). Godot's scene tree makes this natural. A node is a node. You add children. They inherit transforms. You remove them when you're done.
Unity's equivalent is GameObject + Transform, which is conceptually similar but syntactically heavier. Instantiating a mesh at runtime in Unity means creating a GameObject, adding a MeshFilter, adding a MeshRenderer, assigning a mesh, assigning a material, setting the transform. In Godot:
var mi := MeshInstance3D.new()
mi.mesh = BoxMesh.new()
mi.mesh.material = my_material
mi.position = Vector3(10, 0, 5)
add_child(mi)Four lines. No components. No GetComponent. Just nodes with properties.
GDScript is enough
I hear this a lot: "But GDScript is slow." And yeah, if you're writing a ray tracer or a fluid sim, it's too slow. But for game logic — reading input, moving characters, spawning particles, managing UI — it's fast enough. My flight physics run in _physics_process at 60 Hz with sub-millisecond frame times. The bottleneck is GPU fill rate from the terrain mesh, not CPU from GDScript.
GDScript's syntax is clean. It's Python-adjacent, so there's almost no learning curve. It has static typing (I use it everywhere) so the editor catches bugs before runtime. And the iteration speed is unbeatable — change a script, press F5, you're running the game. No compile step. No 30-second build. Just go.
Free and open source
Unity is free until you make $200K/year (or was it $100K? the licensing changes so often I've lost track). Godot is free. Period. MIT license. No revenue thresholds, no splash screens, no phone-home telemetry. The source is on GitHub and I've read parts of it when I needed to understand how the WebSocket implementation works.
For a solo indie dev who might never make $200K but doesn't want to worry about licensing gymnastics, this matters.
What I miss from Unity
Asset Store. Full stop. Godot's addon ecosystem is growing but it's nowhere near Unity's. If I needed a production-ready VOIP plugin or a sophisticated analytics SDK, Unity's ecosystem wins. But my games are built from primitives — box meshes, cylinder meshes, math. I don't need the Asset Store.
The other thing is documentation. Unity has 20 years of tutorials, forum posts, and Stack Overflow answers. Godot has maybe 5 years of comparable coverage. When I hit a weird WebSocket edge case, there were three relevant forum posts. For Unity, there'd be thirty.
The bottom line
I chose Godot because it exports to the web cleanly, runs on phones without hacks, ships a small binary, and lets me build everything in code without fighting the engine. If my requirements were "native desktop game with AAA rendering," I might have chosen differently. But for "multiplayer arcade game that runs in a browser tab on someone's phone"? Godot wins and it isn't close.
Written by Oliver
Indie game developer building 3D web experiences in Godot and Next.js. I write about creative coding, procedural generation, and game feel.