just making sure the repo is up to date

This commit is contained in:
2025-11-28 19:17:59 -06:00
parent 4871a4ed3e
commit 454124a90a
2 changed files with 205 additions and 185 deletions

BIN
game/game

Binary file not shown.

View File

@@ -1,227 +1,247 @@
#+feature dynamic-literals
package game package game
import "core:math/noise"
import "core:math"
import "core:fmt" import "core:fmt"
import "core:math"
import "core:math/noise"
BIOME_SCALE : f64 : 1 BIOME_SCALE: f64 : 1
biome_list := map[u32]Biome { biome_list := map[u32]Biome {
0 = grasslands_biome, 0 = grasslands_biome,
1 = forest_biome, 1 = forest_biome,
2 = desert_biome, 2 = desert_biome,
3 = lake_biome, 3 = lake_biome,
} }
BiomeType :: enum { BiomeType :: enum {
GRASSLAND, GRASSLAND,
FOREST, FOREST,
LAKE, LAKE,
DESERT, DESERT,
} }
Biome :: struct { Biome :: struct {
id:u32, id: u32,
name: string, name: string,
type: BiomeType, type: BiomeType,
fauna_color: [4]u8, fauna_color: [4]u8,
valid_structures: [dynamic]u32 valid_structures: [dynamic]u32,
} }
// Define biome constants // Define biome constants
grasslands_biome := Biome { grasslands_biome := Biome {
id = 0, id = 0,
name = "Grasslands", name = "Grasslands",
type = .GRASSLAND, type = .GRASSLAND,
fauna_color = {50, 120, 25, 255}, fauna_color = {50, 120, 25, 255},
valid_structures = {} valid_structures = {},
} }
forest_biome := Biome { forest_biome := Biome {
id = 1, id = 1,
name = "Forest", name = "Forest",
type = .FOREST, type = .FOREST,
fauna_color = {30, 80, 20, 255}, fauna_color = {30, 80, 20, 255},
valid_structures = {} valid_structures = {},
} }
desert_biome := Biome { desert_biome := Biome {
id = 2, id = 2,
name = "Desert", name = "Desert",
type = .DESERT, type = .DESERT,
fauna_color = {200, 180, 100, 255}, fauna_color = {200, 180, 100, 255},
valid_structures = {} valid_structures = {},
} }
lake_biome := Biome { lake_biome := Biome {
id = 3, id = 3,
name = "Lake", name = "Lake",
type = .LAKE, type = .LAKE,
fauna_color = {0, 50, 150, 255}, fauna_color = {0, 50, 150, 255},
valid_structures = {} valid_structures = {},
} }
get_biome_from_id :: proc(id:u32) -> Biome { get_biome_from_id :: proc(id: u32) -> Biome {
return biome_list[id] return biome_list[id]
} }
get_biome_type :: proc(world_pos: Vec2i, seed: i64) -> Biome { get_biome_type :: proc(world_pos: Vec2i, seed: i64) -> Biome {
// Use multiple noise scales for different features // Use multiple noise scales for different features
continent_scale := 0.0008 // Very large scale features (continents) continent_scale := 0.0008 // Very large scale features (continents)
region_scale := 0.007 // Medium scale features (regions) region_scale := 0.007 // Medium scale features (regions)
local_scale := 0.025 // Local variations local_scale := 0.025 // Local variations
// Use different seed offsets for each noise layer // Use different seed offsets for each noise layer
continent_seed := seed continent_seed := seed
region_seed := seed + 10000 region_seed := seed + 10000
moisture_seed := seed + 20000 moisture_seed := seed + 20000
temperature_seed := seed + 30000 temperature_seed := seed + 30000
// Generate base continent shapes // Generate base continent shapes
continent := noise.noise_2d(continent_seed, {f64(world_pos.x) * continent_scale, f64(world_pos.y) * continent_scale}) continent := noise.noise_2d(
// Amplify to get more defined continents continent_seed,
continent = math.pow(continent * 0.5 + 0.5, 1.5) * 2.0 - 1.0 {f64(world_pos.x) * continent_scale, f64(world_pos.y) * continent_scale},
)
// Generate regional variations // Amplify to get more defined continents
region := noise.noise_2d(region_seed, {f64(world_pos.x) * region_scale, f64(world_pos.y) * region_scale}) continent = math.pow(continent * 0.5 + 0.5, 1.5) * 2.0 - 1.0
// Generate moisture and temperature maps for biome determination // Generate regional variations
moisture := noise.noise_2d(moisture_seed, {f64(world_pos.x) * region_scale, f64(world_pos.y) * region_scale}) region := noise.noise_2d(
temperature := noise.noise_2d(temperature_seed, {f64(world_pos.x) * region_scale, f64(world_pos.y) * region_scale}) region_seed,
{f64(world_pos.x) * region_scale, f64(world_pos.y) * region_scale},
// Adjust temperature to create larger hot regions )
// This skews the distribution to have more areas with higher temperature
// temperature = math.pow(temperature * 0.5 + 0.5, 0.8) * 2.0 - 1.0 // Generate moisture and temperature maps for biome determination
moisture := noise.noise_2d(
// Local variations (small details) moisture_seed,
local_var := noise.noise_2d(seed, {f64(world_pos.x) * local_scale, f64(world_pos.y) * local_scale}) * 0.1 {f64(world_pos.x) * region_scale, f64(world_pos.y) * region_scale},
)
// Combine all factors with proper weighting temperature := noise.noise_2d(
elevation := continent * 0.7 + region * 0.3 + local_var temperature_seed,
{f64(world_pos.x) * region_scale, f64(world_pos.y) * region_scale},
// Convert noise values to 0-1 range for easier thresholding )
normalized_elevation := elevation * 0.5 + 0.5
normalized_moisture := moisture * 0.5 + 0.5 // Adjust temperature to create larger hot regions
normalized_temperature := temperature * 0.5 + 0.5 // This skews the distribution to have more areas with higher temperature
// temperature = math.pow(temperature * 0.5 + 0.5, 0.8) * 2.0 - 1.0
if normalized_elevation < 0.3 {
return lake_biome // Local variations (small details)
} local_var :=
noise.noise_2d(seed, {f64(world_pos.x) * local_scale, f64(world_pos.y) * local_scale}) *
if normalized_temperature > 0.7 && normalized_moisture < 0.2 { 0.1
return desert_biome
} // Combine all factors with proper weighting
elevation := continent * 0.7 + region * 0.3 + local_var
// Forests need moderate to high moisture
if normalized_moisture > 0.55 { // Convert noise values to 0-1 range for easier thresholding
return forest_biome normalized_elevation := elevation * 0.5 + 0.5
} normalized_moisture := moisture * 0.5 + 0.5
normalized_temperature := temperature * 0.5 + 0.5
// Default to grasslands
return grasslands_biome if normalized_elevation < 0.3 {
return lake_biome
}
if normalized_temperature > 0.7 && normalized_moisture < 0.2 {
return desert_biome
}
// Forests need moderate to high moisture
if normalized_moisture > 0.55 {
return forest_biome
}
// Default to grasslands
return grasslands_biome
} }
// Improved chunk generation that considers neighboring chunks // Improved chunk generation that considers neighboring chunks
generate_chunk :: proc(pos: Vec2i, seed: i64) -> Chunk { generate_chunk :: proc(pos: Vec2i, seed: i64) -> Chunk {
chunk := Chunk{position = pos} chunk := Chunk {
position = pos,
// Store the biome for this chunk for consistency }
chunk_center := Vec2i{pos.x * CHUNK_SIZE + CHUNK_SIZE/2, pos.y * CHUNK_SIZE + CHUNK_SIZE/2}
biome := get_biome_type(chunk_center, seed)
chunk.biome_id = biome.id
// Generate each tile, allowing for biome blending at edges // Store the biome for this chunk for consistency
for x in 0..<CHUNK_SIZE { chunk_center := Vec2i{pos.x * CHUNK_SIZE + CHUNK_SIZE / 2, pos.y * CHUNK_SIZE + CHUNK_SIZE / 2}
for y in 0..<CHUNK_SIZE { biome := get_biome_type(chunk_center, seed)
world_x := pos.x * CHUNK_SIZE + x chunk.biome_id = biome.id
world_y := pos.y * CHUNK_SIZE + y
world_pos := Vec2i{world_x, world_y} // Generate each tile, allowing for biome blending at edges
for x in 0 ..< CHUNK_SIZE {
// Check the tile's specific biome (for transitions) for y in 0 ..< CHUNK_SIZE {
tile_biome := get_biome_type(world_pos, seed) world_x := pos.x * CHUNK_SIZE + x
world_y := pos.y * CHUNK_SIZE + y
// Calculate distances to chunk edges for potential blending world_pos := Vec2i{world_x, world_y}
edge_dist_x := min(x, CHUNK_SIZE - 1 - x)
edge_dist_y := min(y, CHUNK_SIZE - 1 - y) // Check the tile's specific biome (for transitions)
edge_dist := min(edge_dist_x, edge_dist_y) tile_biome := get_biome_type(world_pos, seed)
// Blend between chunk biome and tile biome near edges // Calculate distances to chunk edges for potential blending
// for smoother transitions between chunks edge_dist_x := min(x, CHUNK_SIZE - 1 - x)
biome_to_use := biome edge_dist_y := min(y, CHUNK_SIZE - 1 - y)
if edge_dist < 4 { // Within 4 tiles of chunk edge edge_dist := min(edge_dist_x, edge_dist_y)
blend_factor := f32(edge_dist) / 4.0
// Blend between chunk biome and tile biome near edges
// Simple way to blend biomes - just pick one based on blend factor // for smoother transitions between chunks
// For a more sophisticated approach, you could actually blend features biome_to_use := biome
if hash_noise(world_x, world_y, seed) > blend_factor { if edge_dist < 4 { // Within 4 tiles of chunk edge
biome_to_use = tile_biome blend_factor := f32(edge_dist) / 4.0
}
} // Simple way to blend biomes - just pick one based on blend factor
// For a more sophisticated approach, you could actually blend features
chunk.tiles[x][y] = generate_tile(world_pos, seed, biome_to_use) if hash_noise(world_x, world_y, seed) > blend_factor {
} biome_to_use = tile_biome
} }
}
return chunk
chunk.tiles[x][y] = generate_tile(world_pos, seed, biome_to_use)
}
}
return chunk
} }
// Improved tile generation with biome transition support // Improved tile generation with biome transition support
generate_tile :: proc(pos: Vec2i, seed: i64, biome: Biome) -> Tile { generate_tile :: proc(pos: Vec2i, seed: i64, biome: Biome) -> Tile {
hash_value := hash_noise(pos.x, pos.y, seed) hash_value := hash_noise(pos.x, pos.y, seed)
// Use multiple noise scales for natural-looking features
large_scale := 0.025
medium_scale := 0.07
small_scale := 0.20
large_noise := noise.noise_2d(seed, {f64(pos.x) * large_scale, f64(pos.y) * large_scale})
medium_noise := noise.noise_2d(seed + 5000, {f64(pos.x) * medium_scale, f64(pos.y) * medium_scale})
small_noise := noise.noise_2d(seed + 10000, {f64(pos.x) * small_scale, f64(pos.y) * small_scale})
// Combine noise at different scales
combined_noise := large_noise * 0.6 + medium_noise * 0.3 + small_noise * 0.1
// Different biomes use the noise differently
switch biome.type {
case .GRASSLAND:
if combined_noise > 0.8 {
return tree_tile
} else if combined_noise > 0.2 {
return grass_tile
} else {
return nothing_tile
}
case .FOREST:
if combined_noise > 0.75 {
return double_tree_tile
} else if combined_noise > 0.4 {
return tree_tile
} else if combined_noise > 0.0 {
return grass_tile
} else {
return nothing_tile
}
case .DESERT:
cactus_noise := medium_noise * 0.5 + 0.5 // Normalize to 0-1 // Use multiple noise scales for natural-looking features
large_scale := 0.025
medium_scale := 0.07
small_scale := 0.20
if cactus_noise > 0.8 && hash_value > 0.65 { large_noise := noise.noise_2d(seed, {f64(pos.x) * large_scale, f64(pos.y) * large_scale})
return cactus_tile medium_noise := noise.noise_2d(
} else if combined_noise > 0.85 { seed + 5000,
return dead_bush_tile {f64(pos.x) * medium_scale, f64(pos.y) * medium_scale},
} else { )
return nothing_tile small_noise := noise.noise_2d(
} seed + 10000,
case .LAKE: {f64(pos.x) * small_scale, f64(pos.y) * small_scale},
// Lakes can have different depths )
if combined_noise > 0.7 {
return shallow_water_tile // You'd need to define this // Combine noise at different scales
} else { combined_noise := large_noise * 0.6 + medium_noise * 0.3 + small_noise * 0.1
return water_tile
} // Different biomes use the noise differently
case: switch biome.type {
return nothing_tile case .GRASSLAND:
} if combined_noise > 0.8 {
return tree_tile
} else if combined_noise > 0.2 {
return grass_tile
} else {
return nothing_tile
}
case .FOREST:
if combined_noise > 0.75 {
return double_tree_tile
} else if combined_noise > 0.4 {
return tree_tile
} else if combined_noise > 0.0 {
return grass_tile
} else {
return nothing_tile
}
case .DESERT:
cactus_noise := medium_noise * 0.5 + 0.5 // Normalize to 0-1
if cactus_noise > 0.8 && hash_value > 0.65 {
return cactus_tile
} else if combined_noise > 0.85 {
return dead_bush_tile
} else {
return nothing_tile
}
case .LAKE:
// Lakes can have different depths
if combined_noise > 0.7 {
return shallow_water_tile // You'd need to define this
} else {
return water_tile
}
case:
return nothing_tile
}
} }