c4e7302567
- Introduced `civilization_benchmark.gd` and `legacy_quantity_math.gd` for benchmarking and legacy quantity calculations. - Created `test_dynamic_math.gd`, `test_frame_evolution.gd`, and `test_sparse_batches.gd` to validate mathematical operations and frame evolution logic. - Implemented `frame_budget.gd` to manage cooperative work on the main thread, ensuring no partially calculated state is published. - Added UID files for all new scripts to maintain unique identifiers.
125 lines
6.4 KiB
GDScript
125 lines
6.4 KiB
GDScript
extends SceneTree
|
|
const E = preload("res://world/owniverse/math/exact.gd")
|
|
const Clock = preload("res://world/owniverse/simulation_time.gd")
|
|
var checks: int = 0
|
|
var failures: int = 0
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run")
|
|
|
|
func check(condition: bool, message: String) -> void:
|
|
checks = E.add(checks, 1)
|
|
if (not condition):
|
|
failures = E.add(failures, 1)
|
|
push_error(message)
|
|
|
|
func fixture():
|
|
var world = load("res://world/owniverse/owniverse.gd").new()
|
|
var global: Node = root.get_node("Global")
|
|
for id in global.OwniverseEntities:
|
|
var entity = load("res://world/owniverse/owniverse_entity.gd").new(global.OwniverseEntities[id])
|
|
world.catalog.entities[id] = entity
|
|
world.state.amount[id] = 0
|
|
world.state.stats.total_amount[id] = 0
|
|
if E.ne(entity.group_as, ""):
|
|
world.state.amount[entity.group_as] = 0
|
|
world.state.stats.total_amount[entity.group_as] = 0
|
|
world.catalog.entities["N"].life_product = {}
|
|
world.catalog.entities["N"].product_per_year_type = "H"
|
|
world.catalog.entities["N"].product_per_year_amount = 10
|
|
world.catalog.entities["N"].auto = 0
|
|
world.state.amount.N = 1
|
|
return world
|
|
|
|
func dispose(world) -> void:
|
|
for entity in world.catalog.entities.values():
|
|
entity.free()
|
|
world.free()
|
|
|
|
func run() -> void:
|
|
var world = fixture()
|
|
world.state.amount.N = 0
|
|
world.state.amount.HP = 40000
|
|
world.evolution.initialize_life_batches()
|
|
check(E.eq(world.state.batches.HP.size(), 1), "Old HP receives life cohort")
|
|
check(E.eq(world.state.batches.HP[0].start_year, 5000000), "HP uses source span")
|
|
var before: Dictionary = world.state.duplicate(true)
|
|
world.evolution.initialize_life_batches()
|
|
check(E.eq(world.state, before), "Initialization is idempotent")
|
|
world.evolution.evolve_batches(world.state, E.add(5000000, E.divide(5000000, 40)))
|
|
check(E.eq(world.state.amount.EON1, 10), "HP abiogenesis follows source probability")
|
|
check(E.eq(world.state.amount.RP, 100), "HP degradation produces RP")
|
|
check(E.eq(world.state.amount.HP, 39890), "Unchanged planets retry, not disappear")
|
|
check(E.eq(world.state.stats.total_amount.HP, 0), "Retry does not inflate creation statistics")
|
|
check(E.gt(world.state.batches.HP.size(), 0), "Survivors get next attempt")
|
|
var physical: Dictionary = world.ledger.physical_amounts(world.state)
|
|
check(E.eq(E.add(E.add(physical.HP, physical.EON1), physical.RP), 40000), "Life conserves planets")
|
|
check(E.eq(root.get_node("SaveManager").validate_data({"format_version": 5, "app_version": "", "ui": {"current_page": 0}, "state": world.state}), ""), "Life save validates")
|
|
var restored = fixture()
|
|
restored.state = E.decode(bytes_to_var(var_to_bytes(E.encode(world.state))))
|
|
world.evolution.evolve_batches(world.state, 11000000)
|
|
restored.evolution.evolve_batches(restored.state, 11000000)
|
|
check(E.eq(world.state, restored.state), "Life continuation preserves cohorts and carries")
|
|
dispose(restored)
|
|
dispose(world)
|
|
|
|
world = fixture()
|
|
world.state.amount.RD = 1
|
|
world.state.binds.RD = {"EON5": 40000}
|
|
world.evolution.initialize_life_batches()
|
|
world.evolution.evolve_batches(world.state, E.add(500000, E.divide(500000, 40)))
|
|
check(E.eq(world.state.binds.RD["C0.0"], 10), "Intelligence emerges at the same host star")
|
|
check(E.eq(world.state.amount["C0.0"], 0), "Life transition keeps planet bound")
|
|
check(world.state.batches.has("C0.0"), "New C0.0 starts civilization evolution")
|
|
dispose(world)
|
|
|
|
world = fixture()
|
|
var progress: Variant = 0
|
|
var degraded: Variant = 0
|
|
var valid_outcomes: bool = true
|
|
for i in 4001:
|
|
var products: Dictionary = world.life.life_products(world.state, world.catalog.entities.HP, 1)
|
|
var total: Variant = 0
|
|
for value in products.values():
|
|
total = E.add(total, value)
|
|
valid_outcomes = ((valid_outcomes and E.ge(value, 0)) and E.eq(value, E.floor_value(value)))
|
|
valid_outcomes = (valid_outcomes and E.eq(total, 1))
|
|
progress = E.add(progress, products.get("EON1", 0))
|
|
degraded = E.add(degraded, products.get("RP", 0))
|
|
check(valid_outcomes, "Every single-planet attempt has whole outcomes and conserves population")
|
|
check((E.eq(progress, 1) and E.eq(degraded, 10)), "Rare outcomes accumulate deterministically")
|
|
dispose(world)
|
|
|
|
world = fixture()
|
|
world.state.time = {"datetime": E.of("123.4"), "year": E.of("123.4")}
|
|
world.state.binds.RD = {"HP": 2}
|
|
world.evolution.initialize_life_batches()
|
|
check(E.eq(world.state.batches.HP[0].created_from, E.of("123.4")), "Old bound worlds begin life at load time")
|
|
world.stellar.destroy_planets(world.state, "RD", 1, 1)
|
|
world.evolution.evolve_batches(world.state, 10000000)
|
|
check((E.eq(world.ledger.physical_amounts(world.state).HP, 0) and E.eq(world.state.binds.RD.RP, 2)), "Destroyed life does not resurrect from cohort")
|
|
dispose(world)
|
|
world = fixture()
|
|
world.state.time = {"datetime": E.of("123.4"), "year": E.of("123.4")}
|
|
world.state.amount["C0.0"] = 40000
|
|
world.evolution.initialize_life_batches()
|
|
check(E.eq(world.state.batches["C0.0"][0].created_from, E.of("123.4")), "Civilization cohorts begin at the current time")
|
|
before = world.state.duplicate(true)
|
|
world.evolution.initialize_life_batches()
|
|
check(E.eq(world.state, before), "Life batch initialization is idempotent")
|
|
world.evolution.evolve_batches(world.state, E.of("2173.4"))
|
|
check((E.eq(world.state.amount["C0.1"], 700) and E.eq(world.state.amount.EON5, 1000)), "C0.0 progresses and degrades by Unity rates")
|
|
check(E.eq(world.state.amount["C0.0"], 38300), "C0.0 remainder stays alive")
|
|
dispose(world)
|
|
world = fixture()
|
|
world.state.amount.RD = 1
|
|
world.state.binds.RD = {"C0.1": 40000}
|
|
world.evolution.initialize_life_batches()
|
|
world.evolution.evolve_batches(world.state, 2050)
|
|
check(E.eq(world.state.binds.RD["C0.2"], 700), "C0.1 reaches ethical civilization without losing host")
|
|
check(E.eq(world.state.binds.RD["C0.0"], 1000), "C0.1 degradation follows Unity")
|
|
check(E.eq(root.get_node("SaveManager").validate_data({"format_version": 5, "app_version": "", "ui": {"current_page": 0}, "state": world.state}), ""), "Extended life save validates")
|
|
dispose(world)
|
|
print(("Life: %d checks, %d failures" % [checks, failures]))
|
|
quit((0 if E.eq(failures, 0) else 1))
|