← All posts

Procedural Planet Generation in JavaScript: Noise & Voronoi Meshes

Learn how to build infinite procedural 2D planets in JavaScript using Perlin noise, Voronoi diagrams, and dynamic polygon meshes for browser games.

Procedural planet generation in JavaScript is the process of algorithmically creating round, explorable game worlds directly in the browser using mathematical functions instead of hand-crafted sprites. By combining coherent noise algorithms with Voronoi cell partitioning, browser game developers can generate infinite variations of terrain, biomes, and destructible 2D level meshes in real time.

If you have spent any time playing 2D orbital platformers, gravity-based roguelikes, or space exploration web games recently, you have likely marvelled at how smooth these miniature worlds look. Behind that polished finish lies a clever mix of trigonometry, noise, and computational geometry.


       [ Seed Value ] 
             β”‚
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β–Ό                   β–Ό
[ Simplex Noise ]   [ Voronoi Cells ]
(Elevation/Hills)   (Biomes/Tectonic Plates)
   β”‚                   β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β–Ό
   [ Radial Vertex Mesh ] ──► [ Canvas / WebGL Render ]

The Core Trio: Trigonometry, Noise, and Voronoi Cells

Building a round 2D planet from scratch requires three distinct computational layers working in unison:

1. Radial Mapping: Translating a one-dimensional array of height values into a closed circular polygon using polar coordinates (angle and radius).

2. Coherent Noise (Simplex / Perlin): Providing organic, continuous height variations so your planet has rolling hills, jagged peaks, and deep oceans rather than pure static fuzz.

3. Voronoi Tiling: Splitting the circular surface into discrete regional cells for distinct biomes (such as volcanic crags, crystal forests, or subterranean caverns).

Why Pure Randomness Fails

Using standard Math.random() produces disconnected, jagged spikes resembling an angry audio waveform. Coherent noise ensures that adjacent vertices on your planet mesh share mathematically related elevations, yielding natural hills and valleys.


Step 1: Generating the Radial Mesh with Noise

To construct a basic 2D planetary crust, we divide a full circle ($2\pi$ radians) into discrete slices (steps), sample a noise value at each step, and convert the resulting polar coordinates back into Cartesian coordinates $(x, y)$.

Here is a lean implementation demonstrating this in vanilla JavaScript:


// Procedural 2D Planet Mesh Generator
function createPlanetMesh(centerX, centerY, baseRadius, segments, noiseScale, seed) {
  const vertices = [];
  const angleStep = (Math.PI * 2) / segments;

  for (let i = 0; i < segments; i++) {
    const angle = i * angleStep;
    
    // Convert polar angle to a 2D sample point for looping noise
    const sampleX = Math.cos(angle) * noiseScale + seed;
    const sampleY = Math.sin(angle) * noiseScale + seed;
    
    // Basic pseudo-noise sampling (replace with Simplex / FastNoise)
    const elevation = Math.sin(sampleX * 4) * Math.cos(sampleY * 4) * 25;
    const totalRadius = baseRadius + elevation;

    const x = centerX + Math.cos(angle) * totalRadius;
    const y = centerY + Math.sin(angle) * totalRadius;

    vertices.push({ x, y, angle, radius: totalRadius });
  }

  return vertices;
}

Because the noise coordinate space loops smoothly as the angle sweeps from $0$ to $2\pi$, the resulting polygon closes seamlessly without an awkward visual seam at the junction.


Step 2: Adding Biomes with Voronoi Cells

While noise controls height, Voronoi diagrams dictate character. Voronoi partitioning places a scatter of seed points across the planet's circumference. Every point on the surface belongs to whichever seed point is nearest.

In browser development, Voronoi diagrams provide two massive benefits:

  • Tectonic & Biome Distribution: They naturally group sectors of the circular crust into deserts, tundra, or toxic sludge without manual painting.
  • Destructible Mining Nodes: If your game allows players to blast chunks out of the planet, removing entire Voronoi polygons produces believable, angular fracture lines rather than artificial square cutouts.

Comparing Procedural Techniques for Browser Engines

Choosing the right procedural algorithm depends directly on your performance budget and target frame rate on mobile web browsers:

AlgorithmComputational CostVisual QualityBest Use Case in 2D Web Games
Value NoiseVery LowLow (blocky transitions)Retro pixel-art celestial bodies
Perlin NoiseModerateSmooth, organic curvesBase terrain contours and sea-level depth
Simplex NoiseLow–ModerateHigh (fewer directional artefacts)High-speed, real-time infinite world generation
Voronoi / WorleyModerate–HighSharp, cellular segmentsBiomes, destructible mineral veins, caves
Marching SquaresHighDynamic iso-surfacesFully deformable, subterranean 2D caverns

Handling 2D Radial Gravity and Physics

Once your procedural planet exists as a dynamic vertex loop, standard downward physics (velocity.y += gravity) stops working.

To implement radial physics:

  • Attraction Vector: For any player or projectile at position $(p_x, p_y)$, calculate the angle to the planet centre $(c_x, c_y)$ using Math.atan2(c_y - p_y, c_x - p_x).
  • Surface Alignment: Rotate the player sprite's transform matrix to match the normal angle of the nearest planet polygon edge.
  • Raycast Snapping: Check the distance from the player to the planet centre against the interpolated radius of the nearest two mesh vertices to prevent clipping through procedural crusts.

Practical Takeaways for Web Game Developers

  • Pre-generate Collision Buffers: Avoid calculating noise on every animation frame. Generate the vertex array once, store it in an ArrayBuffer or Float32Array, and only recalculate local segments when cratering terrain.
  • Keep Mesh Resolutions Sensible: Between 120 and 250 vertices are typically plenty for smooth circular contours on standard mobile displays without bogging down canvas redraw routines.
  • Layer Multiple Noise Octaves: Combine low-frequency noise (for broad continental shelves) with high-frequency, low-amplitude noise (for surface crags) to give your planets instant visual depth.

Thanks for reading. Browse more from the Wobblox blog, or jump straight into all 100 free games.