babylon.models.entities.event_template

Event Template model for declarative game events.

An EventTemplate defines a recurring game event with: - Preconditions: Material conditions that enable the event - Resolutions: Deterministic outcomes based on current state - Effects: State modifications to apply - Narrative: Hooks for AI observer narrative generation

This implements the Paradox Pattern for events - data-driven definitions that the EventTemplateSystem evaluates against WorldState.

Sprint: Event Template System

Classes

EdgeCondition(**data)

Condition on edge types/counts with optional node filtering.

EventEmission(**data)

Specification for emitting an EventBus event.

EventTemplate(**data)

A declarative template for recurring game events.

GraphCondition(**data)

Condition on graph-level aggregate metrics.

NarrativeHooks(**data)

Hooks for AI observer narrative generation.

NodeCondition(**data)

Condition on node attributes with optional filtering and aggregation.

NodeFilter(**data)

Filter to select which nodes a condition applies to.

PreconditionSet(**data)

A set of conditions that must be satisfied for an event to trigger.

Resolution(**data)

A resolution path with condition and effects.

TemplateEffect(**data)

Effect specification within an event template.

class babylon.models.entities.event_template.NodeFilter(**data)[source]

Bases: BaseModel

Filter to select which nodes a condition applies to.

Used to restrict condition evaluation to specific node types, roles, or ID patterns. All specified filters must match (AND logic).

Parameters:
role

Filter by SocialRole values.

node_type

Filter by _node_type attribute (social_class or territory).

id_pattern

Regex pattern for node IDs.

role: list[SocialRole] | None
node_type: Literal['social_class', 'territory'] | None
id_pattern: str | None
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

matches(node_id, node_data)[source]

Check if a node matches this filter.

Parameters:
  • node_id (str) – The node’s identifier.

  • node_data (dict[str, Any]) – The node’s data dictionary.

Return type:

bool

Returns:

True if all specified criteria match, False otherwise.

class babylon.models.entities.event_template.NodeCondition(**data)[source]

Bases: BaseModel

Condition on node attributes with optional filtering and aggregation.

Evaluates a dot-notation path on nodes, optionally filtered by NodeFilter, then aggregates results and compares to threshold.

Parameters:
  • path (str)

  • operator (Literal['>=', '<=', '>', '<', '==', '!='])

  • threshold (float)

  • node_filter (NodeFilter | None)

  • aggregation (Literal['any', 'all', 'count', 'sum', 'avg', 'max', 'min'])

path

Dot-notation path to node attribute (e.g., ideology.agitation).

operator

Comparison operator.

threshold

Value to compare against.

node_filter

Optional filter to select which nodes to check.

aggregation

How to aggregate across matched nodes.

path: str
operator: Literal['>=', '<=', '>', '<', '==', '!=']
threshold: float
node_filter: NodeFilter | None
aggregation: Literal['any', 'all', 'count', 'sum', 'avg', 'max', 'min']
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class babylon.models.entities.event_template.EdgeCondition(**data)[source]

Bases: BaseModel

Condition on edge types/counts with optional node filtering.

Counts or aggregates edges of a specific type, optionally restricted to edges connected to nodes matching the filter.

Parameters:
edge_type

Type of edge to check.

metric

What to measure (count, sum_strength, avg_strength).

operator

Comparison operator.

threshold

Value to compare against.

node_filter

Optional filter to select nodes whose edges to count.

edge_type: EdgeType
metric: Literal['count', 'sum_strength', 'avg_strength']
operator: Literal['>=', '<=', '>', '<', '==', '!=']
threshold: float
node_filter: NodeFilter | None
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class babylon.models.entities.event_template.GraphCondition(**data)[source]

Bases: BaseModel

Condition on graph-level aggregate metrics.

Evaluates aggregate properties of the entire graph rather than individual nodes or edges.

Parameters:
  • metric (Literal['solidarity_density', 'exploitation_density', 'average_agitation', 'average_consciousness', 'total_wealth', 'gini_coefficient'])

  • operator (Literal['>=', '<=', '>', '<', '==', '!='])

  • threshold (float)

metric

Graph-level metric to evaluate.

operator

Comparison operator.

threshold

Value to compare against.

metric: Literal['solidarity_density', 'exploitation_density', 'average_agitation', 'average_consciousness', 'total_wealth', 'gini_coefficient']
operator: Literal['>=', '<=', '>', '<', '==', '!=']
threshold: float
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class babylon.models.entities.event_template.PreconditionSet(**data)[source]

Bases: BaseModel

A set of conditions that must be satisfied for an event to trigger.

Combines node, edge, and graph-level conditions with specified logic.

