Back to Blogs
#flutter#ai#webassembly#gamedev

Stress-Testing Gemini 4 Argon: Building a 3D Flutter Kart Game in 15 Prompts with Zero Assets

Most AI coding benchmarks test standard web apps or CRUD dashboards. Frontier models can already...

6 min read
Cover for Stress-Testing Gemini 4 Argon: Building a 3D Flutter Kart Game in 15 Prompts with Zero Assets

Most AI coding benchmarks test standard web apps or CRUD dashboards. Frontier models can already one-shot those, so they don't tell you much anymore.

To really stress-test Gemini 4 Argon (inside Antigravity), I gave it a much weirder challenge: build a 60 FPS, Mario Kart-style 3D racing game in Flutter.

The catch? Zero external assets. No Blender .glb models, no .png textures, and no downloaded .mp3 sound packs. Everything you see and hear had to be generated by code.

Flutter Kart Grand Prix Gameplay


The Scoreboard

Going from an empty folder to a live WebAssembly game on GitHub Pages took 15 prompts and about 3.5 hours of active build time:

Metric Result
Model Tested Gemini 4 Argon
Total Prompts 15
Active Build Time 3h 26m (4h 35m wall-clock with playtesting)
External 3D / Image Files 0 (100% generated in code)
Cross-Platform Code Shared 96.7% between macOS Desktop and WebAssembly

How the 15 Prompts Played Out

Instead of writing long technical specs, I gave short, casual feedback just like playtesting with a teammate:

  • Prompts 1 to 4 (Building the Game): "Create a 3D kart racing game using Flutter", "Polish the visuals", "Add Llama and Flutter Dash", and "Compare it to Mario Kart and improve it." This got us the track, 4 playable mascots, 3-tier drift boosts, jump ramps, coins, and 7 items.
  • Prompts 5 to 9 (Visual Debugging): The agent launched the macOS app, took screenshots of its own window, and fixed camera angles, character silhouettes, and wall collisions.
  • Prompts 10 to 12 (Fixing "Cheap" Audio & Speed): I complained that "the BGM sounds too cheap", "the game is a bit too fast", and "the BGM loop is cut."
  • Prompts 13 to 15 (Shipping to WebAssembly): I asked "Can you run this on web?" and had it deploy a WebAssembly build to GitHub Pages.

3D Showroom & Mascot Selector
The 3D Showroom selector and race setup screen.

Turbo Llama Overtaking Flutter Dash
Turbo Llama overtaking Flutter Dash on the Emerald Coast Circuit.


1. How Do You Build 3D Characters Without Blender?

An AI can't open Blender and sculpt a mesh with a mouse. So how did it create Flutter Dash, Turbo Llama, Bugdroid, and Blaze Dino?

It treated 3D modeling like Lego. Using flutter_scene and Flutter GPU, it combined basic geometric shapes (spheres, cones, capsules, rings, and boxes) in kart_builder.dart to build each character and kart.

Procedural 3D Pipeline

It used the same trick for textures in pbr_assets.dart. Since we had no .png files, the app generates its own asphalt grain, tire skid marks, and surface bump maps in memory when the game boots up.

The coolest moment here was visual self-correction. On its first try, Flutter Dash looked cute from the front in the character selector. But once the race started, you only see the back of the driver's head, and Dash looked like a plain blue bowling ball.

After taking a screenshot of the running game window, Gemini 4 Argon noticed the problem on its own. It went back into the code and added a goggle strap, a fluttering red scarf, tail feathers, and angled wings so you could actually tell it was Dash from behind.


2. "Your Audio Sounds Too Cheap"

In Prompt #5, I asked for music and sound effects. To avoid external files, the model wrote a basic synthesizer in Dart using sine and square waves.

Technically it worked, but it sounded like a cheap 8-bit toy. So in Prompt #10, I told it:

"Can you improve the BGM and the sounds more? They sound too cheap..."

I expected it to just tweak its synth math. Instead, it did something much smarter: it remembered that every Mac comes with a complete Roland MIDI instrument library hidden inside macOS (/System/Library/Components/CoreAudio.component/Contents/Resources/gs_instruments.dls).

It wrote a Swift script (generate_studio_audio.swift) that loads that built-in Apple soundbank, plays multi-track brass horns, slap bass, jazz organ, and drums through a studio reverb effect, and exports stereo WAV files into the project.

