
Few things in Rainboids got as much patient, near-obsessive attention as the background starfield. From the start, I wanted it to feel like more than a backdrop — more than a black screen with some white dots on it. I wanted it to feel alive. Stars blink. Their brightness slides up and down on long, slow rhythms, so each pinpoint has a kind of unhurried breath to it. Soft blobs of color drift in the deep distance, suggesting far-flung nebulae. Bright halos and four-armed spikes pin the occasional pulsar or quasar to the sky at varying depths. Together, the goal was a universe that breathes around the player rather than sitting motionless behind them.
Here’s the story of how that sky was built.
Starting With a Bunch of Dots
The earliest version was, like most things in Rainboids, a hand-rolled approximation of an idea I could only half see. A few hundred white dots, scattered around the screen, all twinkling in lockstep. It looked passable. It also looked dead.
You can tell from the early commits that I was already wrestling with it: “tuning starfield parameters,” then “better star generation, fewer stars.” Too many stars and the field distracted from the action. Too few and the sky felt empty. That’s the first thing I learned — a starfield is a contract with the player’s attention. Every dot is asking to be looked at. The trick is to make most of them gracefully refuse.
The first real breakthrough came when stars stopped being one thing. Some became decorative — soft pinpoints in cool tones, shaped like circles, diamonds, triangles, hexagons, and four-, five-, six-, and eight-pointed stars. Others became collectibles — the health orbs and money coins that drop from enemies, dressed in greens and golds. A small slice of the decorative stars got promoted to “big stars,” with larger shapes, gentle rotation, and a soft glow. The rest stayed quiet pinpoints. From the player’s side, the field stopped looking like wallpaper and started looking like a sky in which a few rare jewels caught the light.
The Twinkle and the Breath
Stars in real life don’t actually twinkle from anything they’re doing — that’s just our atmosphere distorting the light on the way down. But in a videogame, twinkling is more truthful than the truth. A motionless dot reads as inert. A dot that pulses reads as a star.
So every star carries its own little internal rhythm — a phase, a speed, an amplitude — and its brightness rides a slow sine wave. The amplitudes are small on purpose. Earlier on I had stars dimming much more aggressively, and they ended up flickering instead of breathing. The current version gives a sigh, not a strobe.
Later I added a second motion on top of the first: the breath. The same wave that drives brightness also drives a tiny size pulse. Stars don’t just brighten — they swell faintly with their own light. With both motions running on each star at independent speeds and offsets, the field stopped feeling like a bitmap and started feeling like respiration.
Depth, Parallax, and the Trick of Brightness
A starfield without depth is a flat sky. A starfield with depth is a window.
Each star carries a depth value, and when the ship moves, each one slides backward a little — distant ones barely shift, close ones drift more. The player feels themselves moving through something rather than across a painted screen. Easy to write down; surprisingly fiddly to tune. Too much parallax and the close stars whip past distractingly. Too little and you can’t tell anything is happening at all.
For a long time, every star rendered at the same baseline brightness regardless of size. The biggest decorative shapes consequently dominated the field — the player’s eye kept locking onto a slowly rotating eight-point star, looking for a target. The fix turned out to mirror something true about real astronomy: distant stars look bright not because they emit more light but because all of their light arrives concentrated in a single pixel. Closer stars spread their light over more area and read as softer.
So Rainboids adopted what I started calling the “astronomical rule.” Tiny stars render hot and punchy. Bigger stars get progressively dimmer. The largest decorative shapes are the dimmest of all — atmospheric, present, but quiet. The instant the rule was in place, the field read as cosmic atmosphere instead of gameplay clutter. The big shapes became settings. The tiny dots became stars.
Nebulae: A Brief, Beautiful Detour
For a while, the background carried full painterly nebulae. I went a little wild. Layered blobs with multi-stop color gradients. Sub-blobs as small ellipses with random rotations. Hot off-center cores. Stardust speckles biased toward the bright regions. Filament threads running tangent to the outer edges. Dust lanes painted on top, mimicking the dark absorption silhouettes that bisect real emission nebulae like Trifid and Eagle and Lagoon. Embedded lens-flare stars with halos and four-arm diffraction crosses, scattered through the gas. Connecting wisps. Per-layer sky tints. Even a pool of named scene palettes — cobalt-deep, violet-nursery, teal-aurora, ember-warmth, periwinkle-dream, crimson-ultraviolet, emerald-jade, rose-petal.
The screenshots looked like Hubble photos.
The play sessions looked like Rainboids drowning under fog.
The cumulative effect of every haze layer — the speckles, the filaments, the dust lanes, the wisps, the sky tints — was a thin uniform veil over the entire canvas. It washed out the foreground. The player’s bullets, the player’s ship, the enemies, the asteroids — the very things the eye was supposed to find quickly were suddenly hard to see. So one afternoon I reluctantly tore most of it out. The blob bodies went. The speckles went. The filaments, the dust lanes, the wisps, the sky tints — all gone.
What remained was the loveliest piece: the lens-flare stars. Soft halos. Four-armed diffraction spikes. A bright saturated core with a white-hot center. Sparse pinpoints of light scattered across a dark canvas, with the void showing through in between them.
The result felt right immediately. The sky read as space again. The action read as action again. And the lens-flare stars — without their crowd of supporting effects — became the rare, precious accents they were always meant to be.
It was the first big lesson of the project: more is almost always less.
Letting the GPU Carry the Load
By the middle of development, a few hundred stars on the regular 2D canvas had become a real cost. Hundreds of little draw calls per frame, hundreds of opacity changes, hundreds of fills. The starfield was, in performance terms, getting in the way of itself.
So I moved the bulk of it to the GPU. The new pipeline bakes a small atlas of star shapes once at startup — a soft dot, a diamond, a triangle, a hexagon, a few different point counts — and then every star in the sky becomes a single instance the GPU can stamp out in one big batch. All the heavy lifting — parallax, twinkle, rotation, breathing — happens in the shader. The CPU’s job, every frame, is basically to push a couple of numbers and ask for one draw call.
The budget exploded. Where before the field topped out around sixty stars, now it carries hundreds without breaking a sweat. The frame cost is essentially flat regardless of how many stars are on screen. Some of the more elaborate shapes — sparkles, bursts, the collectible orbs — still draw on the regular canvas, because they need behaviors the simple atlas can’t express. But everything else lives on the GPU now, and the CPU got its breathing room back.
Light, Color, and the Fragile Art of Brightness
Bright, saturated color in this kind of pipeline is trickier than it sounds. I spent more time than I’d like to admit fixing variations of the same bug: hot colors quietly turning pale.
The first attempt at “brighter stars” multiplied the output color by a brightness boost. It looked great on white stars. It silently destroyed every saturated hue. Yellow-gold stars came out as pale lemon. Hot pink came out as washed pink. Anything with two channels near maximum lost its identity, because the boost pushed those channels off the top end and clipped them flat.
The fix was philosophical. Instead of pumping the color and hoping it didn’t clip, the pipeline keeps every star’s color at full saturation and modulates brightness through transparency instead. Hot pixels still read as bright (the way colors stack in the renderer takes care of that), but every saturated mid-band hue keeps its identity. Color stopped being a casualty of brightness.
A halo glow was added at the same time — a soft circle of color spreading outward from each star, but only into the empty space around the silhouette, never on top of it. Diamonds glow violet. Hexagons glow amber. Six-point stars glow neon cyan. The sky learned to be colorful without learning to be muddy.
A Real Night Sky, Mostly
Even with the field colorful and breathing, something was off. Pure-white stars are a fine baseline — most real stars actually do read as blue-white to the eye — but a sky entirely in the cool-tone family looks digital. A real night sky has wanderers in it: red giants, sodium-yellow variables, sun-tinted main-sequence stars at certain depths.
So I diversified the palette. The decorative shapes got a much wider range of saturated tints — violet, magenta, hot pink, electric blue, neon cyan, emerald, lime, gold, amber. The plain pinpoint stars stayed mostly cool, but with the occasional saturated burst mixed in. The result reads, to the player’s peripheral vision, like a real night sky most of the time, with quiet bursts of color punctuating the dark. Cosmic, not cartoon.
The lens-flare stars got their own pool of curated palettes, each named after a hue family — cobalt, violet, teal, ember, periwinkle, crimson, emerald, rose, twilight, solar, aurora, sunset. A fresh palette gets picked at random for each run. One game might unfold under cobalt; the next under sunset; the next under aurora. The sky has moods.
Clouds Through the Same Pipeline
The lens-flare layer alone, however lovely, was a little thin. The dark canvas between flares felt vast. So I added one more shape to the atlas: a soft volumetric cloud blob. A wide gaussian falloff with a bit of organic noise mixed in. Scaled up to enormous sizes and drawn very faintly, it becomes the suggestion of distant gas.
A handful of these clouds spawn per run, anchored deep in the background so they barely move with the camera, tinted in saturated nebula colors and rotating very slowly. They render through the exact same pipeline as everything else — no new draw calls, no new shader, the GPU cost rounds to nothing. With everything stacking additively, overlapping clouds blend into mixed-hue patches, giving the sky the ghost of structure without the haze problem from the painterly era.
There was a brief, comic regression here. When I added a global flicker layer — a faint, fast, irregular blink across the field, to give the stars a more organic feel — it accidentally got applied to the clouds too, which immediately turned them into a 5 Hz strobe. Whole patches of the sky pulsing on and off. A one-line fix: stars flicker, clouds drift. The way it should be.
Solids and a CRT Glow
Two final touches gave the field its current personality.
I added 3D-looking shapes to the rotation: a cube, an octahedron, a tetrahedron, a prism. Each is drawn as a clean silhouette with a few internal edges that suggest depth without actually computing any. They mix in with the existing 2D stars, so the sky now contains both flat geometric ornaments and small dimensional jewels turning gently in place.
And, at the very end, scanlines. Every other row of pixels on the background layer gets dimmed slightly, producing the fine horizontal banding of an old CRT monitor. It only affects the sky — the foreground action draws on a separate layer on top, so bullets and explosions stay crisp. The scanlines, the soft glow halos, the breathing pulses, the lens-flare spikes, the slow drifting clouds — together they push the sky toward something almost analog. Something that feels filmed rather than rendered.
In the End
A starfield is, on paper, the simplest visual element in a videogame. A scatter of points. Maybe a parallax offset. Done.
In practice, what Rainboids taught me — across many, many iterations of this one thing — is that the simplest visual element is also the one the player’s eye spends the most uninterrupted time on. The foreground action is rare and fast and over in seconds. The background is constant. Every wrong note in it — a too-bright pinpoint, a too-large rotating shape, a foggy nebula veiling the bullets, a strobing cloud, a desaturated palette — the eye registers and quietly resents.
So the work was patience. Brighten. Darken. Add structure. Strip structure. Diversify the palette. Restrain the palette. Trust the GPU. Trust the math. Trust that what feels right will, eventually, be right.
The current sky is a quiet thing. Most of the time the player isn’t looking at it. That, in the end, is the success.
A Rough Timeline
The starfield’s journey, in milestones rather than version numbers.
The earliest days. A uniform field of pinpoints, all twinkling at the same speed. White dots on a black screen. Tuned by hand, loosely, until it looked “fine.”
Star generation gets smarter. Counts come down. Sizes diversify. The first division into decorative stars (just background) and collectible orbs (health and money, dropped from enemies) lands. Big-star promotions appear — a small fraction of stars become more elaborate, with shapes and gentle rotation.
Twinkling and breathing. Each star gets its own internal rhythm. Brightness slides on a sine wave. Later, size pulses on the same wave for a “breath” effect.
Parallax depth. A z value on every star. Distant stars move slowly, close stars move quickly. The sky stops being flat.
The astronomical rule. Tiny stars get full brightness; bigger stars get progressively quieter. The field stops competing with the gameplay.
The painterly nebula era. Full-on space-photograph mode. Layered blobs, sub-blobs, dust lanes, filaments, wisps, embedded lens-flare stars, stardust speckles, sky tints, named scene palettes. Beautiful. Too much.
The great strip-down. The blobs go. The speckles go. The filaments, dust lanes, wisps, and sky tints all go. Only the lens-flare stars survive — sparse pinpoints with halos and 4-armed diffraction spikes, scattered across a dark canvas.
Title-screen parallax. The starfield comes alive on the title screen — drifting gently before the player even presses a key. The lens-flare layer wanders along with it.
Performance reckoning. Star counts get cut in half. The render path gets smarter about batching. The starfield has to share frame budget with the action; it learns to be lean.
The WebGL migration. The bulk of the field moves to the GPU. A small atlas of shapes, baked once at startup. Every star becomes one instance in a single batch. Counts explode upward; cost essentially disappears.
Brightness and breathing on the GPU. Stars now twinkle, breathe, and rotate entirely in the shader. The CPU stops pushing per-star data every frame.
The colorful sky. The decorative palette grows from a handful of cool pastels to a much wider range of saturated hues. Plain pinpoints stay mostly cool but with occasional bursts of color. The lens-flare stars get a curated set of named mood palettes — cobalt, violet, ember, aurora, sunset — chosen at random per run.
The brightness fix. The early “make it brighter” pass quietly desaturated saturated colors; a rewrite drives all brightness through transparency instead, and saturated hues finally stay saturated. A halo glow gets added at the same time — every star gets a soft colored bloom around its edges.
Clouds. A soft volumetric blob shape gets added to the atlas. A handful of huge, faint, slowly rotating clouds anchor the deep background. Same pipeline, same draw call — essentially free.
3D shapes. Cube, octahedron, tetrahedron, prism. Drawn as silhouettes with a few internal edges to suggest depth. They mix into the rotation alongside the 2D shapes.
Scanlines and flicker. A fine horizontal banding evokes an old CRT monitor; a fast irregular blink layered over the slow twinkle gives stars an organic, stuttery character. Stars flicker. Clouds drift.
The current sky. Quiet, layered, breathing. A little colorful. Mostly out of the way. Hopefully, on the right kind of evening, almost worth flying through.



Leave a Reply