class_name WorldGenerator const CHUNK_SIZE: int = 16 static func generate_chunk(chunk_x: int, chunk_y: int, chunk_z: int, seed: int) -> PackedInt32Array: var data: PackedInt32Array = PackedInt32Array() data.resize(4096) var noise_surface: FastNoiseLite = FastNoiseLite.new() noise_surface.seed = seed noise_surface.noise_type = FastNoiseLite.TYPE_SIMPLEX_SMOOTH noise_surface.frequency = 0.015 var noise_biome: FastNoiseLite = FastNoiseLite.new() noise_biome.seed = seed + 1337 noise_biome.noise_type = FastNoiseLite.TYPE_SIMPLEX_SMOOTH noise_biome.frequency = 0.004 var noise_detail: FastNoiseLite = FastNoiseLite.new() noise_detail.seed = seed + 42 noise_detail.noise_type = FastNoiseLite.TYPE_SIMPLEX_SMOOTH noise_detail.frequency = 0.05 var noise_wreck: FastNoiseLite = FastNoiseLite.new() noise_wreck.seed = seed + 999 noise_wreck.noise_type = FastNoiseLite.TYPE_CELLULAR noise_wreck.frequency = 0.03 for lx: int in range(CHUNK_SIZE): for lz: int in range(CHUNK_SIZE): var wx: int = chunk_x * CHUNK_SIZE + lx var wz: int = chunk_z * CHUNK_SIZE + lz var surface_val: float = noise_surface.get_noise_2d(float(wx), float(wz)) var ground_height: int = int(-20.0 + surface_val * 20.0) var biome_val: float = noise_biome.get_noise_2d(float(wx), float(wz)) var biome: int = _get_biome(biome_val, ground_height) var wreck_val: float = noise_wreck.get_noise_2d(float(wx), float(wz)) var is_wreck_center: bool = wreck_val > 0.75 for ly: int in range(CHUNK_SIZE): var wy: int = chunk_y * CHUNK_SIZE + ly var idx: int = lx + ly * CHUNK_SIZE + lz * 256 data[idx] = _get_block_at(wy, ground_height, biome, wx, wz, lx, lz, is_wreck_center, noise_detail, seed) return data static func _get_biome(biome_val: float, ground_height: int) -> int: if biome_val > 0.5: return 0 elif biome_val > 0.0: return 1 elif biome_val > -0.5: return 2 else: return 3 static func _get_block_at(wy: int, ground_height: int, biome: int, wx: int, wz: int, lx: int, lz: int, is_wreck_center: bool, noise_detail: FastNoiseLite, seed: int) -> int: if wy <= -60: return BlockDatabase.BlockType.BEDROCK if wy < ground_height - 5: return BlockDatabase.BlockType.ROCK if wy < ground_height: return BlockDatabase.BlockType.SAND if wy == ground_height: return _surface_block(biome, wx, wz, noise_detail) if wy == ground_height + 1: return _decoration_block(biome, wx, wz, noise_detail, seed) if wy > ground_height + 1 and wy <= ground_height + 6: if biome == 1: var kelp_height: int = _kelp_height(wx, wz, seed) if wy <= ground_height + kelp_height: return BlockDatabase.BlockType.KELP if wy > 60: return BlockDatabase.BlockType.AIR if wy >= 58: var ice_noise: float = noise_detail.get_noise_2d(float(wx) * 0.5, float(wz) * 0.5) if ice_noise > 0.6: return BlockDatabase.BlockType.ICE return BlockDatabase.BlockType.WATER if wy > ground_height: if is_wreck_center and biome == 3: var rel_y: int = wy - ground_height - 1 if rel_y >= 0 and rel_y < 3: var rel_x: int = (wx % 5 + 5) % 5 var rel_z: int = (wz % 3 + 3) % 3 if rel_x < 5 and rel_z < 3: if rel_y == 0 or rel_y == 2 or rel_x == 0 or rel_x == 4 or rel_z == 0 or rel_z == 2: return BlockDatabase.BlockType.WRECK_WOOD return BlockDatabase.BlockType.WATER return BlockDatabase.BlockType.WATER static func _surface_block(biome: int, wx: int, wz: int, noise_detail: FastNoiseLite) -> int: match biome: 0: return BlockDatabase.BlockType.SAND 1: return BlockDatabase.BlockType.SAND 2: return BlockDatabase.BlockType.ROCK 3: return BlockDatabase.BlockType.SAND _: return BlockDatabase.BlockType.SAND static func _decoration_block(biome: int, wx: int, wz: int, noise_detail: FastNoiseLite, seed: int) -> int: match biome: 0: var coral_noise: float = noise_detail.get_noise_2d(float(wx + seed % 100), float(wz + seed % 100)) if coral_noise > 0.4: if (wx + wz) % 2 == 0: return BlockDatabase.BlockType.CORAL_RED else: return BlockDatabase.BlockType.CORAL_BLUE _: pass return BlockDatabase.BlockType.WATER static func _kelp_height(wx: int, wz: int, seed: int) -> int: var h: int = ((wx * 73856093) ^ (wz * 19349663) ^ seed) % 4 return 3 + h