fix: preserve deterministic decisions across saves
This commit is contained in:
@@ -27,7 +27,7 @@ func update_modifiers() -> void:
|
||||
food_modifier = 2.0
|
||||
if wood <= 0:
|
||||
wood_modifier = 2.0
|
||||
if safety < 20:
|
||||
if _strictly_below(safety, 20.0):
|
||||
safety_modifier = 2.0
|
||||
if knowledge > 25:
|
||||
knowledge_modifier = 0.75
|
||||
@@ -46,24 +46,24 @@ func update_priorities() -> void:
|
||||
safety_priority = 1.0
|
||||
knowledge_priority = 1.0
|
||||
|
||||
if food < 10.0:
|
||||
if _strictly_below(food, 10.0):
|
||||
food_priority = 3.0
|
||||
elif food < 20.0:
|
||||
elif _strictly_below(food, 20.0):
|
||||
food_priority = 2.0
|
||||
|
||||
if wood < 5.0:
|
||||
if _strictly_below(wood, 5.0):
|
||||
wood_priority = 2.5
|
||||
elif wood < 15.0:
|
||||
elif _strictly_below(wood, 15.0):
|
||||
wood_priority = 1.75
|
||||
|
||||
if safety < 25.0:
|
||||
if _strictly_below(safety, 25.0):
|
||||
safety_priority = 3.0
|
||||
elif safety < 50.0:
|
||||
elif _strictly_below(safety, 50.0):
|
||||
safety_priority = 1.5
|
||||
|
||||
if knowledge < 5.0:
|
||||
if _strictly_below(knowledge, 5.0):
|
||||
knowledge_priority = 1.75
|
||||
elif knowledge < 15.0:
|
||||
elif _strictly_below(knowledge, 15.0):
|
||||
knowledge_priority = 1.25
|
||||
|
||||
if debug_logs:
|
||||
@@ -147,3 +147,9 @@ func get_priority_summary() -> String:
|
||||
func debug_log(message: String) -> void:
|
||||
if debug_logs:
|
||||
print("[Village] ", message)
|
||||
|
||||
|
||||
static func _strictly_below(value: float, threshold: float) -> bool:
|
||||
# JSON round trips can normalize a value a few ULPs below a threshold to the
|
||||
# exact decimal. Treat that boundary identically before and after saving.
|
||||
return value < threshold and not is_equal_approx(value, threshold)
|
||||
|
||||
@@ -1359,6 +1359,10 @@ func restore_state(record: SimulationStateRecord) -> bool:
|
||||
village = record.village.restore(debug_logs)
|
||||
economy.configure(village, debug_logs)
|
||||
economy.restore_storage(record.storages)
|
||||
# Priorities and modifiers are deterministic derived state, not save payload.
|
||||
# Rebuild them before the next decision so save/load cannot change outcomes.
|
||||
village.update_modifiers()
|
||||
village.update_priorities()
|
||||
event_log.restore(record.economic_events, int(record.simulation["next_event_id"]))
|
||||
latest_decisions.clear()
|
||||
npcs.clear()
|
||||
|
||||
@@ -138,7 +138,19 @@ static func from_dictionary(record_data: Dictionary) -> KnownEventStateRecord:
|
||||
or hop_count != 0
|
||||
):
|
||||
return null
|
||||
return KnownEventStateRecord.new(normalized)
|
||||
return create(
|
||||
knower_id,
|
||||
event_id,
|
||||
acquisition_method,
|
||||
source_npc_id,
|
||||
acquired_tick,
|
||||
source_acquisition_method,
|
||||
hop_count,
|
||||
confidence,
|
||||
salience,
|
||||
source_actor_id,
|
||||
bool(normalized["pinned"])
|
||||
)
|
||||
|
||||
|
||||
func get_knower_id() -> int:
|
||||
|
||||
@@ -89,6 +89,11 @@ static func from_dictionary(record_data: Dictionary) -> RelationshipStateRecord:
|
||||
return null
|
||||
if cause_event_id < NO_CAUSE_EVENT:
|
||||
return null
|
||||
normalized[String(dimension)] = value
|
||||
normalized[_cause_key(dimension)] = cause_event_id
|
||||
normalized["schema_version"] = SCHEMA_VERSION
|
||||
normalized["observer_id"] = observer_id
|
||||
normalized["subject_id"] = subject_id
|
||||
return RelationshipStateRecord.new(normalized)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://becxio7ec31yj
|
||||
Reference in New Issue
Block a user