Parameters:
node_conditions

Conditions on node attributes.

edge_conditions

Conditions on edge types/counts.

graph_conditions

Conditions on graph-level metrics.

logic

How to combine conditions (all = AND, any = OR).

node_conditions: list[NodeCondition]
edge_conditions: list[EdgeCondition]
graph_conditions: list[GraphCondition]
logic: Literal['all', 'any']
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

is_empty()[source]

Check if precondition set has no conditions.

Return type:

bool

Returns:

True if no conditions are defined, False otherwise.

class babylon.models.entities.event_template.NarrativeHooks(**data)[source]

Bases: BaseModel

Hooks for AI observer narrative generation.

Provides context for Persephone to generate narrative around events.

Parameters:
  • motif (str | None)

  • historical_echoes (list[str])

  • flavor_text_key (str | None)

  • entity_refs (list[str])

motif

Narrative motif key (e.g., bifurcation, betrayal).

historical_echoes

References to historical parallels.

flavor_text_key

Key for localized flavor text lookup.

entity_refs

Entity IDs to reference in narrative.

motif: str | None
historical_echoes: list[str]
flavor_text_key: str | None
entity_refs: list[str]
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class babylon.models.entities.event_template.EventEmission(**data)[source]

Bases: BaseModel

Specification for emitting an EventBus event.

Defines what event to emit when a resolution is selected.

Parameters:
event_type

EventType name to emit.

payload_template

Template for event payload with ${var} substitution.

event_type: str
payload_template: dict[str, Any]
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class babylon.models.entities.event_template.TemplateEffect(**data)[source]

Bases: BaseModel

Effect specification within an event template.

Similar to the Effect model but supports ${var} substitution for dynamic target resolution at runtime.

Parameters:
  • target_id (str)

  • attribute (str)

  • operation (Literal['increase', 'decrease', 'set', 'multiply'])

  • magnitude (float)

  • description (str)

target_id

Entity ID to modify (supports ${node_id} substitution).

attribute

Attribute name to change.

operation

How to modify the value.

magnitude

Amount of change.

description

Human-readable explanation.

target_id: str
attribute: str
operation: Literal['increase', 'decrease', 'set', 'multiply']
magnitude: float
description: str
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

apply_to(current_value)[source]

Calculate the new value after applying this effect.

Parameters:

current_value (float) – The current value of the attribute.

Return type:

float

Returns:

The new value after the effect is applied.

class babylon.models.entities.event_template.Resolution(**data)[source]

Bases: BaseModel

A resolution path with condition and effects.

When an EventTemplate’s preconditions are met, resolutions are evaluated in order. The first resolution whose condition matches (or has no condition) is selected.

Parameters:
id

Resolution identifier (snake_case).

name

Human-readable name.

condition

Optional condition for this resolution path.

effects

Effects to apply when this resolution is selected.

emit_event

Optional event to emit.

narrative

Narrative hooks specific to this resolution.

id: str
name: str | None
condition: PreconditionSet | None
effects: list[TemplateEffect]
emit_event: EventEmission | None
narrative: NarrativeHooks | None
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class babylon.models.entities.event_template.EventTemplate(**data)[source]

Bases: BaseModel

A declarative template for recurring game events.

EventTemplates are the Paradox Pattern for events - data-driven definitions that the EventTemplateSystem evaluates against WorldState.

When preconditions are satisfied, the first matching resolution’s effects are applied and events are emitted for the narrative layer.

Parameters:
id

Unique identifier (EVT_* pattern).

name

Human-readable name.

description

Detailed explanation.

category

System domain category.

preconditions

Conditions that must be met to trigger.

resolutions

Ordered list of resolution paths.

narrative

Hooks for AI narrative generation.

cooldown_ticks

Minimum ticks between activations.

priority

Higher priority templates evaluate first.

id: str
name: str
description: str
category: Literal['economic', 'consciousness', 'struggle', 'contradiction', 'territory']
preconditions: PreconditionSet
resolutions: list[Resolution]
narrative: NarrativeHooks | None
cooldown_ticks: int
priority: int
last_triggered_tick: int | None
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

validate_resolutions_have_effects_or_events()[source]

Ensure each resolution has at least one effect or event emission.

Return type:

EventTemplate

is_on_cooldown(current_tick)[source]

Check if this template is on cooldown.

Parameters:

current_tick (int) – The current simulation tick.

Return type:

bool

Returns:

True if still on cooldown, False otherwise.

mark_triggered(tick)[source]

Mark this template as having been triggered.

Parameters:

tick (int) – The tick at which this was triggered.

Return type:

None