Add core simulation modules for owniverse mechanics
- Introduced `life_evolution.gd` to manage life evolution processes. - Implemented `manual_production.gd` for handling production mechanics, including resource management and production steps. - Created `object_batches.gd` to manage batches of objects, including scaling and appending batches. - Developed `object_ledger.gd` for tracking physical amounts, available resources, and binding ownerships. - Added `simulation_module.gd` as a base class for simulation modules, providing a weak reference to the world. - Established `stellar_rules.gd` for managing stellar evolution and destruction mechanics. - Introduced `universe_environment.gd` to calculate environmental parameters based on the current state of the universe.
This commit is contained in:
@@ -17,21 +17,21 @@ func fixture():
|
||||
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.entities[id] = entity
|
||||
world.catalog.entities[id] = entity
|
||||
world.state.amount[id] = 0.0
|
||||
world.state.stats.total_amount[id] = 0.0
|
||||
if entity.group_as != "":
|
||||
world.state.amount[entity.group_as] = 0.0
|
||||
world.state.stats.total_amount[entity.group_as] = 0.0
|
||||
world.entities["N"].life_product = {}
|
||||
world.entities["N"].product_per_year_type = "H"
|
||||
world.entities["N"].product_per_year_amount = 10.0
|
||||
world.entities["N"].auto = 0.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.0
|
||||
world.catalog.entities["N"].auto = 0.0
|
||||
world.state.amount.N = 1.0
|
||||
return world
|
||||
|
||||
func dispose(world) -> void:
|
||||
for entity in world.entities.values():
|
||||
for entity in world.catalog.entities.values():
|
||||
entity.free()
|
||||
world.free()
|
||||
|
||||
@@ -39,7 +39,7 @@ func seed_population(world, id: String, count: float, time: float = 1.0) -> void
|
||||
world.state.amount.N = 0.0
|
||||
world.state.amount[id] = count
|
||||
world.state.batches[id] = [{"amount": count, "start_year": time, "end_year": time}]
|
||||
world.initialize_life_batches()
|
||||
world.evolution.initialize_life_batches()
|
||||
|
||||
func sum_ethics(world, id: String) -> float:
|
||||
var result: float = 0.0
|
||||
@@ -47,7 +47,7 @@ func sum_ethics(world, id: String) -> float:
|
||||
return result
|
||||
|
||||
func invariants(world) -> void:
|
||||
var physical: Dictionary = world._physical_amounts(world.state)
|
||||
var physical: Dictionary = world.ledger.physical_amounts(world.state)
|
||||
for id in world.state.ethics:
|
||||
check(sum_ethics(world, id) == physical.get(id, 0.0), "Ethics equal physical population for " + id)
|
||||
for n in world.state.ethics[id].values():
|
||||
@@ -59,7 +59,7 @@ func run() -> void:
|
||||
var baseline: Dictionary = global.CivilizationRules.duplicate(true)
|
||||
var world = fixture()
|
||||
seed_population(world, "C0.2", 60000.0)
|
||||
world._evolve_batches(world.state, 1.0)
|
||||
world.evolution.evolve_batches(world.state, 1.0)
|
||||
check(world.state.amount["C0.3"] > 0.0, "C0.2 actually progresses")
|
||||
check(world.state.amount["C0.1"] > 0.0, "C0.2 actually degrades")
|
||||
check(world.state.civilization_stats.get("wars", 0.0) == 0.0, "Table disables early wars")
|
||||
@@ -69,8 +69,8 @@ func run() -> void:
|
||||
invariants(world)
|
||||
var restored = fixture()
|
||||
restored.state = bytes_to_var(var_to_bytes(world.state))
|
||||
world._evolve_batches(world.state, 2100.0)
|
||||
restored._evolve_batches(restored.state, 2100.0)
|
||||
world.evolution.evolve_batches(world.state, 2100.0)
|
||||
restored.evolution.evolve_batches(restored.state, 2100.0)
|
||||
check(world.state == restored.state, "Save resumes deterministic ethical evolution")
|
||||
invariants(world)
|
||||
dispose(restored)
|
||||
@@ -80,8 +80,8 @@ func run() -> void:
|
||||
world.state.amount.RD = 1e8
|
||||
seed_population(world, "C2.0", 60000.0)
|
||||
world.state.amount["C1.9"] = 10000.0
|
||||
world.initialize_life_batches()
|
||||
world._evolve_batches(world.state, 1.0)
|
||||
world.evolution.initialize_life_batches()
|
||||
world.evolution.evolve_batches(world.state, 1.0)
|
||||
check(world.state.civilization_stats.wars > 0.0, "Wars execute when enabled")
|
||||
check(world.state.civilization_stats.collateral > 0.0, "Wars affect previous-stage populations")
|
||||
check(world.state.amount["C2.1"] > 0.0, "Winners and peaceful progress reach next stage")
|
||||
@@ -93,14 +93,14 @@ func run() -> void:
|
||||
world.state.binds.RD = {"HP": 5.0, "GG": 5.0, "AB": 5.0, "RP": 5.0}
|
||||
seed_population(world, "C1.6", 60000.0)
|
||||
for row: Dictionary in global.CivilizationRules["C1.6"].ethics.values(): row.degradation = "0"
|
||||
world._evolve_batches(world.state, 1.0)
|
||||
var after: Dictionary = world._physical_amounts(world.state)
|
||||
world.evolution.evolve_batches(world.state, 1.0)
|
||||
var after: Dictionary = world.ledger.physical_amounts(world.state)
|
||||
check(world.state.civilization_stats.colonies == 20.0, "Colonization limited to real targets")
|
||||
check(after.HP + after.GG + after.AB + after.RP == 0.0, "Colonized objects consumed once")
|
||||
check(world.state.binds.RD.get("C1.4", 0.0) == 20.0, "Colonies retain target host and use two-stages-earlier level")
|
||||
var totals: float = 0.0
|
||||
for id in after:
|
||||
if world.entities[id].group_as == "Planet": totals += after[id]
|
||||
if world.catalog.entities[id].group_as == "Planet": totals += after[id]
|
||||
check(totals == 60020.0, "Colonization replaces planets, does not create extra worlds")
|
||||
invariants(world)
|
||||
dispose(world)
|
||||
@@ -114,8 +114,8 @@ func run() -> void:
|
||||
world.state.amount.MGT = 1e25
|
||||
world.state.amount.BH25 = 1e25
|
||||
world.state.amount.SMBH = 1e26
|
||||
for id in world.entities:
|
||||
if world.entities[id].claim != "": world.state.amount[id] = 1e12
|
||||
for id in world.catalog.entities:
|
||||
if world.catalog.entities[id].claim != "": world.state.amount[id] = 1e12
|
||||
# Accelerated deterministic fixture traverses every enabled stage, including Ct.
|
||||
for id in global.CivilizationRules:
|
||||
if id == "Ct": continue
|
||||
@@ -125,11 +125,11 @@ func run() -> void:
|
||||
for row: Dictionary in global.CivilizationRules[id].ethics.values():
|
||||
row.progress = "1"
|
||||
row.degradation = "0"
|
||||
world.entities[id].lifespan = 1.0
|
||||
world.entities[id].lifespan_delta = 1.0
|
||||
world.catalog.entities[id].lifespan = 1.0
|
||||
world.catalog.entities[id].lifespan_delta = 1.0
|
||||
global.CivilizationRules[id].span = 1.0
|
||||
seed_population(world, "C0.2", 6.0)
|
||||
world._evolve_batches(world.state, 1000.0)
|
||||
world.evolution.evolve_batches(world.state, 1000.0)
|
||||
check(world.state.amount.Ct == 6.0, "Complete C0.2 -> C4.4 -> Ct chain runs")
|
||||
check(not world.state.batches.has("Ct"), "Transcendence is terminal")
|
||||
invariants(world)
|
||||
@@ -140,7 +140,7 @@ func run() -> void:
|
||||
world.state.amount.RD = 10000.0
|
||||
world.state.amount.SCS = 1.0
|
||||
world.state.amount["C2.4"] = 1.0
|
||||
world.initialize_life_batches()
|
||||
world.evolution.initialize_life_batches()
|
||||
var span: float = world.state.batches["C2.4"][0].start_year
|
||||
check(is_equal_approx(span, 20000.0 / 3.6), "Structure bonus shortens newly registered lifespan")
|
||||
dispose(world)
|
||||
@@ -156,7 +156,7 @@ func run() -> void:
|
||||
world.state.amount.RD = 1e15
|
||||
world.state.amount.BG = 1e15
|
||||
world.state.amount["C3.0"] = 6.0
|
||||
world.initialize_life_batches()
|
||||
world.evolution.initialize_life_batches()
|
||||
check(world.state.amount["C3.0"] == 0.0 and world.state.amount["C2.9"] == 6.0, "Missing mandatory structures degrade existing civilizations")
|
||||
invariants(world)
|
||||
dispose(world)
|
||||
|
||||
Reference in New Issue
Block a user