Categories
Rust

World generation

Let’s create a 2d grid world using tiles for the player to explore. First, we create a struct for the world containing a seed, width and height, a bool if it should wrap around, and a tile grid.

pub struct World {
    pub seed: u64,
    pub width: usize,
    pub height: usize,
    pub wraparound: bool,
    pub tiles: TileGrid,
}
pub type TileGrid = Vec<Vec<Tile>>;

Our tile struct contains a height value, type of terrain, an optional feature location which could be a town, farm, mine, dungeon etc, a bool if it’s blocked and a bool if the player has visited this tile.

#[derive(Clone)]
pub struct Tile {
    pub height: f32,
    pub terrain: TerrainType,
    pub location: Option<Location>,
    pub blocked: bool,
    pub seen: bool,
}

We want to generate worlds using deterministic random noise. For simplicity, I’ve imported a perlin generator which is in noise = “0.8”. Here’s the generator struct.

pub struct WorldGenerator {
    height_noise: Perlin,
    mountain_noise: Perlin,
    temperature_noise: Perlin,
    moisture_noise: Perlin,
    river_noise: Perlin,
    size: usize,
    rng: StdRng,
}

The first noise map is a height map. I only use this to decide what is ocean and what is land at this point. Temperature and moisture noise are then used to place biome tiles.

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TerrainType {
    Water,
    Plains,
    Forest,
    Mountains,
    Desert,
    Snow,
    Jungle,
    Swamp,
}