2026-09-15 23:05:05 +03:00
extends SceneTree
2026-09-30 08:08:27 +03:00
const E = preload ( "res://world/owniverse/math/exact.gd" )
2026-09-15 23:05:05 +03:00
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 :
2026-09-30 08:08:27 +03:00
checks = E . add ( checks , 1 )
if ( not condition ):
failures = E . add ( failures , 1 )
2026-09-15 23:05:05 +03:00
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 ])
2026-09-29 20:23:20 +03:00
world . catalog . entities [ id ] = entity
2026-09-30 08:08:27 +03:00
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
2026-09-29 20:23:20 +03:00
world . catalog . entities [ "N" ] . life_product = {}
world . catalog . entities [ "N" ] . product_per_year_type = "H"
2026-09-30 08:08:27 +03:00
world . catalog . entities [ "N" ] . product_per_year_amount = 10
world . catalog . entities [ "N" ] . auto = 0
world . state . amount . N = 1
2026-09-15 23:05:05 +03:00
return world
func dispose ( world ) -> void :
2026-09-29 20:23:20 +03:00
for entity in world . catalog . entities . values ():
2026-09-15 23:05:05 +03:00
entity . free ()
world . free ()
func run () -> void :
var world = fixture ()
2026-09-30 08:08:27 +03:00
world . state . amount . N = 0
world . state . amount . HP = 40000
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
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" )
2026-09-15 23:05:05 +03:00
var before : Dictionary = world . state . duplicate ( true )
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
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" )
2026-09-29 20:23:20 +03:00
var physical : Dictionary = world . ledger . physical_amounts ( world . state )
2026-09-30 08:08:27 +03:00
check ( E . eq ( E . add ( E . add ( physical . HP , physical . EON1 ), physical . RP ), 40000 ), "Life conserves planets" )
2026-10-06 23:02:42 +03:00
check ( E . eq ( root . get_node ( "SaveManager" ) . validate_data ({ "format_version" : 6 , "app_version" : "" , "ui" : { "current_page" : 0 }, "state" : world . state }), "" ), "Life save validates" )
2026-09-15 23:05:05 +03:00
var restored = fixture ()
2026-09-30 08:08:27 +03:00
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" )
2026-09-15 23:05:05 +03:00
dispose ( restored )
dispose ( world )
world = fixture ()
2026-09-30 08:08:27 +03:00
world . state . amount . RD = 1
world . state . binds . RD = { "EON5" : 40000 }
2026-10-05 22:16:59 +03:00
# Test host preservation with a fixed rate, independent of game balance.
world . catalog . entities . EON5 . life_rule . progress = "0.00025"
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
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" )
2026-09-15 23:05:05 +03:00
check ( world . state . batches . has ( "C0.0" ), "New C0.0 starts civilization evolution" )
dispose ( world )
world = fixture ()
2026-09-30 08:08:27 +03:00
var progress : Variant = 0
var degraded : Variant = 0
2026-09-15 23:05:05 +03:00
var valid_outcomes : bool = true
for i in 4001 :
2026-09-30 08:08:27 +03:00
var products : Dictionary = world . life . life_products ( world . state , world . catalog . entities . HP , 1 )
var total : Variant = 0
2026-09-15 23:05:05 +03:00
for value in products . values ():
2026-09-30 08:08:27 +03:00
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 ))
2026-09-15 23:05:05 +03:00
check ( valid_outcomes , "Every single-planet attempt has whole outcomes and conserves population" )
2026-09-30 08:08:27 +03:00
check (( E . eq ( progress , 1 ) and E . eq ( degraded , 10 )), "Rare outcomes accumulate deterministically" )
2026-09-15 23:05:05 +03:00
dispose ( world )
world = fixture ()
2026-09-30 08:08:27 +03:00
world . state . time = { "datetime" : E . of ( "123.4" ), "year" : E . of ( "123.4" )}
world . state . binds . RD = { "HP" : 2 }
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
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" )
2026-09-15 23:05:05 +03:00
dispose ( world )
world = fixture ()
2026-09-30 08:08:27 +03:00
world . state . time = { "datetime" : E . of ( "123.4" ), "year" : E . of ( "123.4" )}
world . state . amount [ "C0.0" ] = 40000
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
check ( E . eq ( world . state . batches [ "C0.0" ][ 0 ] . created_from , E . of ( "123.4" )), "Civilization cohorts begin at the current time" )
2026-09-15 23:05:05 +03:00
before = world . state . duplicate ( true )
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
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" )
2026-09-15 23:05:05 +03:00
dispose ( world )
world = fixture ()
2026-09-30 08:08:27 +03:00
world . state . amount . RD = 1
world . state . binds . RD = { "C0.1" : 40000 }
2026-09-29 20:23:20 +03:00
world . evolution . initialize_life_batches ()
2026-09-30 08:08:27 +03:00
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" )
2026-10-06 23:02:42 +03:00
check ( E . eq ( root . get_node ( "SaveManager" ) . validate_data ({ "format_version" : 6 , "app_version" : "" , "ui" : { "current_page" : 0 }, "state" : world . state }), "" ), "Extended life save validates" )
2026-09-15 23:05:05 +03:00
dispose ( world )
2026-09-30 08:08:27 +03:00
print (( "Life: %d checks, %d failures" % [ checks , failures ]))
quit (( 0 if E . eq ( failures , 0 ) else 1 ))