Add black hole planet and dark matter resource (#55)

A rare, deterministically-seeded landable body yielding a fourth
resource, dark matter, obtainable only through an extractor - never a
surface pickup. Reuses every existing generic system (resource/planet
definitions, surface profiles, extractor/transporter pipeline) with no
type-switch branching.

Also fixes a latent conquest-gating gap: a surface profile with no
authored PlanetSetup (like the black hole's "void") never registered
capture points at all, permanently blocking extractor placement.
register_capture_points() now treats zero required points as vacuously
conquered, and PlanetSurfaceController registers that zero-point state
explicitly when no setup exists.
This commit is contained in:
Loïc Wisniewski 2026-08-16 13:13:38 +02:00
commit cbe07bbb55
20 changed files with 421 additions and 2 deletions

View file

@ -16,6 +16,12 @@ const NOISE_SEED: int = 1337
const ASTEROID_FIELD_THRESHOLD: float = 0.15
const PLANET_THRESHOLD: float = 0.33
const GAS_GIANT_THRESHOLD: float = 0.55
# A flat per-planet-chunk probability rather than another noise field: gas
# giants already cover every SPACE-biome planet chunk (see GAS_GIANT_THRESHOLD
# above), so making black holes noticeably rarer just needs a small, uniform
# chance independent of biome - not a second smooth region to tune against
# the first.
const BLACK_HOLE_CHANCE: float = 0.05
# A predictable early gas source for play-testing. The origin chunk is
# deterministically normal space. Its explicit in-chunk position puts it
@ -84,10 +90,20 @@ static func planet_data_at_chunk(chunk: Vector2i) -> Dictionary:
var local_pos: Vector2 = NEARBY_GAS_GIANT_LOCAL_POS if guaranteed_nearby_giant \
else Vector2(rng.randf() * CHUNK_SIZE, rng.randf() * CHUNK_SIZE)
var shape_seed: int = rng.randi()
# Drawn unconditionally, in the same fixed position every call,
# regardless of biome or the gas-giant roll below - so adding this
# roll doesn't shift which random values any LATER draw (planet_name,
# below) consumes for chunks that would have existed before it.
var black_hole_roll: float = rng.randf()
# A stable per-chunk roll makes gas giants persistent landmarks rather
# than a different resource whenever the scene reloads.
var gas_giant: bool = guaranteed_nearby_giant or biome_at_chunk(chunk) == Biome.SPACE
var definition_id: String = PLANET_DEFINITIONS.GAS_GIANT_ID if gas_giant else PLANET_DEFINITIONS.ROCKY_ID
# A rare third outcome, seeded the same deterministic way as everything
# else here. Never overrides the guaranteed early gas giant landmark -
# that chunk's whole purpose is to always be the same reachable source.
if not guaranteed_nearby_giant and black_hole_roll < BLACK_HOLE_CHANCE:
definition_id = PLANET_DEFINITIONS.BLACK_HOLE_ID
var definition: Resource = PLANET_DEFINITIONS.get_definition(definition_id)
var names: PackedStringArray = definition.names
var planet_name: String = names[rng.randi() % names.size()]