Implement gradual evolution mechanics and simulation time handling in Owniverse.GI

- Added `blastability` property to entities for vulnerability tracking.
- Enhanced planet string parsing with validation and error handling.
- Introduced `simulation_rules.md` to document evolution mechanics and rules.
- Created tests for time progression and stellar evolution rules, ensuring correct handling of fractional years and resource production.
- Implemented `simulation_time.gd` for managing accumulated time and year processing.
- Updated tests to validate legacy save compatibility and migration to new time schema.
This commit is contained in:
Kirill
2026-09-15 08:27:04 +03:00
parent 7de65f6145
commit 5f5cc6f894
13 changed files with 647 additions and 28 deletions
+12 -6
View File
@@ -6,7 +6,8 @@ const SETTING_SECTION := "Settings"
const SAVE_PATH = "user://settings.cfg"
const FORMAT_VERSION: int = 1
const STATE_VERSION: String = "0.1.0"
const SimulationTime = preload("res://world/owniverse/simulation_time.gd")
const STATE_VERSION: String = SimulationTime.STATE_VERSION
var last_error: String = ""
var blocked_saves: Dictionary = {}
@@ -123,14 +124,19 @@ func validate_data(data: Variant) -> String:
if not data.ui is Dictionary or not data.ui.get("current_page") is int or data.ui.current_page < 0:
return "invalid ui.current_page"
var saved: Dictionary = data.state
if saved.get("version") != STATE_VERSION:
if saved.get("version") not in [STATE_VERSION, SimulationTime.LEGACY_VERSION]:
return "unsupported state.version"
if not saved.get("time") is Dictionary:
return "state.time must be a Dictionary"
if not _number(saved.time.get("datetime")) or not _number(saved.time.get("year"), true):
if not _number(saved.time.get("datetime")) or not _number(saved.time.get("year")):
return "invalid state.time"
if saved.time.year != floorf(saved.time.datetime):
return "state.time.year must equal floor(datetime)"
if not is_finite(float(saved.time.datetime) * 10.0):
return "state.time exceeds supported precision range"
var expected_year: float = SimulationTime.processed_year(saved.time.datetime)
if saved.version == SimulationTime.LEGACY_VERSION:
expected_year = floorf(saved.time.datetime)
if saved.time.year != expected_year:
return "state.time.year does not match the processed time for this version"
if not _number(saved.get("speed"), true) or saved.speed < 1 or saved.speed > Global.SPEED_LIMIT:
return "invalid state.speed"
if not _number(saved.get("speed_in_year")) or saved.speed_in_year != pow(10.0, saved.speed - 1):
@@ -172,7 +178,7 @@ func validate_data(data: Variant) -> String:
return "invalid batch.processed_until in " + id
if batch.has("withdraw_remainder") and (not _number(batch.withdraw_remainder) or batch.withdraw_remainder > batch.amount):
return "invalid batch.withdraw_remainder in " + id
for field in ["batch_origins", "distribution", "auto_resources", "production_remainders", "auto_star_deficits", "evolution_remainders"]:
for field in ["batch_origins", "distribution", "auto_resources", "production_remainders", "auto_star_deficits", "evolution_remainders", "planet_remainders", "blast_remainders", "destruction_remainders"]:
if saved.has(field) and not _number_map(saved[field], field == "auto_resources", field != "auto_star_deficits"):
return "invalid state." + field
if saved.has("resource_remainders"):