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:
Kirill
2026-09-29 20:23:20 +03:00
parent da03ba11c0
commit f2111a376a
42 changed files with 1681 additions and 1704 deletions
+17 -17
View File
@@ -12,7 +12,7 @@ static func is_space_civilization(id: String, rules: Dictionary) -> bool:
static func reconcile(world, target: Dictionary, rules: Dictionary) -> void:
if not target.has("ethics"):
target.ethics = {}
var physical: Dictionary = world._physical_amounts(target)
var physical: Dictionary = world.ledger.physical_amounts(target)
for id in rules:
var count: float = physical.get(id, 0.0)
var current: Dictionary = target.ethics.get(id, {})
@@ -40,10 +40,10 @@ static func detach_space_civilizations(target: Dictionary, rules: Dictionary) ->
# A shared budget per stellar family, including stars bound into structures.
# Reservations affect capacity, not the physical stock or its production.
static func stellar_budget(world, target: Dictionary, rules: Dictionary) -> Dictionary:
var physical: Dictionary = world._physical_amounts(target)
var physical: Dictionary = world.ledger.physical_amounts(target)
var capacity: Dictionary = {}
for id in physical:
var entity = world.entities[id]
var entity = world.catalog.entities[id]
for home in ["DwStar", "GiStar", "WD", "NS", "MGT", "BH"]:
if entity.event_group == home or entity.count_as == home or id == home:
capacity[home] = capacity.get(home, 0.0) + physical[id]
@@ -129,10 +129,10 @@ static func enforce_capacity(world, target: Dictionary, rules: Dictionary, year:
if excess <= 0.0:
continue
var previous: String = stages[index - 1] if index > 0 else "C1.9"
world._scale_batches(target, id, supported / count)
world.batches.scale_batches(target, id, supported / count)
target.amount[id] = supported
world._credit(target, previous, excess)
world._append_batch(target, previous, excess, year, year)
world.ledger.credit(target, previous, excess)
world.batches.append_batch(target, previous, excess, year, year)
var removed: Dictionary = QuantityMath.allocate_whole(target.ethics[id], excess)
if not target.ethics.has(previous):
target.ethics[previous] = {}
@@ -141,9 +141,9 @@ static func enforce_capacity(world, target: Dictionary, rules: Dictionary, year:
target.ethics[previous][ethic] = target.ethics[previous].get(ethic, 0.0) + removed[ethic]
if previous == "C1.9":
var stars: Dictionary = {}
var physical: Dictionary = world._physical_amounts(target)
var physical: Dictionary = world.ledger.physical_amounts(target)
for star in physical:
if world.entities[star].event_group == "DwStar" and physical[star] > 0.0:
if world.catalog.entities[star].event_group == "DwStar" and physical[star] > 0.0:
stars[star] = physical[star]
var weights: Dictionary = QuantityMath.normalize_distribution(stars)
# Worlds are aggregates: a star may host several inhabited planets.
@@ -164,16 +164,16 @@ static func enforce_capacity(world, target: Dictionary, rules: Dictionary, year:
# Unity's structure chain: direct Claim resets the required structure count;
# intervening stages require ten times more units of the preceding structure.
static func habitat_budget(world, target: Dictionary, rules: Dictionary) -> Dictionary:
var physical: Dictionary = world._physical_amounts(target)
var physical: Dictionary = world.ledger.physical_amounts(target)
var structures: Array = []
var capacity: Dictionary = {}
for id in world.entities:
if world.entities[id].claim != "":
for id in world.catalog.entities:
if world.catalog.entities[id].claim != "":
structures.append(id)
capacity[id] = physical.get(id, 0.0)
structures.sort_custom(func(a, b):
var left: float = world.entities[a].civ_bonus
var right: float = world.entities[b].civ_bonus
var left: float = world.catalog.entities[a].civ_bonus
var right: float = world.catalog.entities[b].civ_bonus
return left > right if left != right else str(a) < str(b))
var stages: Array = []
for id in rules:
@@ -186,7 +186,7 @@ static func habitat_budget(world, target: Dictionary, rules: Dictionary) -> Dict
for id in stages:
var direct: String = ""
for structure in structures:
if world.entities[structure].claim == id: direct = structure
if world.catalog.entities[structure].claim == id: direct = structure
if direct != "":
anchor = direct
units = 1.0
@@ -216,7 +216,7 @@ static func assign_homes(world, target: Dictionary, rules: Dictionary) -> void:
if structure == budget.anchors[id]: allowed = true
if not allowed or budget.capacity[structure] <= 0.0: continue
var amount: float = left
if world.entities[structure].claim == id:
if world.catalog.entities[structure].claim == id:
amount = minf(amount, maxf(0.0, budget.capacity[structure] - used.get(structure, 0.0)))
used[structure] = used.get(structure, 0.0) + amount
if amount > 0.0: homes[structure] = amount
@@ -225,7 +225,7 @@ static func assign_homes(world, target: Dictionary, rules: Dictionary) -> void:
target.civilization_homes[id] = homes
static func effective_span(world, target: Dictionary, id: String, rules: Dictionary) -> float:
if not rules.has(id): return world.entities[id].lifespan
if not rules.has(id): return world.catalog.entities[id].lifespan
var base: float = rules[id].span
if not is_space_civilization(id, rules): return base
assign_homes(world, target, rules)
@@ -233,5 +233,5 @@ static func effective_span(world, target: Dictionary, id: String, rules: Diction
if population <= 0.0: return base
var weighted: float = population
for home in target.civilization_homes.get(id, {}):
weighted += target.civilization_homes[id][home] * (maxf(0.0, world.entities[home].civ_bonus) - 1.0)
weighted += target.civilization_homes[id][home] * (maxf(0.0, world.catalog.entities[home].civ_bonus) - 1.0)
return base * population / weighted if weighted > 0.0 else base