201 lines
7.7 KiB
GDScript
201 lines
7.7 KiB
GDScript
extends GutTest
|
|
|
|
const EventKnowledgeSystemScript := preload("res://simulation/knowledge/EventKnowledgeSystem.gd")
|
|
const RelationshipSystemScript := preload("res://simulation/relationships/RelationshipSystem.gd")
|
|
|
|
|
|
func test_known_event_v3_migrates_metadata_and_player_is_a_valid_knower() -> void:
|
|
var legacy_data := {
|
|
"schema_version": KnownEventStateRecord.LEGACY_SCHEMA_VERSION,
|
|
"knower_id": 2,
|
|
"event_id": 12,
|
|
"acquisition_method": String(SimulationIds.KNOWLEDGE_ACQUISITION_COMMUNICATED),
|
|
"source_npc_id": 1,
|
|
"acquired_tick": 30,
|
|
"source_acquisition_method": String(SimulationIds.KNOWLEDGE_ACQUISITION_WITNESSED),
|
|
}
|
|
var migrated := KnownEventStateRecord.from_dictionary(legacy_data)
|
|
|
|
assert_not_null(migrated)
|
|
assert_eq(int(migrated.to_dictionary()["schema_version"]), KnownEventStateRecord.SCHEMA_VERSION)
|
|
assert_eq(migrated.get_source_actor_id(), 1)
|
|
assert_eq(migrated.get_hop_count(), 1)
|
|
assert_eq(migrated.get_confidence(), KnownEventStateRecord.DEFAULT_CONFIDENCE)
|
|
assert_eq(migrated.get_salience(), KnownEventStateRecord.DEFAULT_SALIENCE)
|
|
assert_false(migrated.is_pinned())
|
|
|
|
var player_record := KnownEventStateRecord.create(
|
|
SimulationIds.PLAYER_ACTOR_ID,
|
|
13,
|
|
SimulationIds.KNOWLEDGE_ACQUISITION_WITNESSED,
|
|
KnownEventStateRecord.NO_SOURCE_NPC_ID,
|
|
31
|
|
)
|
|
assert_not_null(KnownEventStateRecord.from_dictionary(player_record.to_dictionary()))
|
|
var invalid_knower_data := player_record.to_dictionary()
|
|
invalid_knower_data["knower_id"] = KnownEventStateRecord.NO_SOURCE_ACTOR_ID
|
|
assert_null(KnownEventStateRecord.from_dictionary(invalid_knower_data))
|
|
|
|
|
|
func test_direct_npc_knowledge_can_be_communicated_explicitly_to_player() -> void:
|
|
var event := EconomicEventRecord.create(
|
|
21,
|
|
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
|
40,
|
|
0,
|
|
SimulationIds.npc_inventory_id(0),
|
|
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
|
SimulationIds.RESOURCE_FOOD,
|
|
2.0,
|
|
Vector3.ZERO
|
|
)
|
|
var speaker_record := KnownEventStateRecord.create(
|
|
1,
|
|
int(event.data["event_id"]),
|
|
SimulationIds.KNOWLEDGE_ACQUISITION_WITNESSED,
|
|
KnownEventStateRecord.NO_SOURCE_NPC_ID,
|
|
40
|
|
)
|
|
var knowledge_system := EventKnowledgeSystemScript.new()
|
|
var records: Array[KnownEventStateRecord] = [speaker_record]
|
|
knowledge_system.restore(records)
|
|
|
|
assert_false(
|
|
knowledge_system.knows_event(SimulationIds.PLAYER_ACTOR_ID, int(event.data["event_id"]))
|
|
)
|
|
var communicated := knowledge_system.communicate_event_to_player(event, 1, 45)
|
|
assert_not_null(communicated)
|
|
assert_eq(communicated.get_knower_id(), SimulationIds.PLAYER_ACTOR_ID)
|
|
assert_eq(communicated.get_source_actor_id(), 1)
|
|
assert_eq(communicated.get_source_npc_id(), 1)
|
|
assert_eq(communicated.get_hop_count(), 1)
|
|
assert_true(is_equal_approx(communicated.get_confidence(), 0.9))
|
|
assert_eq(communicated.get_source_acquisition_method(), speaker_record.get_acquisition_method())
|
|
assert_null(knowledge_system.communicate_event(event, SimulationIds.PLAYER_ACTOR_ID, 2, 46))
|
|
|
|
|
|
func test_player_performed_world_event_is_known_without_a_witness() -> void:
|
|
var event := EconomicEventRecord.create(
|
|
22,
|
|
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
|
41,
|
|
SimulationIds.PLAYER_ACTOR_ID,
|
|
SimulationIds.PLAYER_INVENTORY_ID,
|
|
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
|
SimulationIds.RESOURCE_FOOD,
|
|
1.0,
|
|
Vector3(1000.0, 0.0, 1000.0)
|
|
)
|
|
var knowledge_system := EventKnowledgeSystemScript.new()
|
|
var learned := knowledge_system.observe_event(event, [])
|
|
|
|
assert_eq(learned.size(), 1)
|
|
assert_eq(learned[0].get_knower_id(), SimulationIds.PLAYER_ACTOR_ID)
|
|
assert_eq(learned[0].get_acquisition_method(), SimulationIds.KNOWLEDGE_ACQUISITION_PERFORMED)
|
|
|
|
|
|
func test_pinned_knowledge_is_bounded_and_survives_ordinary_retention() -> void:
|
|
var knowledge_system := EventKnowledgeSystemScript.new()
|
|
var records: Array[KnownEventStateRecord] = []
|
|
for event_id in range(1, 6):
|
|
records.append(
|
|
KnownEventStateRecord.create(
|
|
0,
|
|
event_id,
|
|
SimulationIds.KNOWLEDGE_ACQUISITION_WITNESSED,
|
|
KnownEventStateRecord.NO_SOURCE_NPC_ID,
|
|
event_id
|
|
)
|
|
)
|
|
knowledge_system.restore(records)
|
|
|
|
assert_true(knowledge_system.pin_event(0, 1))
|
|
var no_lasting: Array[KnownEventStateRecord] = []
|
|
var forgotten := knowledge_system.maintain_retention(5, 100, no_lasting, false)
|
|
assert_eq(forgotten.size(), 1)
|
|
assert_eq(forgotten[0].get_event_id(), 2)
|
|
assert_eq(knowledge_system.get_pinned_event_ids(0), [1])
|
|
assert_eq(knowledge_system.get_retained_event_ids(0, [], 0), [1, 5, 4, 3])
|
|
assert_true(knowledge_system.set_event_salience(0, 3, 2.0))
|
|
assert_eq(knowledge_system.get_record(0, 3).get_salience(), 1.0)
|
|
assert_true(knowledge_system.set_event_confidence(0, 3, -1.0))
|
|
assert_eq(knowledge_system.get_record(0, 3).get_confidence(), 0.0)
|
|
|
|
var pin_limit_system := EventKnowledgeSystemScript.new()
|
|
var pin_limit_records: Array[KnownEventStateRecord] = []
|
|
for event_id in range(1, 6):
|
|
pin_limit_records.append(KnownEventStateRecord.create(0, event_id))
|
|
pin_limit_system.restore(pin_limit_records)
|
|
for event_id in range(1, EventKnowledgeSystemScript.MAX_PINNED_FACTS_PER_KNOWER + 1):
|
|
assert_true(pin_limit_system.pin_event(0, event_id))
|
|
assert_false(
|
|
pin_limit_system.pin_event(0, EventKnowledgeSystemScript.MAX_PINNED_FACTS_PER_KNOWER + 1)
|
|
)
|
|
|
|
|
|
func test_relationship_v1_migrates_all_dimensions_and_exact_causes() -> void:
|
|
var legacy_data := {
|
|
"schema_version": RelationshipStateRecord.LEGACY_SCHEMA_VERSION,
|
|
"observer_id": 1,
|
|
"subject_id": 2,
|
|
"familiarity": 0.4,
|
|
"trust": 0.6,
|
|
"last_trust_cause_event_id": 8,
|
|
}
|
|
var relationship := RelationshipStateRecord.from_dictionary(legacy_data)
|
|
|
|
assert_not_null(relationship)
|
|
assert_eq(
|
|
int(relationship.to_dictionary()["schema_version"]), RelationshipStateRecord.SCHEMA_VERSION
|
|
)
|
|
assert_eq(relationship.get_affection(), 0.0)
|
|
assert_eq(relationship.get_respect(), 0.0)
|
|
assert_eq(relationship.get_fear(), 0.0)
|
|
assert_eq(relationship.get_obligation(), 0.0)
|
|
assert_eq(relationship.get_hostility(), 0.0)
|
|
assert_eq(relationship.get_last_trust_cause_event_id(), 8)
|
|
|
|
for index in range(RelationshipStateRecord.DIMENSIONS.size()):
|
|
var dimension: StringName = RelationshipStateRecord.DIMENSIONS[index]
|
|
var cause_event_id := 20 + index
|
|
assert_true(relationship.adjust_dimension(dimension, 0.1, cause_event_id) > 0.0)
|
|
assert_eq(relationship.get_last_cause_event_id(dimension), cause_event_id)
|
|
assert_true(relationship.adjust_hostility(2.0, 99) > 0.0)
|
|
assert_eq(relationship.get_hostility(), 1.0)
|
|
assert_eq(relationship.get_last_hostility_cause_event_id(), 99)
|
|
assert_not_null(RelationshipStateRecord.from_dictionary(relationship.to_dictionary()))
|
|
|
|
var player_observer := RelationshipStateRecord.create(SimulationIds.PLAYER_ACTOR_ID, 3, 0.2)
|
|
assert_not_null(RelationshipStateRecord.from_dictionary(player_observer.to_dictionary()))
|
|
|
|
|
|
func test_sparse_relationship_queries_are_deterministic_and_bounded() -> void:
|
|
var relationship_system := RelationshipSystemScript.new()
|
|
for subject_id in range(10):
|
|
var relationship := relationship_system.get_or_create_relationship(
|
|
SimulationIds.PLAYER_ACTOR_ID, subject_id, float(subject_id) / 10.0
|
|
)
|
|
assert_not_null(relationship)
|
|
assert_true(
|
|
(
|
|
relationship_system.adjust_relationship_dimension(
|
|
SimulationIds.PLAYER_ACTOR_ID, 0, RelationshipStateRecord.DIMENSION_RESPECT, 1.0, 77
|
|
)
|
|
> 0.0
|
|
)
|
|
)
|
|
|
|
var sorted := relationship_system.get_relationships_for_observer(SimulationIds.PLAYER_ACTOR_ID)
|
|
assert_eq(sorted.size(), 10)
|
|
assert_eq(sorted[0].get_subject_id(), 0)
|
|
assert_eq(sorted[9].get_subject_id(), 9)
|
|
var salient := relationship_system.get_salient_relationships(SimulationIds.PLAYER_ACTOR_ID, 100)
|
|
assert_eq(salient.size(), RelationshipSystemScript.MAX_BOUNDED_RELATIONSHIPS_PER_QUERY)
|
|
assert_eq(salient[0].get_subject_id(), 0)
|
|
assert_eq(
|
|
relationship_system.get_relationship_cause_event_id(
|
|
SimulationIds.PLAYER_ACTOR_ID, 0, RelationshipStateRecord.DIMENSION_RESPECT
|
|
),
|
|
77
|
|
)
|