Fixing the Loop Cut

When I listened to the new music, it sounded great, except for a tiny cut every 14 seconds when the loop restarted.

Seamless 3-Cycle Audio Looping

Why did it cut? Because at 0:00 the reverb room is completely quiet, while at 0:14 the echo from the last note is still ringing out.

To fix it, the model rendered the 8-bar loop 3 times in a row and sliced out the middle take (Take 2). Because Take 2 already has the natural echo spilling over from Take 1, it loops forever with zero clicks.


3. Why Flutter? Native macOS to WebAssembly in 7 Minutes

A big reason I picked Flutter for this experiment was to test cross-platform 3D.

Instead of using a heavyweight third-party game engine, the game uses a standard 60 Hz Flutter Ticker for physics, flutter_scene for 3D rendering, and a regular Flutter CustomPainter overlay for the 2D HUD (speedometer, minimap, and item roulette).

Flutter Kart Grand Prix Architecture

For the first 12 prompts, we only ran the game as a native macOS desktop app on Apple Metal. Then in Prompt #13, I asked:

"Can you run this on web?"

Out of 12,082 lines of Dart code, 96.7% worked on the web with zero changes. All the 3D karts, shaders, textures, physics, and HUD compiled straight to WebAssembly (flutter build web --wasm).

The only thing that needed to change was the audio player (macOS command-line audio vs. browser HTML5 audio), which took a 3-line conditional import in sound_backend.dart:

export 'sound_backend_stub.dart'
    if (dart.library.io) 'sound_backend_io.dart'
    if (dart.library.js_interop) 'sound_backend_web.dart';
Enter fullscreen mode Exit fullscreen mode

Total time to bring a native macOS 3D game to Chrome: under 7 minutes.

The Sneaky GitHub Pages Bug

When we deployed the WebAssembly build to GitHub Pages, the live site got stuck on the loading spinner. All I told the agent was: "The static web doesn't seem working."

It opened the live URL in headless Chrome, checked the network logs, and found that the 3D .shaderbundle files were returning 404 Not Found.

The culprit was surprisingly sneaky: when flutter_scene compiles shaders locally, it drops a .gitignore containing * into its generated folder so you don't commit build artifacts. When flutter build web copies assets into build/web, it copies that .gitignore file too. So when we pushed build/web to gh-pages, Git dutifully ignored all our 3D shaders!

Deleting nested .gitignore files before deploying fixed it right away:

flutter build web --release --wasm --base-href "/flutter-kart-gp/"
find build/web -name ".gitignore" -delete
Enter fullscreen mode Exit fullscreen mode

Where Gemini 4 Argon Needed Pushback

It definitely wasn't a one-shot magic trick. Watching where the model stumbled on the first try was the most interesting part of the test:

  1. Camera perspective blindness: When building 3D models in code, it initially designed characters from the front. It didn't realize you stare at the back of the kart 95% of the time until it looked at a live gameplay screenshot.
  2. Settling for "good enough" audio first: Left to itself, it wrote basic 8-bit beep oscillators. It took human pushback ("they sound too cheap") to make it tap into macOS's built-in Roland instrument bank.
  3. Tuning speed for AI, not humans: Its first version of the game was ~22% too fast because AI drivers have zero reaction delay. I had to ask it to slow the karts down so human players could actually make the corners.

The Verdict on Gemini 4 Argon

What impressed me most wasn't that Gemini 4 Argon could write 13,000 lines of Dart and Swift. It was how it recovered when I pushed back.

When it couldn't use 3D asset files, it built Lego-style rigs in code. When its first audio synth sounded cheap, it found a system MIDI soundbank hidden inside macOS. And when the WebAssembly build broke on GitHub Pages, it inspected the live browser logs and caught a hidden .gitignore file eating the shaders.

Try It Out

You can play the WebAssembly build right in your browser (Chrome, Edge, or Brave), or clone the repo to run natively on macOS:

git clone https://github.com/leehack/flutter-kart-gp.git
cd flutter-kart-gp
flutter config --enable-flutter-gpu
flutter run -d macos   # or: flutter run -d chrome
Enter fullscreen mode Exit fullscreen mode