feat: author emergent situations and dialogue

This commit is contained in:
Rijad Zuzo
2026-08-12 21:58:12 +02:00
parent 14120115d4
commit d12e9515fb
29 changed files with 856 additions and 143 deletions
+8 -57
View File
@@ -2,6 +2,7 @@ class_name SituationSystem
extends RefCounted
const MAX_CONCURRENT_SITUATIONS := 3
const PANTRY_SHORTAGE_DEFINITION_PATH := "res://simulation/situations/resources/pantry_shortage.tres"
const DEFINITION_PANTRY_SHORTAGE := &"situation_pantry_shortage"
const PREDICATE_EVENT_TYPE := &"event_type"
const PREDICATE_EVENT_PAYLOAD_EQUALS := &"event_payload_equals"
@@ -26,68 +27,18 @@ var _next_situation_id := 0
static func create_default() -> SituationSystem:
var system := SituationSystem.new()
var definitions: Array[SituationDefinition] = [create_pantry_shortage_definition()]
var definitions: Array[SituationDefinition] = []
var catalog := ContentCatalog.create_core()
if catalog.is_valid():
for definition in catalog.get_situations():
definitions.append(definition.duplicate_definition())
system.configure(definitions)
return system
static func create_pantry_shortage_definition() -> SituationDefinition:
var definition := SituationDefinition.new()
definition.situation_definition_id = DEFINITION_PANTRY_SHORTAGE
definition.display_name = "The Pantry Is Empty"
definition.description = "The village pantry has run out of food."
definition.severity = 70
definition.priority = 80
definition.trigger_predicates = [
_event_predicate(
&"pantry_withdrawal", PREDICATE_EVENT_TYPE, {"event_type": "storage_withdrawn"}
),
_event_predicate(
&"withdrawal_from_pantry",
PREDICATE_EVENT_PARTICIPANT_ID,
{"role": "source", "entity_id": "village_pantry"}
),
_event_predicate(
&"withdrawal_of_food",
PREDICATE_EVENT_PAYLOAD_EQUALS,
{"key": "item_id", "value": "food"}
),
_state_predicate(
&"pantry_empty", PREDICATE_STATE_NUMBER_LTE, {"fact_key": "pantry.food", "value": 0.0}
),
]
definition.resolution_predicates = [
_event_predicate(
&"pantry_restocked",
PREDICATE_EVENT_PANTRY_SUPPLIED,
{"target_id": "village_pantry", "item_id": "food", "amount": 1.0}
)
]
definition.expiry_predicate_ids = [EXPIRY_AGE_REACHED]
definition.dedupe_key_fields = [&"world_id", &"source_id"]
definition.expiry_ticks = 200
definition.cooldown_ticks = 50
definition.dialogue_topic_ids = [DIALOGUE_TOPIC_PANTRY_SHORTAGE]
var restock := SituationAlternativeDefinition.new()
restock.alternative_id = ALTERNATIVE_RESTOCK
restock.display_name = "Restock the pantry"
restock.description = "Bring at least one food item to the village pantry."
restock.resolution_predicate_ids = [&"pantry_restocked"]
restock.dialogue_topic_ids = [DIALOGUE_TOPIC_PANTRY_SHORTAGE]
restock.commitment_terms = {
"action_id": "deposit_food",
"target_id": "village_pantry",
"item_id": "food",
"amount": 1.0,
}
var endure := SituationAlternativeDefinition.new()
endure.alternative_id = ALTERNATIVE_ENDURE
endure.display_name = "Endure the shortage"
endure.description = "Make no promise and let the immediate concern pass."
endure.resolution_predicate_ids = [&"pantry_restocked"]
endure.dialogue_topic_ids = [DIALOGUE_TOPIC_PANTRY_SHORTAGE]
definition.alternatives = [restock, endure]
return definition
var authored := load(PANTRY_SHORTAGE_DEFINITION_PATH) as SituationDefinition
return authored.duplicate_definition() if authored != null else null
func configure(definitions: Array[SituationDefinition]) -> Array[String]: