Compare commits

...

18 Commits

Author SHA1 Message Date
MC-Worldgen Dev
0a06f34d99 Tune tree density/spacing and fix trail distance to use segments
- nearest_trail_distance2 now measures point-to-segment distance to each
  trail edge instead of only to stored points, with a single-point fallback.
- Tree height scaling keeps canopy proportions; maturity adds subtle
  variation instead of shrinking young trees to bare poles.
- Raise forest spawn probability and tighten spacing for denser, more
  coherent stands; redwoods cluster a bit closer.
- Cabins near trails favor a wooded setback off the centerline; the spur
  still connects.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-11 20:33:21 +00:00
root
e2436f6e24 Improve roads, cabins, forests, and woodland communities 2026-07-11 20:00:19 +00:00
chelsea
afbf333622 Add subtle island terrain relief 2026-05-03 11:58:59 -05:00
chelsea
acd5eaa52f Add dry sand patches near beaches 2026-05-03 11:53:07 -05:00
chelsea
84a0435312 Place wall stairs above walkway surface 2026-05-03 11:39:35 -05:00
chelsea
46f1d24e9d Add stair ramps to border wall walks 2026-05-03 11:32:22 -05:00
chelsea
aed76c3b1b Add dead sequoias and align tower walks 2026-05-03 01:22:38 -05:00
chelsea
95bd106a3b Fix generated map integrity and wall access 2026-05-02 23:48:35 -05:00
chelsea
127e706bcb Fix wall rails and water biomes 2026-05-02 23:23:29 -05:00
chelsea
335b35d416 Add plant and aquatic variety 2026-05-02 23:18:00 -05:00
chelsea
d0f3c9a048 Address border wall issue reports 2026-05-02 21:54:12 -05:00
chelsea
f93ebff0b9 Refine wall base and ladder access 2026-05-02 20:59:38 -05:00
chelsea
17c9634c0f Add wall exteriors and interior access 2026-05-02 20:30:12 -05:00
chelsea
32d2b09b9f Make border wall brutalist 2026-05-02 20:07:38 -05:00
chelsea
f423c046ac Add generated area border wall option 2026-05-02 19:26:44 -05:00
chelsea
1addbada63 Speed up terrain generation 2026-05-02 19:03:57 -05:00
chelsea
d5fd7e6bb5 Add broad buildable flatlands 2026-05-02 17:32:16 -05:00
chelsea
7861ab63f0 Improve redwood titan shape 2026-05-02 17:28:54 -05:00
6 changed files with 1231 additions and 156 deletions

View File

