vibespire.ai / Elysian Whispers /

how it's made

open the planet β†—

Vibespire presents

How Elysian Whispers Is Made

You cannot tile a sphere with hexagons. Every hexagonal planet ever built has exactly twelve pentagons in it, and no amount of cleverness reduces that to eleven. This one puts them where the icosahedron's corners were, and then grows continents, weather and an ecology on top.

ICOSAHEDRON Γ—12 ITS DUAL β€” HEXES, AND TWELVE PENTAGONS

Both figures on this page run the engine's own generator.

The grid

Twelve pentagons, and no way around it

A planet needs a grid, and a latitude-longitude grid is a bad one: cells crowd together at the poles, distances stop meaning the same thing everywhere, and every rule you write about neighbours needs an exception near the top of the map.

So the world is tiled with a Goldberg polyhedron, built in three steps. Start from an icosahedron β€” twelve vertices, twenty triangular faces. Subdivide each face into an fΓ—f triangular lattice and project every point onto the sphere, de-duplicating the points shared along edges so the mesh stays watertight. Then take the dual: every geodesic vertex becomes a cell centre, and that cell's corners are the centroids of the triangles around it.

A vertex with six incident triangles becomes a hexagon. The twelve original icosahedron corners have only five, so they become pentagons β€” and there are exactly twelve of them at every frequency, because Euler's formula says so. Turn the frequency knob and watch the cell count climb by 10fΒ² + 2 while the pentagon count never moves.

What that buys is uniformity. Every cell has five or six neighbours, cells are close to the same size everywhere, and β€œdistance in tiles” is a real measurement β€” one tile is the mean angular spacing between adjacent centres. Everything downstream indexes a flat cell id and walks the neighbour graph, so terrain, ecology, weather and the divine powers all use the same three lines of traversal at the equator and at the pole.

The neighbours and the corners are stored cyclically, ordered by angle in each cell's own tangent plane. That is what lets the renderer fan a polygon out of them without sorting anything at draw time.

show

The engine's own buildHexSphere, drawn from its own corner rings. Drag to spin.

The land

Two noise fields, flattened into geography

Height is a 3D fractal noise sampled at each cell centre β€” 3D rather than 2D, because a noise field on a plane cannot wrap a sphere without a seam or a pinch. Five octaves at a feature scale of 2.6, which is roughly how many continents you get.

Raw fBm is a bell curve, and a bell curve makes a planet of endless mid-height mush. So the values are rank-normalised: sorted, and each cell given its position in the ordering. That forces a perfectly uniform distribution, which means the sea level is not a guess β€” it is a percentile, and the same fraction of the planet is ocean on every seed.

Then land is bent. Anything above sea level is raised to the power 2.4 within its remaining range, which keeps most land just above the water and makes mountains sporadic. Ocean depth is left linear, because nobody is looking at it.

Moisture is a second noise pass, equalised into five bands with target shares of 20% each β€” so deserts and rainforests both actually appear, instead of the whole planet drifting temperate. It then spreads inland from water over five cell-hops of falloff, which is what puts rainforest on coasts and desert in continental interiors without anything in the code mentioning either.

Biome is the intersection: a five-by-five matrix of elevation category against moisture category, plus two polar overrides driven by absolute latitude. Fourteen biomes, each with a colour and a fertility figure, and fertility is not decoration β€” it is the food supply the ecology eats.

The whole planet is a pure function of one integer. Two separate random streams run off it β€” one for the ecology, one for the settlements β€” so villages doing village things can never perturb the creatures' reproducible sequence.

Hands on

Try it

A real world, generated live and painted flat: every polygon is a hex cell, every colour is the biome the classifier assigned it. Roll another seed and watch the same rules produce a different planet.

generate

The actual World and BIOMES, imported by this page. Drag to spin. The 3D globe is one click away.

The ecology

A food web that stops eating itself

Every creature is a handful of numbers: which cell it is on, how much energy it has, how old it is and what species it belongs to. All the behaviour is data β€” the species table decides everything.

Vegetation is a real, depletable resource sitting on the fertility field. Grazers eat it down, it regrows, and a grazed cell stays bare for a timer's worth of ticks before it starts recovering. That single detail is what turns a herd into something that has to keep moving.

