babylon.models.world_state
WorldState model for the Babylon simulation.
WorldState is an immutable snapshot of the entire simulation at a specific tick. It encapsulates: - All entities (social classes) as nodes - All territories (strategic sectors) as nodes - All relationships (value flows, tensions) as edges - A tick counter for temporal tracking - An event log for narrative/debugging
- The state is designed for functional transformation:
new_state = step(old_state, config)
Sprint 4: Phase 2 game loop state container with NetworkX integration. Sprint 3.5.3: Territory integration for Layer 0.
Classes
|
Immutable snapshot of the simulation at a specific tick. |
- class babylon.models.world_state.WorldState(**data)[source]
Bases:
BaseModelImmutable snapshot of the simulation at a specific tick.
WorldState follows the Data/Logic separation principle: - State holds WHAT exists (pure data) - Engine determines HOW it transforms (pure logic)
This enables: - Determinism: Same state + same engine = same output - Replayability: Save initial state, replay entire history - Counterfactuals: Modify a parameter, run forward, compare - Testability: Feed state in, assert on state out
- Parameters:
tick (int)
entities (dict[str, SocialClass])
relationships (list[Relationship])
events (list[SimulationEvent])
economy (GlobalEconomy)
state_finances (dict[str, StateFinance])
contradiction_frames (dict[str, ContradictionFrame])
organizations (dict[str, Annotated[StateApparatus | Business | PoliticalFaction | CivilSocietyOrg, FieldInfo(annotation=NoneType, required=True, discriminator='org_type')]])
institutions (dict[str, Institution])
institution_relations (list[InstitutionOrgRelation])
industries (dict[str, IndustryHyperedge])
factions (dict[str, BalkanizationFaction])
- tick
Current turn number (0-indexed)
- entities
Map of entity ID to SocialClass (the nodes)
- territories
Map of territory ID to Territory (Layer 0 nodes)
- relationships
List of Relationship edges (the edges)
- event_log
Recent events for narrative/debugging (string format)
- events
Structured simulation events for analysis (Sprint 3.1)
- economy
Global economic state for dynamic balance (Sprint 3.4.4)
- model_config: ClassVar[ConfigDict] = {'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- entities: dict[str, SocialClass]
- relationships: list[Relationship]
- events: list[SimulationEvent]
- economy: GlobalEconomy
- state_finances: dict[str, StateFinance]
- contradiction_frames: dict[str, ContradictionFrame]
- organizations: dict[str, Annotated[StateApparatus | Business | PoliticalFaction | CivilSocietyOrg, FieldInfo(annotation=NoneType, required=True, discriminator='org_type')]]
- institutions: dict[str, Institution]
- institution_relations: list[InstitutionOrgRelation]
- industries: dict[str, IndustryHyperedge]
- factions: dict[str, BalkanizationFaction]
- to_graph()[source]
Convert state to a BabylonGraph for formula application.
The rustworkx-backed
BabylonGraph(Amendment L) replaces the former NetworkX DiGraph; its nx-compat authoring surface keeps this method’s body and all downstream readers unchanged, and it satisfiesGraphProtocoldirectly so systems no longer wrap per tick.Nodes are entity/territory IDs with all fields as attributes. A _node_type marker distinguishes between node types: - _node_type=’social_class’ for SocialClass nodes - _node_type=’territory’ for Territory nodes
Edges are relationships with all Relationship fields as attributes.
Graph metadata (G.graph) contains: - economy: GlobalEconomy state (Sprint 3.4.4)
- Return type:
BabylonGraph- Returns:
BabylonGraph with nodes and edges from this state.
- Raises:
ValueError – If two relationships share a (source, target) pair with differing edge_types — BabylonGraph stores one edge per pair, so the collision would silently collapse last-writer-wins (Design B fail-loud).
Example:
G = state.to_graph() for node_id, data in G.nodes(data=True): if data["_node_type"] == "social_class": data["wealth"] += 10 # Modify entity new_state = WorldState.from_graph(G, tick=state.tick + 1)
- classmethod from_graph(G, tick, event_log=None, events=None)[source]
Reconstruct WorldState from a BabylonGraph.
- Parameters:
G (
BabylonGraph) – Graph with node/edge data (BabylonGraph— the sole substrate since Amendment L closed the adapter seam)tick (
int) – The tick number for the new stateevent_log (
list[str] |None) – Optional event log to preserve (backward compatibility)events (
list[SimulationEvent] |None) – Optional structured events to include (Sprint 3.1)
- Return type:
- Returns:
New WorldState with entities, territories, and relationships from graph.
Example
G = state.to_graph() # … modify graph … new_state = WorldState.from_graph(G, tick=state.tick + 1)
- add_entity(entity)[source]
Return new state with entity added.
- Parameters:
entity (
SocialClass) – SocialClass to add- Return type:
- Returns:
New WorldState with the entity included.
Example
new_state = state.add_entity(worker)
- add_territory(territory)[source]
Return new state with territory added.
- Parameters:
territory (
Territory) – Territory to add (Layer 0 node)- Return type:
- Returns:
New WorldState with the territory included.
Example
new_state = state.add_territory(university_district)
- add_relationship(relationship)[source]
Return new state with relationship added.
- Parameters:
relationship (
Relationship) – Relationship edge to add- Return type:
- Returns:
New WorldState with the relationship included.
Example
new_state = state.add_relationship(exploitation_edge)
- add_event(event)[source]
Return new state with event appended to log.
- Parameters:
event (
str) – Event description string- Return type:
- Returns:
New WorldState with event in log.
Example
new_state = state.add_event(“Worker crossed poverty threshold”)
- property total_biocapacity: Annotated[float, FieldInfo(annotation=NoneType, required=True, description='Non-negative economic value (wealth, wages, rent, GDP)', metadata=[Ge(ge=0.0)]), AfterValidator(func=quantize)]
Global sum of territory biocapacity.
- property total_consumption: Annotated[float, FieldInfo(annotation=NoneType, required=True, description='Non-negative economic value (wealth, wages, rent, GDP)', metadata=[Ge(ge=0.0)]), AfterValidator(func=quantize)]
Global sum of consumption needs.