Fizzics' entire concept rests on one bet: glowing liquid blobs that merge and explode will look spectacular on a phone screen. If I can't render fluid physics at 60fps on an iPhone, there's no game. Just a nice concept doc and a life lesson about validating assumptions.
So before writing a single line of production code, I built the spike.
The Question
Can metaball-based viscous blobs merge visually by color at 60fps on iPhone?
This is a Go/No-Go question. Everything downstream (architecture, UI, game design) depends on the answer. If this spike fails, I kill the project. If it passes, I commit fully. No middle ground.
The Approach
I started with an open-source Unity MetaBalls Liquids implementation and extended it with three things:
Per-color distance fields. This was the key insight. Instead of one global metaball field where everything merges into everything (a blobby mess), I compute separate distance fields per color in the shader. Same-colored blobs flow together organically. Different colors maintain distinct boundaries with zero bleed. It looks like colored liquids sitting next to each other, exactly the oil-and-water effect I needed.
URP 2D Render Pipeline. A custom ScriptableRendererFeature for the metaball pass. URP's Bloom post-processing gave me the neon glow effect essentially for free. No custom VFX system needed for the base aesthetic. Sometimes the framework just hands you a win.
Half-resolution rendering. The metaball shader runs at 0.5x screen resolution, then composites at full res. Visually indistinguishable at phone viewing distance. Cuts GPU cost roughly in half. This turned out to be the difference between "playable" and "my phone is a space heater."
The Results
Testing on an iPhone Air (A19 Pro):
| Metric | Result |
|---|---|
| Frame rate | 60fps stable |
| Blob count | 30 simultaneous |
| Resolution | Half-res (0.5x) |
| Glow | URP Bloom (free) |
Verdict: Go.

The blobs genuinely look like glowing liquid. Not "good enough for a prototype," actually good. The kind of thing you'd show someone to explain what the game is.
Things That Almost Went Wrong
Unity defaults to 30fps on iOS. I didn't know this. I spent an hour staring at the profiler wondering why my "60fps" target was producing a rock-solid 33ms frame time. Turns out Unity caps at 30fps on iOS unless you explicitly set Application.targetFrameRate = 60. The spike would have "failed" for a setting I didn't know existed. Always validate your assumptions about the platform, especially the stupid ones.
Full-res rendering was a no-go. I almost scrapped the metaball approach when the editor started hitching badly. Then I tried half-res on a whim, and the frame rate doubled with no visible quality loss. The lesson: when your GPU is the bottleneck, throw fewer pixels at it before you throw the whole approach away.
Viscosity is still too watery. The physics settings (gravityScale=1.5, linearDrag=2, angularDrag=3) produce natural blob behavior (splat, settle, pile up) but they feel more "water balloon" than "thick liquid." Good enough to validate the concept, but I know this will be a production-long tuning exercise.
Risk Mitigation
| Risk | Before Spike | After Spike |
|---|---|---|
| Fluid rendering quality at 60fps | Critical blocker | Mitigated |
| Per-color blob grouping confusing | Uncertain | Mitigated |
| Viscosity tuning | Uncertain | Needs iteration |
With the critical risk mitigated, the conditional Go became unconditional. Time to build the actual game.
// The line that unlocked everything
Application.targetFrameRate = 60;
// Half-res metaball rendering: the difference between
// "playable" and "thermal throttling"
[SerializeField] float renderScale = 0.5f;