@@ -64,6 +64,7 @@ Useful options:
- `--sea-level L`: sea level, default `70`. - `--sea-level L`: sea level, default `70`.
- `--snow-line H`: snow threshold, default `sea-level + 38`. - `--snow-line H`: snow threshold, default `sea-level + 38`.
- `--trails`: enable trail and cabin prepass. - `--trails`: enable trail and cabin prepass.
- `--wall`: build a brutalist border wall around the generated area.
- `--format mca|bin`: write Minecraft region files or raw debug chunks. - `--format mca|bin`: write Minecraft region files or raw debug chunks.
- `--out DIR`: output directory. - `--out DIR`: output directory.
@@ -73,11 +74,30 @@ Features
- Redwoods are enabled automatically. The biome classifier marks high-rainfall, - Redwoods are enabled automatically. The biome classifier marks high-rainfall,
higher-relief areas as redwood forest, then places titan trees, dirt/mulch higher-relief areas as redwood forest, then places titan trees, dirt/mulch
floor cover, tall grass, and occasional fallen logs. floor cover, tall grass, and occasional fallen logs.
- General forests grow as broad, coherent oak, maple, birch, pine, spruce,
walnut, and cypress stands with occasional companion species. Seeded
clearings, sparse field trees, regenerating edges, mature interiors, variable
tree height, and irregular crown spacing keep the distribution from resolving
into a uniform grid.
- Cabins are enabled automatically. With `--trails`, cabins only try to spawn on - Cabins are enabled automatically. With `--trails`, cabins only try to spawn on
chunks crossed by the trail network so their spur paths can connect to roads. chunks crossed by the trail network so their spur paths can connect to roads.
Without `--trails`, cabins can still spawn, but they are rarer and unconnected. Without `--trails`, cabins can still spawn, but they are rarer and unconnected.
- Cabin generation includes compact homesteads, longhouses, two-story houses,
L-shaped cabins, cross-gabled lodges, mixed-height tower lodges, and rambling
multi-wing cabins. Roof direction, wing height, material palette, windows,
porches, chimneys, decay, and path width vary by design.
- Seeded woodland-community regions raise the local cabin frequency and give
their roads permission to bridge narrowly bounded water at exact sea level.
Eligible crossings must have nearby dry banks on both sides; deep water,
broad lakes, and open ocean remain impassable. Bridges use raised spruce
decks, timber supports, and intermittent edge posts rather than gravel fill.
- Trails are optional because they need a prepass over the target area. Use - Trails are optional because they need a prepass over the target area. Use
`--trails` when you want roads and better-connected cabins. `--trails` when you want roads and better-connected cabins.
- Long roads search a broad terrain corridor and prefer valley floors, gentle
contour-following grades, low ridge crossings, and stable side slopes. Deep
water remains impassable; shallow water is crossed only when the detour cost
is greater, keeping fords and causeways short. Short cabin spurs use looser
engineering constraints so they can still reach the main network.
Minecraft Version Minecraft Version
----------------- -----------------

Binary file not shown.

View File

@@ -7,6 +7,7 @@
#define CHUNK_SIZE 16 #define CHUNK_SIZE 16
#define CHUNK_HEIGHT 256 #define CHUNK_HEIGHT 256
#define WORLDGEN_HEIGHT_CACHE_SIZE 32768
enum BlockId { enum BlockId {
BLOCK_BEDROCK = 0, BLOCK_BEDROCK = 0,
@@ -52,7 +53,27 @@
BLOCK_LADDER_N = 40, BLOCK_LADDER_N = 40,
BLOCK_LADDER_S = 41, BLOCK_LADDER_S = 41,
BLOCK_LADDER_W = 42, BLOCK_LADDER_W = 42,
BLOCK_LADDER_E = 43 BLOCK_LADDER_E = 43,
BLOCK_SMOOTH_STONE = 44,
BLOCK_STONE_BRICKS = 45,
BLOCK_BLACKSTONE = 46,
BLOCK_IRON_BARS = 47,
BLOCK_STONE_BRICK_STAIRS_E = 48,
BLOCK_STONE_BRICK_STAIRS_W = 49,
BLOCK_STONE_BRICK_STAIRS_N = 50,
BLOCK_STONE_BRICK_STAIRS_S = 51,
BLOCK_DANDELION = 52,
BLOCK_AZURE_BLUET = 53,
BLOCK_OXEYE_DAISY = 54,
BLOCK_CORNFLOWER = 55,
BLOCK_LILY_OF_THE_VALLEY = 56,
BLOCK_FERN = 57,
BLOCK_CLAY = 58,
BLOCK_SEAGRASS = 59,
BLOCK_IRON_BARS_NS = 60,
BLOCK_IRON_BARS_EW = 61,
BLOCK_SPRUCE_STAIRS_N = 62,
BLOCK_SPRUCE_STAIRS_S = 63
}; };
struct trail_segment; struct trail_segment;
@@ -64,17 +85,27 @@ typedef struct {
uint16_t blocks[CHUNK_HEIGHT][CHUNK_SIZE][CHUNK_SIZE]; uint16_t blocks[CHUNK_HEIGHT][CHUNK_SIZE][CHUNK_SIZE];
} chunk_data; } chunk_data;
typedef struct {
int x;
int z;
int value;
uint8_t valid;
} worldgen_height_cache_entry;
typedef struct { typedef struct {
simplex_noise noise; simplex_noise noise;
int sea_level; int sea_level;
int world_seed; int world_seed;
int enable_trails; int enable_trails;
int enable_wall;
int wall_min_x, wall_max_x, wall_min_z, wall_max_z;
int snow_line; int snow_line;
struct trail_segment *trail_segments; struct trail_segment *trail_segments;
size_t trail_segment_count; size_t trail_segment_count;
size_t trail_segment_cap; size_t trail_segment_cap;
int prepass_done; int prepass_done;
int prepass_min_x, prepass_max_x, prepass_min_z, prepass_max_z; int prepass_min_x, prepass_max_x, prepass_min_z, prepass_max_z;
worldgen_height_cache_entry height_cache[WORLDGEN_HEIGHT_CACHE_SIZE];
} worldgen_ctx; } worldgen_ctx;
void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_line); void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_line);
@@ -83,5 +114,7 @@ void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int ma
void worldgen_free_trails(worldgen_ctx *ctx); void worldgen_free_trails(worldgen_ctx *ctx);
int worldgen_debug_biome(worldgen_ctx *ctx, int x, int z); int worldgen_debug_biome(worldgen_ctx *ctx, int x, int z);
double worldgen_debug_redwood_mask(worldgen_ctx *ctx, int x, int z); double worldgen_debug_redwood_mask(worldgen_ctx *ctx, int x, int z);
double worldgen_debug_community_strength(worldgen_ctx *ctx, int x, int z);
int worldgen_debug_bridge_site(worldgen_ctx *ctx, int x, int z, int dir_x, int dir_z);
#endif #endif

