Files
owniverse/tests/benchmark_many_objects.gd
T

112 lines
6.1 KiB
GDScript
Raw Normal View History

extends "res://tests/benchmark_large_star_cohorts.gd"
## Fresh all-object stress world with many valid cohorts sharing death cycles.
const Fixture = preload("res://tests/fixtures/civilization_benchmark.gd")
var death_cycles: int = 40
var fragments_per_cycle: int = 8
func _initialize():
artifact_prefix = "many_objects_fragmented_stars"
cycles = 40
call_deferred("run")
func make_state(_initial: Dictionary, use_cycles: bool) -> Dictionary:
var world = load("res://world/owniverse/owniverse.gd").new()
world.catalog.load_definitions(root.get_node("Global").OwniverseEntities)
var global: Node = root.get_node("Global")
Fixture.seed(world, global)
world.batches.cycle_stars = use_cycles
var anchor: Variant = E.of("1e12")
var stock: Variant = E.of("1e60")
var planets: Variant = E.of("1e28")
world.state.time = {"datetime": anchor, "year": anchor}
world.state.energy = E.of("1e100")
world.state.batches = {}
world.state.batch_origins = {}
world.state.binds = {}
world.state.ethics = {}
for id in world.catalog.entities:
world.state.amount[id] = 0 if world.catalog.is_group(id) else (planets if world.catalog.entities[id].group_as == "Planet" else stock)
world.state.stats.total_amount[id] = world.state.amount[id]
# Keep the synthetic universe sparse enough for blast damage to coexist
# with all life stages instead of sterilizing them on the first cycle.
world.state.amount.S = E.of("1e300")
world.state.amount.H = E.of("1e80")
world.state.amount.He = E.of("1e79")
world.state.amount.Met = E.of("1e79")
var dwarfs: Array = ["RD", "OD", "YD", "WYD"]
var stages: int = 0
for id in global.CivilizationRules:
world.state.amount[id] = planets
var weights: Array = [0.35, 0.2, 0.15, 0.12, 0.1, 0.08]
var profile: Dictionary = {}
var ethics: Array = ["m", "l", "w", "d", "c", "b"]
for e in 6: profile[ethics[e]] = weights[(e + stages) % 6]
world.state.ethics[id] = profile
stages += 1
# Planetary stages are hosted by all four kinds of dwarf stars.
for id in world.catalog.entities:
if world.catalog.entities[id].group_as != "Planet" or world.catalog.is_group(id): continue
if global.CivilizationRules.has(id) and str(global.CivilizationRules[id].home) != "": continue
var held: Variant = E.divide(world.state.amount[id], 4)
world.state.amount[id] = 0
for dwarf in dwarfs:
if not world.state.binds.has(dwarf): world.state.binds[dwarf] = {}
world.state.binds[dwarf][id] = held
# Bound stars remain physical and continue producing inside structures.
var structures: Array = ["SCD", "SCM", "SCG", "GEM", "GSD"]
var stellar_types: int = 0
for id in world.catalog.entities:
if world.catalog.entities[id].group_as != "Star" or E.le(world.catalog.entities[id].lifespan, 0): continue
var held: Variant = E.divide(stock, 4)
var owner: String = structures[stellar_types % structures.size()]
if not world.state.binds.has(owner): world.state.binds[owner] = {}
world.state.binds[owner][id] = held
world.state.amount[id] = E.subtract(stock, held)
stellar_types += 1
world.ledger.refresh_groups(world.state)
var physical: Dictionary = world.ledger.physical_amounts(world.state)
var active_types: int = 0
for id in world.catalog.entities:
if world.catalog.is_group(id) or E.le(physical.get(id, 0), 0): continue
active_types += 1
world.state.stats.total_amount[id] = physical[id]
var entity = world.catalog.entities[id]
if E.le(entity.lifespan, 0) or global.CivilizationRules.has(id): continue
if entity.group_as != "Star":
world.batches.append_batch(world.state, id, physical[id], anchor, anchor)
continue
# Valid but deliberately fragmented historical age cohorts. The test
# stresses merge eligibility, rather than claiming these are produced
# by the ordinary steady-state creation path with one fixed origin.
var span: Variant = world.batches.effective_lifespan(world.state, id)
var count: int = death_cycles * fragments_per_cycle
var assigned: Variant = 0
world.state.batches[id] = []
for n in count:
var cycle: int = n / fragments_per_cycle
var fragment: int = n % fragments_per_cycle
var start: Variant = E.add(anchor, cycle * 20000 + (fragment + 1) * 1800)
var end: Variant = E.add(start, 500)
var quota: Variant = E.floor_value(E.mul_div(physical[id], n + 1, count))
world.state.batches[id].append({"amount": E.subtract(quota, assigned), "created_from": E.subtract(start, span), "created_to": E.subtract(end, span), "start_year": start, "end_year": end})
assigned = quota
assert(E.eq(assigned, physical[id]))
world.state.batch_origins[id] = world.state.batches[id][0].created_from
var raw_cohorts: int = cohort_count(world)
world.batches.coarsen(world.state)
var payload: Dictionary = {"format_version": 6, "app_version": "0.7.0", "ui": {"current_page": 0}, "state": world.state,
"simulation": {"active_clock": {}, "requested_clock": {}, "productions": [], "speed": 6}}
var error: String = root.get_node("SaveManager").validate_data(payload)
assert(error.is_empty(), error)
var suffix: String = "cycle" if use_cycles else "legacy"
var path: String = "res://tests/artifacts/%s_%s.adventure.json" % [artifact_prefix, suffix]
var output = FileAccess.open(path, FileAccess.WRITE)
assert(output != null)
output.store_string(JSON.stringify(E.encode(payload), " ", true, true))
output.close()
var restored: Dictionary = E.decode(restore_json_integers(JSON.parse_string(FileAccess.get_file_as_string(path))))
assert(E.eq(restored.state, world.state), "Save roundtrip changed the stress state")
print("Generated %s: active_types=%d civilization_stages=%d stellar_types=%d raw_cohorts=%d stored_stellar_cohorts=%d" % [suffix, active_types, stages, stellar_types, raw_cohorts, cohort_count(world)])
dispose(world)
return restored.state