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

WorldState(**data)

Immutable snapshot of the simulation at a specific tick.

class babylon.models.world_state.WorldState(**data)[source]

Bases: BaseModel

Immutable 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

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].

tick: int
entities: dict[str, SocialClass]
territories: dict[str, Territory]
relationships: list[Relationship]
event_log: list[str]
events: list[SimulationEvent]
economy: GlobalEconomy
state_finances: dict[str, StateFinance]
contradiction_frames: dict[str, ContradictionFrame]
opposition_states: dict[str, Any]
organizations: dict[str, Annotated[StateApparatus | Business | PoliticalFaction | CivilSocietyOrg, FieldInfo(annotation=NoneType, required=True, discriminator='org_type')]]
key_figures: dict[str, KeyFigure]
institutions: dict[str, Institution]
institution_relations: list[InstitutionOrgRelation]
industries: dict[str, IndustryHyperedge]
sovereigns: dict[str, Sovereign]
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 satisfies GraphProtocol directly 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 state

  • event_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:

WorldState

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:

WorldState

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:

WorldState

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:

WorldState

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:

WorldState

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.

property overshoot_ratio: float

Global ecological overshoot ratio.