extends SceneTree # Forgejo #234: gas is always in reach of where the game starts. # # Gas giants are gated behind two independent noise fields - the SPACE biome # AND the planet roll - so whether any sat near the spawn was luck. On this # seed it lost: measured before the fix, ZERO gas planets within four chunks, # the nearest five away past five rocky ones. Gas is an early need (the # burner, ammunition), so the opening cannot depend on the noise being kind. # # Covers: # A. a gas planet exists within four chunks of the spawn # B. it is a real planet - it spawns, and it actually yields gas # C. it is not sitting on top of the spawn itself # D. forcing it does not reshuffle any other chunk, which is the property # the whole of WorldGen is built on const SPAWN_CHUNK: Vector2i = Vector2i(0, 0) const REACH: int = 4 var WG var PD func _initialize() -> void: WG = load("res://world/WorldGen.gd") PD = load("res://planets/PlanetDefinitions.gd") func _process(_delta: float) -> bool: # --- A. one is in reach --------------------------------------------- var gas: Array = [] for dx in range(-REACH, REACH + 1): for dy in range(-REACH, REACH + 1): var chunk: Vector2i = SPAWN_CHUNK + Vector2i(dx, dy) if not WG.has_planet_at_chunk(chunk): continue if String(WG.planet_data_at_chunk(chunk).get("definition_id", "")) == PD.GAS_GIANT_ID: gas.append(chunk) if gas.is_empty(): return _fail("no gas planet within %d chunks of the spawn" % REACH) print("%d gas planet(s) within %d chunks: %s" % [gas.size(), REACH, gas]) # --- C. and not underneath the fleet --------------------------------- if gas.has(SPAWN_CHUNK): return _fail("the guaranteed gas planet is on the spawn chunk itself") # --- B. it is a real, generated, gas-bearing planet ------------------- var chunk: Vector2i = WG.SPAWN_GAS_GIANT_CHUNK var chebyshev: int = maxi(absi(chunk.x - SPAWN_CHUNK.x), absi(chunk.y - SPAWN_CHUNK.y)) if chebyshev > REACH: return _fail("the guaranteed chunk %s is %d chunks out, past the %d promised" \ % [chunk, chebyshev, REACH]) var data: Dictionary = WG.planet_data_at_chunk(chunk) if String(data.get("definition_id", "")) != PD.GAS_GIANT_ID: return _fail("the guaranteed chunk is '%s', not a gas giant" % data.get("definition_id", "")) var definition: Resource = PD.get_definition(PD.GAS_GIANT_ID) if String(definition.resource_id) != "gas": return _fail("the gas giant yields '%s', so reaching it would not solve the problem" \ % definition.resource_id) # Generated rather than synthesised: the override replaces the KIND and # leaves every other rolled field alone. if String(data.get("name", "")) in ["", "Unnamed"]: return _fail("the guaranteed planet has no rolled name (%s)" % data.get("name", "")) var local: Vector2 = data.get("local_pos", Vector2(-1, -1)) if local.x < 0.0 or local.y < 0.0 or local.x > WG.CHUNK_SIZE or local.y > WG.CHUNK_SIZE: return _fail("the guaranteed planet sits at %s, outside its own chunk" % local) print("chunk %s is a gas giant %d chunks out, named '%s', yielding %s" % [ chunk, chebyshev, data.get("name", ""), definition.resource_id]) # --- D. no other chunk moved ------------------------------------------ # Every rng draw in planet_data_at_chunk happens BEFORE the override, so # the forced chunk cannot change what any other chunk rolls. Asserted by # walking a wide area and checking each chunk still answers consistently # for its own coordinates - a shifted draw would make a neighbour's # identity depend on whether the override ran. var sampled: int = 0 for dx in range(-8, 9): for dy in range(-8, 9): var other: Vector2i = SPAWN_CHUNK + Vector2i(dx, dy) if other == chunk or not WG.has_planet_at_chunk(other): continue var a: Dictionary = WG.planet_data_at_chunk(other) var b: Dictionary = WG.planet_data_at_chunk(other) if a.get("definition_id") != b.get("definition_id") \ or a.get("shape_seed") != b.get("shape_seed") \ or a.get("name") != b.get("name"): return _fail("chunk %s generates differently on two calls" % other) sampled += 1 if sampled < 10: return _fail("only %d other planets sampled - that proves nothing about the rest of the map" % sampled) print("%d other planets nearby still generate deterministically" % sampled) print("TEST_SPAWN_GAS_PLANET: PASS") quit(0) return true func _fail(message: String) -> bool: print("TEST_SPAWN_GAS_PLANET: FAIL (%s)" % message) quit(1) return true