Getting that stable took three brakes, and each of them is commented in the source as a fix for a specific failure. Reproduction needs an energy threshold, so an animal must be genuinely well fed. It needs a cooldown β€” a minimum number of ticks between births for one individual β€” which is what turned runaway exponential growth into a paced, logistic rise. And even when both are satisfied there is a per-tick probability of actually breeding, which damps the boom further so the herbivores cannot strip the planet in two hundred ticks.

Coexistence needed one more idea. Two grazers on one food supply is a textbook case of competitive exclusion: the better one wins and the other goes extinct. So each herbivore carries a forage preference β€” a signed number that scales both how much it eats and what it gains, according to the fertility of the land it is standing on. One thrives in deep forest, the other on open scrub. They stop competing for the same cells, and both survive.

The predator has its own buffer: a separate, much lower metabolism while asleep, so it coasts through the lean early spell when prey is still establishing rather than starving before the food web forms.

None of these are simulation rules in any grand sense. They are five numbers per species, each one added because something went extinct without it.

Weather

The sky is a 128Γ—64 picture

All the weather in the world lives in one small equirectangular texture, 128 by 64 pixels, rebuilt every frame and sampled by the cloud shell and the cloud shadows alike β€” so the shadow on the ground always belongs to the cloud above it.

It is written in two layers. The first is climate bands: a per-latitude cloudiness profile with a cloudy equatorial belt, cloudy mid-latitude storm belts, and clear subtropical deserts, broken up by low-frequency 3D noise so it does not read as stripes. That layer is static for a given world and cached once.

The second is storms β€” at most four at a time β€” a managed set of cells that form, intensify, drift and dissipate, spawning preferentially where the bands are already cloudy. Each is stamped into the texture as a soft gaussian blob.

The clever part is the packing. Red is cloud density, and drives both the cloud shell and its shadow. Green is a storm mask, which is what gates rain in the shader. Blue is a transient lightning glow that lights the clouds and the surface beneath at night. One texture, three meanings, one upload a frame.

The divine powers write to the same world the weather does. Raising terrain moves the height field, bumps a version counter, and every renderer that cares re-displaces itself β€” there is no separate β€œedited” copy of the planet.

The bill

What this approach costs

A hex sphere with fields on it is a wonderfully uniform world model, and it is not a planet. Nearly everything here is a plausible-looking correlate of a real process rather than the process.

There is no tectonics, no erosion and no hydrology. Mountains are high noise raised to a power; rivers are carved downhill after the fact. Nothing in the terrain has a history, so a mountain range never runs along a plate boundary because there are no plates.

Climate is latitude and a noise field. Moisture spreads inland from water over a fixed number of cell-hops with no wind, no rain shadow and no ocean currents. It puts rainforest on coasts, which is often right, for a reason that is not the real one.

Rank-normalising fixes the histogram, not the shape. Forcing a uniform height distribution guarantees the right amount of ocean on every seed and guarantees nothing about whether the land is in interesting places. Some worlds come out as one blob and some as confetti.

The ecology is balanced by hand, per species. Every brake β€” threshold, cooldown, probability, forage niche, sleep metabolism β€” is a number tuned until the population curves stopped collapsing. It is stable because it was made stable, not because the model implies stability, and a new species means finding a new set of numbers.

Twelve pentagons are still twelve special cases. The grid hides them well β€” five neighbours instead of six, a padded slot in the array β€” but any rule that assumes six neighbours is wrong twelve times per planet, and always in the same twelve places.

Weather is painted, not simulated. There is no pressure, no air mass and no advection. Storms are gaussian blobs that drift and fade on timers inside latitude bands chosen to look like Earth's, and rain falls where a mask says it does.

Size is a real cost. The default world is nearly thirteen thousand cells, and every field is a typed array of that length; the population caps are scaled by world size specifically so the food web stays stable rather than because the ecology understands area.

The planet is a seed, two noise fields and a table of species traits. Everything that looks like geology or biology is a number chosen because the alternative looked wrong.

Open the planet β†—

Marcin β€” creator of vibespire.ai

About

Hi, I'm Marcin.

I build these experiments whenever something sparks my curiosity β€” a paper, a game, the way grass bends in the wind, the smallest everyday things. Inspiration shows up, and I chase it into a little living world you can open in a browser.

vibespire is where those experiments live. Poke at them, break them, read how they're made β€” and if something sparks an idea for you too, say hello.