Skip to content

Server & map generation

Overview

The server (src/server/) provides a Node.js API for procedural map generation. The client fetches terrain via HTTP; Vite proxies /api to the server during development.

Flow

Client (MapGenerator)  →  GET /api/map?width=256&height=256&seed=12345
Vite proxy (/api → localhost:3000)
Server (Express)  →  MapGeneratorService  →  NoiseMapGenerator (or fallback)
Response: { success, width, height, seed, tiles: [{ x, y, type, elevation }] }

API

Endpoints

Endpoint Method Description
/health GET Health check: { status: "ok", timestamp }
/api/map GET Generate terrain tiles

Map generation

Request: GET /api/map?width=256&height=256&seed=12345

Query param Type Default Description
width number 256 Map width (tiles)
height number 256 Map height (tiles)
seed number random Seed for deterministic generation

Response:

{
  "success": true,
  "width": 256,
  "height": 256,
  "seed": 12345,
  "tiles": [
    { "x": 0, "y": 0, "type": "grass", "elevation": 180 },
    { "x": 1, "y": 0, "type": "sand", "elevation": 95 }
  ]
}

Terrain types

Type Description
deep_water Ocean (terrainNoise < 0.2)
shallow_water Sea (0.2–0.4)
sand Beach (0.4–0.45)
grass Grassland (0.45–0.6)
stone Rocky (0.6+, variant)
mountain Mountain (0.6+, variant)

Components

MapGeneratorService (src/server/services/MapGeneratorService.ts)

  • Uses NoiseMapGenerator by default (custom Open Simplex Noise)
  • Fallback: @reldens/tile-map-generator or simple deterministic pattern
  • Output: GeneratedTile[] with x, y, type, elevation

NoiseMapGenerator (src/server/services/NoiseMapGenerator.ts)

  • Open Simplex Noise (multi-octave) for elevation and moisture
  • Border gradient – edges fade to water for natural island shape
  • Variant noise – sub-types (wet/dry sand, stone/mountain)
  • Config: frequency, octaves, persistence, blur

Client MapGenerator (src/sim/core/MapGenerator.ts)

  • Fetches from /api/map (Vite proxy → server)
  • Fallback: local simple pattern if API fails
  • Used by IsometricMap.generateMap() when starting a new game

Vite proxy

In development, vite.config.ts proxies /api to http://localhost:3000:

proxy: {
  '/api': { target: 'http://localhost:3000', changeOrigin: true }
}

So fetch('/api/map?width=256&height=256') goes to the Node server.

Running

  • Dev: npm run dev – Vite + API server together (or docker compose up dev)
  • API only: Server listens on port 3000 (configurable via PORT env)