Add new tests and implement frame budget management
- 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.
This commit is contained in:
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
extends "res://stage/stage.gd"
|
||||
|
||||
var measuring: bool = false
|
||||
var process_samples: Array = []
|
||||
var frame_samples: Array = []
|
||||
var previous_frame: int = 0
|
||||
|
||||
# Exercise the production Stage, with isolated state and no player-save I/O.
|
||||
func load_data() -> bool: return false
|
||||
func save_data() -> void: pass
|
||||
func _notification(_what: int) -> void: pass
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not measuring: return
|
||||
var started: int = Time.get_ticks_usec()
|
||||
if previous_frame: frame_samples.append((started - previous_frame) / 1000.0)
|
||||
previous_frame = started
|
||||
super._process(delta)
|
||||
process_samples.append((Time.get_ticks_usec() - started) / 1000.0)
|
||||
+1
@@ -0,0 +1 @@
|
||||
uid://d1wm7nav71y3o
|
||||
+1
File diff suppressed because one or more lines are too long
+30
@@ -0,0 +1,30 @@
|
||||
extends RefCounted
|
||||
const E = preload("res://world/owniverse/math/exact.gd")
|
||||
|
||||
static func seed(world, global, fragmented: bool = false, large: bool = false, stable: bool = false):
|
||||
for id in world.catalog.entities:
|
||||
world.state.amount[id] = 0
|
||||
world.state.stats.total_amount[id] = 0
|
||||
var entity = world.catalog.entities[id]
|
||||
if entity.group_as != "":
|
||||
world.state.amount[entity.group_as] = 0
|
||||
world.state.stats.total_amount[entity.group_as] = 0
|
||||
for id in ["RD", "BG", "TWD", "SNS", "MGT", "BH25", "SMBH", "SCD", "GEM", "LGG", "LSC", "LGF", "LGW", "LUB"]:
|
||||
world.state.amount[id] = E.of("1e48")
|
||||
world.state.amount.S = E.of("1e50")
|
||||
world.state.amount.H = E.of("1e48")
|
||||
world.state.binds.RD = {"HP": E.of("1e30"), "RP": E.of("1e30"), "GG": E.of("1e30"), "AB": E.of("1e30")}
|
||||
var count = E.of("6e20") if large else 6000
|
||||
for id in global.CivilizationRules:
|
||||
if E.le(global.CivilizationRules[id].span, 0): continue
|
||||
world.state.amount[id] = count
|
||||
world.state.ethics[id] = {}
|
||||
for ethic in ["m", "l", "w", "d", "c", "b"]:
|
||||
world.state.ethics[id][ethic] = E.divide(count, 6)
|
||||
world.state.batches[id] = []
|
||||
var parties: int = 10 if fragmented else 1
|
||||
for i in parties:
|
||||
var lifespan = E.of(global.CivilizationRules[id].span) if stable else 1
|
||||
world.state.batches[id].append({"amount": E.divide(count, parties), "created_from": i * 100, "created_to": 1000 + i * 100, "start_year": E.add(lifespan, i * 100), "end_year": E.add(lifespan, 1000 + i * 100)})
|
||||
world.ledger.refresh_groups(world.state)
|
||||
world.speed = 6
|
||||
@@ -0,0 +1 @@
|
||||
uid://bjloakx4qdpsj
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
extends RefCounted
|
||||
const E = preload("res://world/owniverse/math/exact.gd")
|
||||
# Frozen apportionment before the civilization performance refactor.
|
||||
|
||||
static func allocate_whole(requests: Dictionary, limit: Variant) -> Dictionary:
|
||||
var total: Variant = 0
|
||||
for amount in requests.values():
|
||||
total = E.add(total, E.floor_value(E.maximum(0, amount)))
|
||||
var available: Variant = E.floor_value(E.minimum(E.maximum(0, limit), total))
|
||||
var result: Dictionary = {}
|
||||
var order: Array = []
|
||||
var assigned: Variant = 0
|
||||
for id in requests:
|
||||
var expected: Variant = (E.mul_div(E.floor_value(E.maximum(0, requests[id])), available, total) if E.gt(total, 0) else 0)
|
||||
result[id] = E.floor_value(expected)
|
||||
assigned = E.add(assigned, result[id])
|
||||
order.append({"id": id, "rest": E.subtract(expected, result[id])})
|
||||
order.sort_custom(func ( a : Dictionary , b : Dictionary ) -> bool : return (E.gt(a.rest, b.rest) if E.ne(a.rest, b.rest) else E.lt(str(a.id), str(b.id))))
|
||||
for item : Dictionary in order:
|
||||
if E.ge(assigned, available):
|
||||
break
|
||||
if E.lt(result[item.id], E.floor_value(requests[item.id])):
|
||||
result[item.id] = E.add(result[item.id], 1)
|
||||
assigned = E.add(assigned, 1)
|
||||
return result
|
||||
|
||||
|
||||
static func sum(pop: Dictionary) -> Variant:
|
||||
var result: Variant = 0
|
||||
for n in pop.values(): result = E.add(result, n)
|
||||
return result
|
||||
|
||||
|
||||
static func split(remainders: Dictionary, key: String, count: Variant, weights: Dictionary) -> Dictionary:
|
||||
var result: Dictionary = {}
|
||||
var sum_weights: Variant = sum(weights)
|
||||
if (E.le(count, 0) or E.le(sum_weights, 0)): return result
|
||||
var expected: Dictionary = {}
|
||||
var positive_sum: Variant = 0
|
||||
for id in weights:
|
||||
expected[id] = E.add(E.mul_div(count, weights[id], sum_weights), remainders.get(E.add(E.add(key, ":"), id), 0))
|
||||
positive_sum = E.add(positive_sum, E.maximum(0, expected[id]))
|
||||
var order: Array = []
|
||||
var assigned: Variant = 0
|
||||
for id in weights:
|
||||
var normalized: Variant = (E.mul_div(E.maximum(0, expected[id]), count, positive_sum) if E.gt(positive_sum, 0) else 0)
|
||||
result[id] = E.floor_value(normalized)
|
||||
assigned = E.add(assigned, result[id])
|
||||
order.append({"id": id, "rest": E.subtract(normalized, result[id])})
|
||||
order.sort_custom(func ( a , b ) : return (E.gt(a.rest, b.rest) if E.ne(a.rest, b.rest) else E.lt(str(a.id), str(b.id))))
|
||||
for entry in order:
|
||||
if E.ge(assigned, count): break
|
||||
result[entry.id] = E.add(result[entry.id], 1)
|
||||
assigned = E.add(assigned, 1)
|
||||
for id in weights:
|
||||
remainders[E.add(E.add(key, ":"), id)] = E.clamp_value(E.subtract(expected[id], result[id]), E.neg(1), 1)
|
||||
return result
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
uid://dxsly3qpyqrjy
|
||||
Reference in New Issue
Block a user