Files
minecraft-builder-mcp/scripts/voxel-island.py
T

62 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Deterministic floating-island columns, independent of any map or server.
Large contour harmonics shape the silhouette; correlated low-frequency fields
shape the underside. Surface grading and gameplay layout belong to the caller.
This is an offline geometry helper, not an additional MCP tool or live edit API.
"""
import math
def smooth(value):
value = max(0., min(1., value))
return value * value * (3 - 2 * value)
def hash_value(x, z, seed):
n = (x * 374761393 + z * 668265263 + seed * 1442695041) & 0xffffffff
n = ((n ^ (n >> 13)) * 1274126177) & 0xffffffff
return (n ^ (n >> 16)) / 0xffffffff
def noise(x, z, seed):
x0, z0 = math.floor(x), math.floor(z)
u, v = smooth(x - x0), smooth(z - z0)
a = hash_value(x0, z0, seed) * (1 - u) + hash_value(x0 + 1, z0, seed) * u
b = hash_value(x0, z0 + 1, seed) * (1 - u) + hash_value(x0 + 1, z0 + 1, seed) * u
return a * (1 - v) + b * v
def columns(cx, cz, radius_x, radius_z, surface_y, depth, seed, contour=.055):
"""Return {(x,z): {bottom, top, radial}} with inclusive occupied Y ranges.
``radial`` is normalized distance from the warped boundary (0 centre,1 rim).
The terrain is a connected solid below each top, with no inferred live air.
Neighbouring columns have coherent variation; random per-block noise is left
out deliberately. Integers give reproducible inclusive world coordinates.
"""
values = (radius_x, radius_z, depth, contour)
if not all(math.isfinite(v) for v in values) or min(radius_x, radius_z, depth) <= 0 or not 0 <= contour <= .2:
raise ValueError('Use positive finite radii/depth and contour in0..0.2')
if any(type(v) is not int for v in (cx, cz, surface_y, seed)):
raise ValueError('Centre, surface and seed must be integers')
result = {}
for x in range(math.floor(cx - radius_x * 1.3), math.ceil(cx + radius_x * 1.3) + 1):
for z in range(math.floor(cz - radius_z * 1.3), math.ceil(cz + radius_z * 1.3) + 1):
dx, dz = (x - cx) / radius_x, (z - cz) / radius_z
angle = math.atan2(dz, dx)
boundary = 1 + contour * (math.sin(3 * angle + seed * .07)
+ .45 * math.sin(7 * angle - seed * .11))
radial = math.hypot(dx, dz) / boundary
if radial > 1:
continue
# A broad taper and coherent hanging buttresses give a recognisable
# mass even when viewed in silhouette, before material decoration.
taper = max(0., 1 - radial ** 1.55) ** .62
buttress = .63 + .37 * noise(x / 7.5, z / 7.5, seed + 31)
ribs = 2.5 * smooth(noise(x / 3.8, z / 3.8, seed + 57))
thickness = max(3, round(3 + depth * taper * buttress + ribs))
result[x, z] = {'top': surface_y, 'bottom': surface_y - thickness + 1,
'radial': radial}
return result