feat: add witnessed knowledge and wind ambience
This commit is contained in:
@@ -14,6 +14,9 @@ func _run() -> void:
|
||||
_test_legacy_resource_migration()
|
||||
_test_legacy_world_storage_migration()
|
||||
_test_previous_world_event_migration()
|
||||
_test_previous_world_relationship_migration()
|
||||
_test_previous_world_knowledge_migration()
|
||||
_test_relationship_schema_rejection()
|
||||
_test_schema_rejection()
|
||||
|
||||
if failures.is_empty():
|
||||
@@ -157,8 +160,10 @@ func _test_legacy_resource_migration() -> void:
|
||||
"Resource migration should preserve mutable authority"
|
||||
)
|
||||
_check(
|
||||
is_equal_approx(migrated.get_safety_risk(), 0.0)
|
||||
and is_equal_approx(migrated.get_comfort_distance(), 18.0),
|
||||
(
|
||||
is_equal_approx(migrated.get_safety_risk(), 0.0)
|
||||
and is_equal_approx(migrated.get_comfort_distance(), 18.0)
|
||||
),
|
||||
"Resource migration should default discovery metadata"
|
||||
)
|
||||
|
||||
@@ -190,9 +195,7 @@ func _test_legacy_world_storage_migration() -> void:
|
||||
var migrated_storages := {}
|
||||
for storage in migrated.storages:
|
||||
migrated_storages[storage.get_storage_id()] = storage
|
||||
var pantry: StorageStateRecord = migrated_storages.get(
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY
|
||||
)
|
||||
var pantry: StorageStateRecord = migrated_storages.get(SimulationIds.STORAGE_VILLAGE_PANTRY)
|
||||
var woodpile: StorageStateRecord = migrated_storages.get(
|
||||
SimulationIds.STORAGE_VILLAGE_WOODPILE
|
||||
)
|
||||
@@ -200,8 +203,12 @@ func _test_legacy_world_storage_migration() -> void:
|
||||
(
|
||||
pantry != null
|
||||
and woodpile != null
|
||||
and is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), manager.village.food)
|
||||
and is_equal_approx(woodpile.get_amount(SimulationIds.RESOURCE_WOOD), manager.village.wood)
|
||||
and is_equal_approx(
|
||||
pantry.get_amount(SimulationIds.RESOURCE_FOOD), manager.village.food
|
||||
)
|
||||
and is_equal_approx(
|
||||
woodpile.get_amount(SimulationIds.RESOURCE_WOOD), manager.village.wood
|
||||
)
|
||||
),
|
||||
"World migration should preserve legacy village resources in their storage"
|
||||
)
|
||||
@@ -211,7 +218,7 @@ func _test_legacy_world_storage_migration() -> void:
|
||||
func _test_previous_world_event_migration() -> void:
|
||||
var manager := _create_manager(56)
|
||||
var previous_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
previous_data["schema_version"] = (SimulationStateRecord.PREVIOUS_SCHEMA_VERSION)
|
||||
previous_data["schema_version"] = SimulationStateRecord.EVENT_LEGACY_SCHEMA_VERSION
|
||||
previous_data.erase("economic_events")
|
||||
previous_data["simulation"].erase("next_event_id")
|
||||
var migrated := SimulationStateRecord.from_dictionary(previous_data)
|
||||
@@ -224,6 +231,169 @@ func _test_previous_world_event_migration() -> void:
|
||||
manager.free()
|
||||
|
||||
|
||||
func _test_previous_world_relationship_migration() -> void:
|
||||
var manager := _create_manager(57)
|
||||
var previous_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
previous_data["schema_version"] = SimulationStateRecord.RELATIONSHIP_LEGACY_SCHEMA_VERSION
|
||||
previous_data.erase("relationships")
|
||||
previous_data.erase("event_knowledge")
|
||||
for npc_data in previous_data["npcs"]:
|
||||
npc_data["schema_version"] = NPCStateRecord.RELATIONSHIP_LEGACY_SCHEMA_VERSION
|
||||
npc_data["familiarity"] = []
|
||||
previous_data["npcs"][0]["familiarity"] = [{"id": 1, "score": 0.75}]
|
||||
var migrated := SimulationStateRecord.from_dictionary(previous_data)
|
||||
_check(migrated != null, "World schema v3 should migrate NPC familiarity into relationships")
|
||||
if migrated != null:
|
||||
_check(
|
||||
(
|
||||
migrated.relationships.size() == 1
|
||||
and migrated.relationships[0].get_observer_id() == 0
|
||||
and migrated.relationships[0].get_subject_id() == 1
|
||||
and is_equal_approx(migrated.relationships[0].get_familiarity(), 0.75)
|
||||
and is_equal_approx(
|
||||
migrated.relationships[0].get_trust(), RelationshipStateRecord.NEUTRAL_TRUST
|
||||
)
|
||||
),
|
||||
"World v3 migration should preserve familiarity and initialize neutral trust"
|
||||
)
|
||||
_check(
|
||||
not migrated.npcs[0].data.has("familiarity"),
|
||||
"World v3 migration should remove obsolete NPC-local familiarity data"
|
||||
)
|
||||
manager.free()
|
||||
|
||||
|
||||
func _test_previous_world_knowledge_migration() -> void:
|
||||
var manager := _create_manager(59)
|
||||
var previous_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
previous_data["schema_version"] = SimulationStateRecord.PREVIOUS_SCHEMA_VERSION
|
||||
previous_data.erase("event_knowledge")
|
||||
var deposit_event := EconomicEventRecord.create(
|
||||
0,
|
||||
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
||||
12,
|
||||
1,
|
||||
SimulationIds.npc_inventory_id(1),
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
||||
SimulationIds.RESOURCE_FOOD,
|
||||
2.0
|
||||
)
|
||||
previous_data["economic_events"] = [deposit_event.to_dictionary()]
|
||||
previous_data["simulation"]["next_event_id"] = 1
|
||||
previous_data["relationships"] = [
|
||||
RelationshipStateRecord.create(0, 1, 0.5, 0.65, 0).to_dictionary()
|
||||
]
|
||||
var migrated := SimulationStateRecord.from_dictionary(previous_data)
|
||||
_check(migrated != null, "World schema v4 should migrate causal facts into NPC knowledge")
|
||||
if migrated != null:
|
||||
_check(
|
||||
(
|
||||
migrated.event_knowledge.size() == 1
|
||||
and migrated.event_knowledge[0].get_knower_id() == 0
|
||||
and migrated.event_knowledge[0].get_event_id() == 0
|
||||
),
|
||||
"World v4 migration should preserve the fact implied by a relationship cause"
|
||||
)
|
||||
manager.free()
|
||||
|
||||
|
||||
func _test_relationship_schema_rejection() -> void:
|
||||
var manager := _create_manager(58)
|
||||
var missing_cause_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
missing_cause_data["relationships"] = [
|
||||
RelationshipStateRecord.create(0, 1, 0.5, 0.65, 999).to_dictionary()
|
||||
]
|
||||
_check(
|
||||
SimulationStateRecord.from_dictionary(missing_cause_data) == null,
|
||||
"Relationship causes must reference an event in the same world record"
|
||||
)
|
||||
|
||||
var duplicate_pair_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
var relationship_data := RelationshipStateRecord.create(0, 1, 0.5).to_dictionary()
|
||||
duplicate_pair_data["relationships"] = [relationship_data, relationship_data.duplicate(true)]
|
||||
_check(
|
||||
SimulationStateRecord.from_dictionary(duplicate_pair_data) == null,
|
||||
"World state should reject duplicate directed relationship pairs"
|
||||
)
|
||||
|
||||
var unknown_knowledge_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
unknown_knowledge_data["event_knowledge"] = [
|
||||
KnownEventStateRecord.create(0, 999).to_dictionary()
|
||||
]
|
||||
_check(
|
||||
SimulationStateRecord.from_dictionary(unknown_knowledge_data) == null,
|
||||
"Known-event records must reference an event in the same world record"
|
||||
)
|
||||
var duplicate_knowledge_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
var event := EconomicEventRecord.create(
|
||||
0,
|
||||
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
||||
1,
|
||||
0,
|
||||
SimulationIds.npc_inventory_id(0),
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
||||
SimulationIds.RESOURCE_FOOD,
|
||||
1.0
|
||||
)
|
||||
duplicate_knowledge_data["economic_events"] = [event.to_dictionary()]
|
||||
duplicate_knowledge_data["simulation"]["next_event_id"] = 1
|
||||
var known_event_data := KnownEventStateRecord.create(0, 0).to_dictionary()
|
||||
duplicate_knowledge_data["event_knowledge"] = [
|
||||
known_event_data, known_event_data.duplicate(true)
|
||||
]
|
||||
_check(
|
||||
SimulationStateRecord.from_dictionary(duplicate_knowledge_data) == null,
|
||||
"World state should reject duplicate NPC knowledge pairs"
|
||||
)
|
||||
|
||||
var wrong_subject_cause_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
var unrelated_deposit := EconomicEventRecord.create(
|
||||
0,
|
||||
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
||||
1,
|
||||
2,
|
||||
SimulationIds.npc_inventory_id(2),
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
||||
SimulationIds.RESOURCE_FOOD,
|
||||
1.0
|
||||
)
|
||||
wrong_subject_cause_data["economic_events"] = [unrelated_deposit.to_dictionary()]
|
||||
wrong_subject_cause_data["simulation"]["next_event_id"] = 1
|
||||
wrong_subject_cause_data["event_knowledge"] = [
|
||||
KnownEventStateRecord.create(0, 0).to_dictionary()
|
||||
]
|
||||
wrong_subject_cause_data["relationships"] = [
|
||||
RelationshipStateRecord.create(0, 1, 0.5, 0.65, 0).to_dictionary()
|
||||
]
|
||||
_check(
|
||||
SimulationStateRecord.from_dictionary(wrong_subject_cause_data) == null,
|
||||
"A trust cause must be a known food deposit performed by the relationship subject"
|
||||
)
|
||||
|
||||
var nonpositive_cause_data: Dictionary = manager.create_state_record().to_dictionary()
|
||||
var nonpositive_deposit := EconomicEventRecord.create(
|
||||
0,
|
||||
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
||||
1,
|
||||
1,
|
||||
SimulationIds.npc_inventory_id(1),
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
||||
SimulationIds.RESOURCE_FOOD,
|
||||
0.0
|
||||
)
|
||||
nonpositive_cause_data["economic_events"] = [nonpositive_deposit.to_dictionary()]
|
||||
nonpositive_cause_data["simulation"]["next_event_id"] = 1
|
||||
nonpositive_cause_data["event_knowledge"] = [KnownEventStateRecord.create(0, 0).to_dictionary()]
|
||||
nonpositive_cause_data["relationships"] = [
|
||||
RelationshipStateRecord.create(0, 1, 0.5, 0.65, 0).to_dictionary()
|
||||
]
|
||||
_check(
|
||||
SimulationStateRecord.from_dictionary(nonpositive_cause_data) == null,
|
||||
"A trust cause must describe a successful positive food deposit"
|
||||
)
|
||||
manager.free()
|
||||
|
||||
|
||||
func _create_manager(seed_value: int) -> Node:
|
||||
var manager: Node = load("res://simulation/SimulationManager.gd").new()
|
||||
manager.simulation_seed = seed_value
|
||||
|
||||
Reference in New Issue
Block a user