Server-authoritative Godot 4.6 strategy game. Includes the headless WebSocket game server, the browser client, and Nix packaging (server and web-export derivations plus a NixOS module) for deployment.
105 lines
4.5 KiB
GDScript
105 lines
4.5 KiB
GDScript
class_name MapGenerationConfig
|
|
|
|
extends Resource
|
|
|
|
## Tunable parameters for the procedurally generated world map. The live
|
|
## values live in res://data/map_generation.tres and can be edited from the
|
|
## Godot inspector without touching any script.
|
|
|
|
## Map size in tiles. Tiles are generated around the origin, so a size of
|
|
## (27, 16) spans x = -13..13 and y = -8..7.
|
|
## A cylindrical map should use an even width so the wrapped rows line up.
|
|
@export var map_size : Vector2i = Vector2i(64, 40)
|
|
|
|
## How the map edges connect. FLAT is an open rectangle; CYLINDRICAL joins the
|
|
## east and west edges together so the world wraps around like the surface of
|
|
## a cylinder.
|
|
enum Topology { FLAT, CYLINDRICAL }
|
|
@export var topology : Topology = Topology.CYLINDRICAL
|
|
|
|
## Seed for the terrain noise. 0 uses a fresh random seed on every run.
|
|
@export var terrain_seed : int = 0
|
|
|
|
@export_group("Terrain")
|
|
## Noise value at or above which a tile becomes land.
|
|
@export_range(-1.0, 1.0) var sea_level : float = -0.2
|
|
|
|
## Push the map edges towards ocean so the playable land is an island.
|
|
@export var falloff_enabled : bool = true
|
|
## Normalised distance from the map centre where the falloff starts.
|
|
@export_range(0.0, 1.5) var falloff_start : float = 0.55
|
|
## How far the falloff lowers the noise at the map edges.
|
|
@export_range(0.0, 2.0) var falloff_strength : float = 0.6
|
|
|
|
## Distance from the equator, as a fraction of half the map height, beyond
|
|
## which every tile is replaced by the tileset's ice terrain. 0.9 freezes only
|
|
## the last few rows at each pole.
|
|
@export_range(0.0, 1.0) var ice_latitude : float = 0.9
|
|
|
|
@export_group("Noise")
|
|
@export var noise_type : FastNoiseLite.NoiseType = FastNoiseLite.TYPE_SIMPLEX_SMOOTH
|
|
@export_range(0.0001, 1.0, 0.0001) var frequency : float = 0.06
|
|
@export var fractal_type : FastNoiseLite.FractalType = FastNoiseLite.FRACTAL_FBM
|
|
@export_range(1, 8) var octaves : int = 4
|
|
@export_range(1.0, 4.0) var lacunarity : float = 2.0
|
|
@export_range(0.0, 1.0) var gain : float = 0.5
|
|
@export_range(0.0, 1.0) var fractal_weighted_strength : float = 0.0
|
|
@export var cellular_distance_function : FastNoiseLite.CellularDistanceFunction = FastNoiseLite.DISTANCE_EUCLIDEAN
|
|
@export var cellular_return_type : FastNoiseLite.CellularReturnType = FastNoiseLite.RETURN_DISTANCE
|
|
@export_range(0.0, 2.0) var cellular_jitter : float = 1.0
|
|
@export var domain_warp_enabled : bool = false
|
|
@export_range(0.0, 100.0) var domain_warp_amplitude : float = 30.0
|
|
@export_range(0.0, 1.0) var domain_warp_frequency : float = 0.05
|
|
@export var domain_warp_fractal_type : FastNoiseLite.DomainWarpFractalType = FastNoiseLite.DOMAIN_WARP_FRACTAL_PROGRESSIVE
|
|
|
|
@export_group("Capitals")
|
|
## Minimum number of tiles a capital is kept away from the map edge.
|
|
@export var capital_margin : int = 2
|
|
## Minimum distance (in tiles) between two capitals. If the land cannot
|
|
## satisfy this for every civilisation, the closest remaining sites are used.
|
|
@export_range(0.0, 64.0) var min_capital_distance : float = 8.0
|
|
## Capitals only spawn on land masses of at least this many tiles, so they
|
|
## never end up stranded on tiny islands. Falls back to the largest land mass
|
|
## when none reaches the threshold.
|
|
@export var min_capital_landmass : int = 40
|
|
|
|
@export_group("Cities")
|
|
## Number of cities each starting civilisation founds, including its capital.
|
|
@export var cities_per_civ : int = 10
|
|
## Minimum distance (in tiles) kept between the centres of any two cities.
|
|
@export var city_spacing : int = 8
|
|
|
|
@export_group("Tiles")
|
|
@export var tile_source_id : int = 5
|
|
@export var land_atlas_coords : Vector2i = Vector2i(3, 0)
|
|
@export var sea_atlas_coords : Vector2i = Vector2i(5, 0)
|
|
|
|
|
|
func is_cylindrical() -> bool:
|
|
return topology == Topology.CYLINDRICAL
|
|
|
|
|
|
func make_topology() -> MapTopology:
|
|
var topology_type := MapTopology.Type.CYLINDRICAL if is_cylindrical() else MapTopology.Type.FLAT
|
|
return MapTopology.new(map_size, topology_type)
|
|
|
|
|
|
func create_noise(seed_value: int) -> FastNoiseLite:
|
|
var noise := FastNoiseLite.new()
|
|
noise.seed = seed_value
|
|
noise.noise_type = noise_type
|
|
noise.frequency = frequency
|
|
noise.fractal_type = fractal_type
|
|
noise.fractal_octaves = octaves
|
|
noise.fractal_lacunarity = lacunarity
|
|
noise.fractal_gain = gain
|
|
noise.fractal_weighted_strength = fractal_weighted_strength
|
|
noise.cellular_distance_function = cellular_distance_function
|
|
noise.cellular_return_type = cellular_return_type
|
|
noise.cellular_jitter = cellular_jitter
|
|
noise.domain_warp_enabled = domain_warp_enabled
|
|
noise.domain_warp_amplitude = domain_warp_amplitude
|
|
noise.domain_warp_frequency = domain_warp_frequency
|
|
noise.domain_warp_fractal_type = domain_warp_fractal_type
|
|
return noise
|