From 80e4008ac6e013f8d485b6f1ae5496faa656f3d4 Mon Sep 17 00:00:00 2001 From: copygirl Date: Tue, 30 Sep 2025 19:01:29 +0200 Subject: [PATCH] Improve GeneratorSimple's terrain shape --- world/generation/generator_simple.gd | 246 +++++++++++++++++++++++---- 1 file changed, 214 insertions(+), 32 deletions(-) diff --git a/world/generation/generator_simple.gd b/world/generation/generator_simple.gd index 091f44f..db0e752 100644 --- a/world/generation/generator_simple.gd +++ b/world/generation/generator_simple.gd @@ -4,7 +4,7 @@ extends RefCounted const NAME := "simple" var noise := FastNoiseLite.new() -var array := PackedFloat32Array() +var array := PackedByteArray() var bias_air := 0.0 # Above this, always air var bias_solid := 64.0 # Below this, always solid @@ -17,42 +17,224 @@ func _init() -> void: noise.fractal_lacunarity = 2.5 noise.fractal_octaves = 3 - array.resize((Chunk.SIZE + 1) * (Chunk.SIZE + 1)) + array.resize((Chunk.SIZE + 4) * (Chunk.SIZE + 4)) func generate(world: World, chunk: Chunk) -> void: + const THRESHOLD := 0.5 + var region := chunk.region.extend(2) + var i := 0 - for y in Chunk.SIZE + 1: - for x in Chunk.SIZE + 1: - var local_pos := Vector2i(x, y) - var block_pos := (chunk.chunk_pos * Chunk.SIZE) + local_pos - var bias := (block_pos.y - bias_air) / (bias_solid - bias_air) - array[i] = noise.get_noise_2dv(Vector2(block_pos)) + bias - i += 1 + for pos in region: + var bias := (pos.y - bias_air) / (bias_solid - bias_air) + array[i] = int((noise.get_noise_2dv(Vector2(pos)) + bias) >= THRESHOLD) + i += 1 var matter: Matter.Layer = chunk.get_or_create_layer(Matter) var shapes: Shape.Layer = chunk.get_or_create_layer(Shape) - for local_pos in BlockRegion.LOCAL_CHUNK: + for pos in BlockRegion.LOCAL_CHUNK: var shape: Shape - match _values(local_pos): - [ true, true, true, true ]: shape = Shape.FULL - [ false, true, true, true ]: shape = Shape.Base.SLOPE.variants[0] - [ true, false, true, true ]: shape = Shape.Base.SLOPE.variants[2] - [ true, true, false, true ]: shape = Shape.Base.SLOPE.variants[3] - [ true, true, true, false ]: shape = Shape.Base.SLOPE.variants[1] - [ false, false, true, true ]: shape = Shape.Base.HALF.variants[0] - [ true, false, false, true ]: shape = Shape.Base.HALF.variants[2] - [ true, true, false, false ]: shape = Shape.Base.HALF.variants[3] - [ false, true, true, false ]: shape = Shape.Base.HALF.variants[1] + + var a := array + const W := (Chunk.SIZE + 4) + i = (pos.x + 2) + (pos.y + 2) * W + + var values: Array[int] = [ + a[i-2-W*2], a[i-1-W*2], a[i-W*2], a[i+1-W*2], a[i+2-W*2], + a[i-2-W ], a[i-1-W ], a[i-W ], a[i+1-W ], a[i+2-W ], + a[i-2 ], a[i-1 ], a[i ], a[i+1 ], a[i+2 ], + a[i-2+W ], a[i-1+W ], a[i+W ], a[i+1+W ], a[i+2+W ], + a[i-2+W*2], a[i-1+W*2], a[i+W*2], a[i+1+W*2], a[i+2+W*2], + ] + + # TODO: Implement custom pattern matching that can handle rotation and mirroring. + # var x := -1 + # var pattern: Array[int] = [ + # x, x, x, x, x, + # x, x, 0, 0, 0, + # x, 0, 0, 1, 1, + # x, 1, 1, 1, x, + # x, x, x, x, x, + # ] + + match values: + # HALF_SLOPE (non-mirrored) + [ + _, _, _, _, _, + _, _, 0, 0, 0, + _, 0, 0, 1, 1, + _, 1, 1, 1, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[0] + [ + _, 0, 1, _, _, + _, 0, 1, 1, _, + _, 0, 0, 1, _, + _, _, 0, 1, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[1] + [ + _, _, _, _, _, + _, 1, 1, 1, _, + 1, 1, 0, 0, _, + 0, 0, 0, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[2] + [ + _, _, _, _, _, + _, 1, 0, _, _, + _, 1, 0, 0, _, + _, 1, 1, 0, _, + _, _, 1, 0, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[3] + + [ + _, _, _, _, _, + _, 0, 0, 0, _, + 0, 0, 1, 1, _, + 1, 1, 1, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[0] + [ + _, _, _, _, _, + _, 0, 1, _, _, + _, 0, 1, 1, _, + _, 0, 0, 1, _, + _, _, 0, 1, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[1] + [ + _, _, _, _, _, + _, _, 1, 1, 1, + _, 1, 1, 0, 0, + _, 0, 0, 0, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[2] + [ + _, 1, 0, _, _, + _, 1, 0, 0, _, + _, 1, 1, 0, _, + _, _, 1, 0, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[3] + + # HALF_SLOPE (mirrored) + [ + _, _, _, _, _, + 0, 0, 0, _, _, + 1, 1, 0, 0, _, + _, 1, 1, 1, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[4] + [ + _, _, _, _, _, + _, _, 0, 1, _, + _, 0, 0, 1, _, + _, 0, 1, 1, _, + _, 0, 1, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[5] + [ + _, _, _, _, _, + _, 1, 1, 1, _, + _, 0, 0, 1, 1, + _, _, 0, 0, 0, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[6] + [ + _, _, 1, 0, _, + _, 1, 1, 0, _, + _, 1, 0, 0, _, + _, 1, 0, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE.variants[7] + + [ + _, _, _, _, _, + _, 0, 0, 0, _, + _, 1, 1, 0, 0, + _, _, 1, 1, 1, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[4] + [ + _, _, 0, 1, _, + _, 0, 0, 1, _, + _, 0, 1, 1, _, + _, 0, 1, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[5] + [ + _, _, _, _, _, + 1, 1, 1, _, _, + 0, 0, 1, 1, _, + _, 0, 0, 0, _, + _, _, _, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[6] + [ + _, _, _, _, _, + _, _, 1, 0, _, + _, 1, 1, 0, _, + _, 1, 0, 0, _, + _, 1, 0, _, _, + ]: + shape = Shape.Base.HALF_SLOPE_BIG.variants[7] + + # SLOPE + [ + _, _, _, _, _, + _, _, 0, _, _, + _, 0, 0, 1, _, + _, _, 1, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.SLOPE.variants[0] + [ + _, _, _, _, _, + _, _, 1, _, _, + _, 0, 0, 1, _, + _, _, 0, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.SLOPE.variants[1] + [ + _, _, _, _, _, + _, _, 1, _, _, + _, 1, 0, 0, _, + _, _, 0, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.SLOPE.variants[2] + [ + _, _, _, _, _, + _, _, 0, _, _, + _, 1, 0, 0, _, + _, _, 1, _, _, + _, _, _, _, _, + ]: + shape = Shape.Base.SLOPE.variants[3] + + # FULL + [ + _, _, _, _, _, + _, _, _, _, _, + _, _, 1, _, _, + _, _, _, _, _, + _, _, _, _, _, + ]: + shape = Shape.FULL + if shape: - matter.set_at(local_pos, Matter.PLASTIC) - shapes.set_at(local_pos, shape) - -func _values(pos: Vector2i) -> Array[bool]: - return [ - _v(pos, 0, 0) >= 0.5, - _v(pos, 1, 0) >= 0.5, - _v(pos, 1, 1) >= 0.5, - _v(pos, 0, 1) >= 0.5, - ] -func _v(pos: Vector2i, x: float, y: float) -> float: - return array[(pos.x + x) + (pos.y + y) * (Chunk.SIZE + 1)] + matter.set_at(pos, Matter.PLASTIC) + shapes.set_at(pos, shape)