feat: generalize social memory and relationships

This commit is contained in:
Rijad Zuzo
2026-08-12 20:23:17 +02:00
parent dd0fc7542c
commit ed7236257a
5 changed files with 726 additions and 71 deletions
+96 -11
View File
@@ -5,6 +5,8 @@ const TRUSTED_HELP_THRESHOLD := 0.6
const FOOD_AID_TRUST_GAIN := 0.15
const SHARED_WORK_FAMILIARITY_GAIN := 0.1
const PLAYER_FAMILIARITY_SEED := 0.5
const DEFAULT_SALIENT_RELATIONSHIP_LIMIT := 4
const MAX_BOUNDED_RELATIONSHIPS_PER_QUERY := 8
var relationships: Dictionary = {}
@@ -39,6 +41,86 @@ func get_relationship(observer_id: int, subject_id: int) -> RelationshipStateRec
return relationships.get(_key(observer_id, subject_id)) as RelationshipStateRecord
func get_or_create_relationship(
observer_id: int, subject_id: int, initial_familiarity: float = 0.0
) -> RelationshipStateRecord:
if (
not RelationshipStateRecord.is_valid_actor_id(observer_id)
or not RelationshipStateRecord.is_valid_actor_id(subject_id)
or observer_id == subject_id
):
return null
var relationship := get_relationship(observer_id, subject_id)
if relationship != null:
return relationship
relationship = RelationshipStateRecord.create(observer_id, subject_id, initial_familiarity)
_add(relationship)
return relationship
func adjust_relationship_dimension(
observer_id: int,
subject_id: int,
dimension: StringName,
amount: float,
cause_event_id: int,
create_if_missing: bool = true
) -> float:
var relationship := get_relationship(observer_id, subject_id)
if relationship == null and create_if_missing:
relationship = get_or_create_relationship(observer_id, subject_id)
if relationship == null:
return 0.0
return relationship.adjust_dimension(dimension, amount, cause_event_id)
func get_relationship_dimension(observer_id: int, subject_id: int, dimension: StringName) -> float:
var relationship := get_relationship(observer_id, subject_id)
return -1.0 if relationship == null else relationship.get_dimension(dimension)
func get_relationship_cause_event_id(
observer_id: int, subject_id: int, dimension: StringName
) -> int:
var relationship := get_relationship(observer_id, subject_id)
return (
RelationshipStateRecord.NO_CAUSE_EVENT
if relationship == null
else relationship.get_last_cause_event_id(dimension)
)
func get_relationships_for_observer(observer_id: int) -> Array[RelationshipStateRecord]:
var records: Array[RelationshipStateRecord] = []
for relationship in relationships.values():
if relationship.get_observer_id() == observer_id:
records.append(relationship)
records.sort_custom(_sort_relationships)
return records
func get_salient_relationships(
observer_id: int,
max_count: int = DEFAULT_SALIENT_RELATIONSHIP_LIMIT,
minimum_salience: float = 0.0
) -> Array[RelationshipStateRecord]:
if max_count <= 0:
return []
var records: Array[RelationshipStateRecord] = []
var bounded_minimum := clampf(minimum_salience, 0.0, 1.0)
for relationship in relationships.values():
if relationship.get_observer_id() != observer_id:
continue
if relationship.get_salience() < bounded_minimum:
continue
records.append(relationship)
records.sort_custom(_is_more_salient)
var bounded_count := mini(max_count, MAX_BOUNDED_RELATIONSHIPS_PER_QUERY)
if records.size() > bounded_count:
records.resize(bounded_count)
return records
func is_trusted_for_help(observer_id: int, subject_id: int) -> bool:
var relationship := get_relationship(observer_id, subject_id)
return (
@@ -49,8 +131,10 @@ func is_trusted_for_help(observer_id: int, subject_id: int) -> bool:
func increase_shared_work_familiarity(first_id: int, second_id: int) -> void:
var first_to_second := _get_or_create(first_id, second_id)
var second_to_first := _get_or_create(second_id, first_id)
var first_to_second := get_or_create_relationship(first_id, second_id)
var second_to_first := get_or_create_relationship(second_id, first_id)
if first_to_second == null or second_to_first == null:
return
first_to_second.increase_familiarity(SHARED_WORK_FAMILIARITY_GAIN)
second_to_first.increase_familiarity(SHARED_WORK_FAMILIARITY_GAIN)
@@ -174,15 +258,6 @@ func get_trusted_starving_subject(
return effective_view.get_starving(best_relationship.get_subject_id())
func _get_or_create(observer_id: int, subject_id: int) -> RelationshipStateRecord:
var relationship := get_relationship(observer_id, subject_id)
if relationship != null:
return relationship
relationship = RelationshipStateRecord.create(observer_id, subject_id, 0.0)
_add(relationship)
return relationship
func _add(relationship: RelationshipStateRecord) -> void:
relationships[_key(relationship.get_observer_id(), relationship.get_subject_id())] = relationship
@@ -207,3 +282,13 @@ static func _is_stronger(
if not is_equal_approx(candidate.get_familiarity(), current.get_familiarity()):
return candidate.get_familiarity() > current.get_familiarity()
return candidate.get_subject_id() < current.get_subject_id()
static func _is_more_salient(
first: RelationshipStateRecord, second: RelationshipStateRecord
) -> bool:
if not is_equal_approx(first.get_salience(), second.get_salience()):
return first.get_salience() > second.get_salience()
if not is_equal_approx(first.get_trust(), second.get_trust()):
return first.get_trust() > second.get_trust()
return first.get_subject_id() < second.get_subject_id()