View File

@@ -51,6 +51,8 @@ typedef struct {
int snow_line; int snow_line;
pthread_mutex_t *log_mu; pthread_mutex_t *log_mu;
int enable_trails; int enable_trails;
int enable_wall;
int wall_min_x, wall_max_x, wall_min_z, wall_max_z;
results_buffer *results; results_buffer *results;
struct trail_segment *trail_segments; struct trail_segment *trail_segments;
size_t trail_segment_count; size_t trail_segment_count;
@@ -84,6 +86,8 @@ static const kv_pair PROPS_WATER[] = {{"level", "0"}};
static const kv_pair PROPS_LEAVES[] = {{"distance", "1"}, {"persistent", "false"}}; static const kv_pair PROPS_LEAVES[] = {{"distance", "1"}, {"persistent", "false"}};
static const kv_pair PROPS_STAIRS_E[] = {{"facing", "east"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}}; static const kv_pair PROPS_STAIRS_E[] = {{"facing", "east"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
static const kv_pair PROPS_STAIRS_W[] = {{"facing", "west"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}}; static const kv_pair PROPS_STAIRS_W[] = {{"facing", "west"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
static const kv_pair PROPS_STAIRS_N[] = {{"facing", "north"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
static const kv_pair PROPS_STAIRS_S[] = {{"facing", "south"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
static const kv_pair PROPS_DOOR_S_LOWER[] = {{"facing", "south"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}}; static const kv_pair PROPS_DOOR_S_LOWER[] = {{"facing", "south"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
static const kv_pair PROPS_DOOR_S_UPPER[] = {{"facing", "south"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}}; static const kv_pair PROPS_DOOR_S_UPPER[] = {{"facing", "south"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
static const kv_pair PROPS_DOOR_N_LOWER[] = {{"facing", "north"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}}; static const kv_pair PROPS_DOOR_N_LOWER[] = {{"facing", "north"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
@@ -96,6 +100,8 @@ static const kv_pair PROPS_LADDER_N[] = {{"facing", "north"}, {"waterlogged", "f
static const kv_pair PROPS_LADDER_S[] = {{"facing", "south"}, {"waterlogged", "false"}}; static const kv_pair PROPS_LADDER_S[] = {{"facing", "south"}, {"waterlogged", "false"}};
static const kv_pair PROPS_LADDER_W[] = {{"facing", "west"}, {"waterlogged", "false"}}; static const kv_pair PROPS_LADDER_W[] = {{"facing", "west"}, {"waterlogged", "false"}};
static const kv_pair PROPS_LADDER_E[] = {{"facing", "east"}, {"waterlogged", "false"}}; static const kv_pair PROPS_LADDER_E[] = {{"facing", "east"}, {"waterlogged", "false"}};
static const kv_pair PROPS_IRON_BARS_NS[] = {{"east", "false"}, {"north", "true"}, {"south", "true"}, {"waterlogged", "false"}, {"west", "false"}};
static const kv_pair PROPS_IRON_BARS_EW[] = {{"east", "true"}, {"north", "false"}, {"south", "false"}, {"waterlogged", "false"}, {"west", "true"}};
static const size_t BLOCK_STATE_CAP = 256; static const size_t BLOCK_STATE_CAP = 256;
static const int32_t DATA_VERSION = 2730; /* Java Edition 1.17.1; includes copper ore. */ static const int32_t DATA_VERSION = 2730; /* Java Edition 1.17.1; includes copper ore. */
static const block_state BLOCK_STATE_TABLE[] = { static const block_state BLOCK_STATE_TABLE[] = {
@@ -142,7 +148,27 @@ static const block_state BLOCK_STATE_TABLE[] = {
[BLOCK_LADDER_N] = {"minecraft:ladder", PROPS_LADDER_N, 2}, [BLOCK_LADDER_N] = {"minecraft:ladder", PROPS_LADDER_N, 2},
[BLOCK_LADDER_S] = {"minecraft:ladder", PROPS_LADDER_S, 2}, [BLOCK_LADDER_S] = {"minecraft:ladder", PROPS_LADDER_S, 2},
[BLOCK_LADDER_W] = {"minecraft:ladder", PROPS_LADDER_W, 2}, [BLOCK_LADDER_W] = {"minecraft:ladder", PROPS_LADDER_W, 2},
[BLOCK_LADDER_E] = {"minecraft:ladder", PROPS_LADDER_E, 2} [BLOCK_LADDER_E] = {"minecraft:ladder", PROPS_LADDER_E, 2},
[BLOCK_SMOOTH_STONE] = {"minecraft:smooth_stone", NULL, 0},
[BLOCK_STONE_BRICKS] = {"minecraft:stone_bricks", NULL, 0},
[BLOCK_BLACKSTONE] = {"minecraft:blackstone", NULL, 0},
[BLOCK_IRON_BARS] = {"minecraft:iron_bars", NULL, 0},
[BLOCK_STONE_BRICK_STAIRS_E] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_E, 4},
[BLOCK_STONE_BRICK_STAIRS_W] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_W, 4},
[BLOCK_STONE_BRICK_STAIRS_N] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_N, 4},
[BLOCK_STONE_BRICK_STAIRS_S] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_S, 4},
[BLOCK_DANDELION] = {"minecraft:dandelion", NULL, 0},
[BLOCK_AZURE_BLUET] = {"minecraft:azure_bluet", NULL, 0},
[BLOCK_OXEYE_DAISY] = {"minecraft:oxeye_daisy", NULL, 0},
[BLOCK_CORNFLOWER] = {"minecraft:cornflower", NULL, 0},
[BLOCK_LILY_OF_THE_VALLEY] = {"minecraft:lily_of_the_valley", NULL, 0},
[BLOCK_FERN] = {"minecraft:fern", NULL, 0},
[BLOCK_CLAY] = {"minecraft:clay", NULL, 0},
[BLOCK_SEAGRASS] = {"minecraft:seagrass", NULL, 0},
[BLOCK_IRON_BARS_NS] = {"minecraft:iron_bars", PROPS_IRON_BARS_NS, 5},
[BLOCK_IRON_BARS_EW] = {"minecraft:iron_bars", PROPS_IRON_BARS_EW, 5},
[BLOCK_SPRUCE_STAIRS_N] = {"minecraft:spruce_stairs", PROPS_STAIRS_N, 4},
[BLOCK_SPRUCE_STAIRS_S] = {"minecraft:spruce_stairs", PROPS_STAIRS_S, 4}
}; };
static const block_state *get_block_state(uint16_t id) { static const block_state *get_block_state(uint16_t id) {
@@ -296,18 +322,18 @@ static int64_t to_signed64(uint64_t v) {
static void pack_bits(const uint16_t *indices, size_t count, int bits_per_value, int64_t *out_longs, size_t out_count) { static void pack_bits(const uint16_t *indices, size_t count, int bits_per_value, int64_t *out_longs, size_t out_count) {
memset(out_longs, 0, out_count * sizeof(int64_t)); memset(out_longs, 0, out_count * sizeof(int64_t));
int values_per_long = 64 / bits_per_value;
if (values_per_long < 1) values_per_long = 1;
for (size_t idx = 0; idx < count; ++idx) { for (size_t idx = 0; idx < count; ++idx) {
uint64_t value = indices[idx]; uint64_t value = indices[idx];
size_t bit_index = idx * (size_t)bits_per_value; size_t long_id = idx / (size_t)values_per_long;
size_t long_id = bit_index / 64; size_t offset = (idx % (size_t)values_per_long) * (size_t)bits_per_value;
size_t offset = bit_index % 64; if (long_id >= out_count) continue;
uint64_t *target = (uint64_t *)&out_longs[long_id]; uint64_t *target = (uint64_t *)&out_longs[long_id];
*target |= value << offset; *target |= value << offset;
int spill = (int)(offset + bits_per_value - 64);
if (spill > 0 && long_id + 1 < out_count) {
uint64_t *next = (uint64_t *)&out_longs[long_id + 1];
*next |= value >> (bits_per_value - spill);
} }
for (size_t i = 0; i < out_count; ++i) {
out_longs[i] = to_signed64((uint64_t)out_longs[i]);
} }
} }
@@ -333,6 +359,13 @@ static void pack_heightmap(const chunk_data *chunk, int64_t *out_longs, size_t o
} }
} }
static int column_contains_water(const chunk_data *chunk, int x, int z) {
for (int y = 1; y < CHUNK_HEIGHT; ++y) {
if (chunk->blocks[y][x][z] == BLOCK_WATER) return 1;
}
return 0;
}
static int section_has_blocks(const chunk_data *chunk, int section_y) { static int section_has_blocks(const chunk_data *chunk, int section_y) {
int y_base = section_y * 16; int y_base = section_y * 16;
for (int y = 0; y < 16; ++y) { for (int y = 0; y < 16; ++y) {
@@ -394,7 +427,9 @@ static void write_section(buf *b, const chunk_data *chunk, int section_y) {
int needed = (int)ceil(log2((double)palette_len)); int needed = (int)ceil(log2((double)palette_len));
if (needed > bits) bits = needed; if (needed > bits) bits = needed;
} }
size_t packed_count = ((size_t)idx * (size_t)bits + 63) / 64; size_t values_per_long = (size_t)(64 / bits);
if (values_per_long < 1) values_per_long = 1;
size_t packed_count = ((size_t)idx + values_per_long - 1) / values_per_long;
int64_t *packed = (int64_t *)calloc(packed_count, sizeof(int64_t)); int64_t *packed = (int64_t *)calloc(packed_count, sizeof(int64_t));
if (!packed) return; if (!packed) return;
pack_bits(block_indices, idx, bits, packed, packed_count); pack_bits(block_indices, idx, bits, packed, packed_count);
@@ -424,7 +459,11 @@ static void write_section(buf *b, const chunk_data *chunk, int section_y) {
static void build_chunk_nbt(const chunk_data *chunk, buf *out) { static void build_chunk_nbt(const chunk_data *chunk, buf *out) {
int32_t biomes[256]; int32_t biomes[256];
for (int i = 0; i < 256; ++i) biomes[i] = 1; // Plains biome for (int z = 0; z < CHUNK_SIZE; ++z) {
for (int x = 0; x < CHUNK_SIZE; ++x) {
biomes[z * CHUNK_SIZE + x] = column_contains_water(chunk, x, z) ? 0 : 1; // Ocean or plains
}
}
int64_t heightmap[37]; int64_t heightmap[37];
pack_heightmap(chunk, heightmap, 37); pack_heightmap(chunk, heightmap, 37);
@@ -593,7 +632,7 @@ static void write_regions(const char *out_dir, region_accum *regions, size_t reg
static void usage(const char *prog) { static void usage(const char *prog) {
fprintf(stderr, fprintf(stderr,
"Usage: %s [--radius R] [--center-x X --center-z Z] [--min-x MX --max-x MX --min-z MZ --max-z MZ]\n" "Usage: %s [--radius R] [--center-x X --center-z Z] [--min-x MX --max-x MX --min-z MZ --max-z MZ]\n"
" [--threads N] [--seed S] [--sea-level L] [--snow-line H] [--format mca|bin] [--trails] [--out DIR]\n", " [--threads N] [--seed S] [--sea-level L] [--snow-line H] [--format mca|bin] [--trails] [--wall] [--out DIR]\n",
prog); prog);
} }
@@ -665,6 +704,11 @@ static void *worker_fn(void *ptr) {
worldgen_ctx ctx; worldgen_ctx ctx;
worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line); worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line);
ctx.enable_trails = args->enable_trails; ctx.enable_trails = args->enable_trails;
ctx.enable_wall = args->enable_wall;
ctx.wall_min_x = args->wall_min_x;
ctx.wall_max_x = args->wall_max_x;
ctx.wall_min_z = args->wall_min_z;
ctx.wall_max_z = args->wall_max_z;
if (args->trail_segments && args->trail_segment_count > 0) { if (args->trail_segments && args->trail_segment_count > 0) {
ctx.trail_segments = args->trail_segments; ctx.trail_segments = args->trail_segments;
ctx.trail_segment_count = args->trail_segment_count; ctx.trail_segment_count = args->trail_segment_count;
@@ -682,14 +726,12 @@ static void *worker_fn(void *ptr) {
chunk_data chunk; chunk_data chunk;
worldgen_generate_chunk(&ctx, job.x, job.z, &chunk); worldgen_generate_chunk(&ctx, job.x, job.z, &chunk);
if (args->results) { if (args->results) {
pthread_mutex_lock(&args->results->mutex);
size_t result_idx = atomic_fetch_add(&args->results->count, 1); size_t result_idx = atomic_fetch_add(&args->results->count, 1);
if (result_idx < args->results->capacity) { if (result_idx < args->results->capacity) {
args->results->chunks[result_idx].chunk_x = chunk.chunk_x; args->results->chunks[result_idx].chunk_x = chunk.chunk_x;
args->results->chunks[result_idx].chunk_z = chunk.chunk_z; args->results->chunks[result_idx].chunk_z = chunk.chunk_z;
memcpy(&args->results->chunks[result_idx].data, &chunk, sizeof(chunk_data)); memcpy(&args->results->chunks[result_idx].data, &chunk, sizeof(chunk_data));
} }
pthread_mutex_unlock(&args->results->mutex);
} else { } else {
write_chunk_file(args->out_dir, &chunk); write_chunk_file(args->out_dir, &chunk);
} }
@@ -716,6 +758,7 @@ int main(int argc, char **argv) {
int sea_level = 70; int sea_level = 70;
int snow_line = INT_MIN; int snow_line = INT_MIN;
int enable_trails = 0; int enable_trails = 0;
int enable_wall = 0;
const char *out_dir = "output"; const char *out_dir = "output";
output_format format = FORMAT_MCA; output_format format = FORMAT_MCA;
@@ -761,6 +804,8 @@ int main(int argc, char **argv) {
} }
} else if (strcmp(argv[i], "--trails") == 0) { } else if (strcmp(argv[i], "--trails") == 0) {
enable_trails = 1; enable_trails = 1;
} else if (strcmp(argv[i], "--wall") == 0) {
enable_wall = 1;
} else if ((strcmp(argv[i], "--out") == 0 || strcmp(argv[i], "--output") == 0) && i + 1 < argc) { } else if ((strcmp(argv[i], "--out") == 0 || strcmp(argv[i], "--output") == 0) && i + 1 < argc) {
out_dir = argv[++i]; out_dir = argv[++i];
} else if (strcmp(argv[i], "--help") == 0) { } else if (strcmp(argv[i], "--help") == 0) {
@@ -791,6 +836,11 @@ int main(int argc, char **argv) {
int world_max_x = max_x * CHUNK_SIZE + (CHUNK_SIZE - 1); int world_max_x = max_x * CHUNK_SIZE + (CHUNK_SIZE - 1);
int world_min_z = min_z * CHUNK_SIZE; int world_min_z = min_z * CHUNK_SIZE;
int world_max_z = max_z * CHUNK_SIZE + (CHUNK_SIZE - 1); int world_max_z = max_z * CHUNK_SIZE + (CHUNK_SIZE - 1);
pre_ctx.enable_wall = enable_wall;
pre_ctx.wall_min_x = world_min_x;
pre_ctx.wall_max_x = world_max_x;
pre_ctx.wall_min_z = world_min_z;
pre_ctx.wall_max_z = world_max_z;
if (enable_trails) { if (enable_trails) {
worldgen_prepass(&pre_ctx, world_min_x, world_max_x, world_min_z, world_max_z); worldgen_prepass(&pre_ctx, world_min_x, world_max_x, world_min_z, world_max_z);
prepass_ready = 1; prepass_ready = 1;
@@ -836,6 +886,11 @@ int main(int argc, char **argv) {
.snow_line = snow_line, .snow_line = snow_line,
.log_mu = &log_mu, .log_mu = &log_mu,
.enable_trails = enable_trails, .enable_trails = enable_trails,
.enable_wall = enable_wall,
.wall_min_x = world_min_x,
.wall_max_x = world_max_x,
.wall_min_z = world_min_z,
.wall_max_z = world_max_z,
.results = &results, .results = &results,
.trail_segments = prepass_ready ? pre_ctx.trail_segments : NULL, .trail_segments = prepass_ready ? pre_ctx.trail_segments : NULL,
.trail_segment_count = prepass_ready ? pre_ctx.trail_segment_count : 0, .trail_segment_count = prepass_ready ? pre_ctx.trail_segment_count : 0,

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ static int is_cabin_block(uint16_t block) {
block == BLOCK_OAK_LOG_X || block == BLOCK_OAK_LOG_Z || block == BLOCK_OAK_LOG_X || block == BLOCK_OAK_LOG_Z ||
block == BLOCK_SPRUCE_LOG_X || block == BLOCK_SPRUCE_LOG_Z || block == BLOCK_SPRUCE_LOG_X || block == BLOCK_SPRUCE_LOG_Z ||
block == BLOCK_GLASS_PANE || block == BLOCK_GLASS || block == BLOCK_SPRUCE_STAIRS_E || block == BLOCK_SPRUCE_STAIRS_W || block == BLOCK_GLASS_PANE || block == BLOCK_GLASS || block == BLOCK_SPRUCE_STAIRS_E || block == BLOCK_SPRUCE_STAIRS_W ||
block == BLOCK_SPRUCE_STAIRS_N || block == BLOCK_SPRUCE_STAIRS_S ||
block == BLOCK_LADDER_N || block == BLOCK_LADDER_S || block == BLOCK_LADDER_E || block == BLOCK_LADDER_W || block == BLOCK_LADDER_N || block == BLOCK_LADDER_S || block == BLOCK_LADDER_E || block == BLOCK_LADDER_W ||
block == BLOCK_SPRUCE_DOOR_N_LOWER || block == BLOCK_SPRUCE_DOOR_N_UPPER || block == BLOCK_SPRUCE_DOOR_N_LOWER || block == BLOCK_SPRUCE_DOOR_N_UPPER ||
block == BLOCK_SPRUCE_DOOR_S_LOWER || block == BLOCK_SPRUCE_DOOR_S_UPPER || block == BLOCK_SPRUCE_DOOR_S_LOWER || block == BLOCK_SPRUCE_DOOR_S_UPPER ||
@@ -78,6 +79,8 @@ int main(int argc, char **argv) {
long cabin_columns = 0; long cabin_columns = 0;
long gravel_columns = 0; long gravel_columns = 0;
long cabin_gravel_columns = 0; long cabin_gravel_columns = 0;
long bridge_deck_columns = 0;
long eligible_bridge_columns = 0;
long tall_log_columns = 0; long tall_log_columns = 0;
long max_oak_log_run = 0; long max_oak_log_run = 0;
long biome_columns[4] = {0, 0, 0, 0}; long biome_columns[4] = {0, 0, 0, 0};
@@ -96,8 +99,11 @@ int main(int argc, char **argv) {
if (biome >= 0 && biome < 4) ++biome_columns[biome]; if (biome >= 0 && biome < 4) ++biome_columns[biome];
double redwood_mask = worldgen_debug_redwood_mask(&ctx, wx, wz); double redwood_mask = worldgen_debug_redwood_mask(&ctx, wx, wz);
if (redwood_mask > max_redwood_mask) max_redwood_mask = redwood_mask; if (redwood_mask > max_redwood_mask) max_redwood_mask = redwood_mask;
if (worldgen_debug_bridge_site(&ctx, wx, wz, 1, 0) ||
worldgen_debug_bridge_site(&ctx, wx, wz, 0, 1)) ++eligible_bridge_columns;
int has_cabin = 0; int has_cabin = 0;
int has_gravel = 0; int has_gravel = 0;
int has_bridge_deck = 0;
int current_run = 0; int current_run = 0;
int best_run = 0; int best_run = 0;
for (int y = 1; y < CHUNK_HEIGHT; ++y) { for (int y = 1; y < CHUNK_HEIGHT; ++y) {
@@ -109,6 +115,8 @@ int main(int argc, char **argv) {
if (block == BLOCK_GRAVEL) { if (block == BLOCK_GRAVEL) {
has_gravel = 1; has_gravel = 1;
} }
if (block == BLOCK_SPRUCE_PLANKS && y > 1 && chunk.blocks[y - 1][lx][lz] == BLOCK_WATER)
has_bridge_deck = 1;
if (block == BLOCK_OAK_LOG) { if (block == BLOCK_OAK_LOG) {
++current_run; ++current_run;
if (current_run > best_run) best_run = current_run; if (current_run > best_run) best_run = current_run;
@@ -120,6 +128,7 @@ int main(int argc, char **argv) {
if (best_run >= 40) ++tall_log_columns; if (best_run >= 40) ++tall_log_columns;
if (has_cabin) ++cabin_columns; if (has_cabin) ++cabin_columns;
if (has_gravel) ++gravel_columns; if (has_gravel) ++gravel_columns;
if (has_bridge_deck) ++bridge_deck_columns;
if (has_cabin && has_gravel) { if (has_cabin && has_gravel) {
++cabin_gravel_columns; ++cabin_gravel_columns;
} }
@@ -133,6 +142,8 @@ int main(int argc, char **argv) {
printf("cabin_columns=%ld\n", cabin_columns); printf("cabin_columns=%ld\n", cabin_columns);
printf("gravel_columns=%ld\n", gravel_columns); printf("gravel_columns=%ld\n", gravel_columns);
printf("cabin_gravel_columns=%ld\n", cabin_gravel_columns); printf("cabin_gravel_columns=%ld\n", cabin_gravel_columns);
printf("bridge_deck_columns=%ld\n", bridge_deck_columns);
printf("eligible_bridge_columns=%ld\n", eligible_bridge_columns);
printf("tall_oak_log_columns=%ld\n", tall_log_columns); printf("tall_oak_log_columns=%ld\n", tall_log_columns);
printf("max_oak_log_run=%ld\n", max_oak_log_run); printf("max_oak_log_run=%ld\n", max_oak_log_run);
printf("biome_west_ky=%ld\n", biome_columns[0]); printf("biome_west_ky=%ld\n", biome_columns[0]);