babylon.engine.observers.endgame_detector

EndgameDetector observer for game ending detection (Slice 1.6).

The EndgameDetector is a SimulationObserver that monitors WorldState for three possible game ending conditions:

  1. REVOLUTIONARY_VICTORY: percolation >= threshold AND class_consciousness > threshold - The masses have achieved critical organization AND ideological clarity - This represents successful proletarian revolution

  2. ECOLOGICAL_COLLAPSE: overshoot_ratio > threshold for N consecutive ticks - Sustained ecological overshoot leads to irreversible collapse - Capital’s metabolic rift has become fatal

  3. FASCIST_CONSOLIDATION: national_identity > class_consciousness for M+ nodes - Fascist ideology has captured the majority of the population - False consciousness prevents class-based organization

Priority when multiple conditions are met:

REVOLUTIONARY_VICTORY > ECOLOGICAL_COLLAPSE > FASCIST_CONSOLIDATION

The detector implements the Observer Pattern: it receives state change notifications but cannot modify simulation state.

Thresholds are configurable via GameDefines.endgame for scenario customization.

Classes

EndgameDetector([logger, defines])

Observer detecting game ending conditions.

class babylon.engine.observers.endgame_detector.EndgameDetector(logger=None, defines=None)[source]

Bases: object

Observer detecting game ending conditions.

Implements SimulationObserver protocol to receive state change notifications and check for endgame conditions after each tick.

The detector maintains: - Current outcome (IN_PROGRESS until game ends) - Consecutive overshoot tick counter (for ecological collapse) - Pending events list (for ENDGAME_REACHED event emission) - Configurable thresholds via GameDefines.endgame

Parameters:
name

Observer identifier (“EndgameDetector”).

outcome

Current GameOutcome (starts as IN_PROGRESS).

is_game_over

Boolean indicating if game has ended.

defines

EndgameDefines containing threshold configuration.

Example

>>> from babylon.engine.observers.endgame_detector import EndgameDetector
>>> detector = EndgameDetector()
>>> detector.outcome
<GameOutcome.IN_PROGRESS: 'in_progress'>
>>> detector.is_game_over
False
>>> # Custom thresholds via GameDefines
>>> from babylon.config.defines import GameDefines, EndgameDefines
>>> custom = GameDefines(endgame=EndgameDefines(
...     revolutionary_percolation_threshold=0.5,
...     fascist_majority_threshold=5,
... ))
>>> detector = EndgameDetector(defines=custom)
>>> detector.defines.revolutionary_percolation_threshold
0.5
__init__(logger=None, defines=None)[source]

Initialize EndgameDetector.

Parameters:
  • logger (Logger | None) – Logger instance for endgame notifications. Defaults to module-level logger if not provided.

  • defines (GameDefines | None) – GameDefines containing endgame thresholds. Defaults to GameDefines() with standard thresholds.

Return type:

None

property defines: EndgameDefines

Return the endgame threshold configuration.

Returns:

EndgameDefines containing all threshold values.

property name: str

Return observer identifier.

Returns:

String “EndgameDetector” for logging and debugging.

property outcome: GameOutcome

Return current game outcome.

Returns:

GameOutcome enum value (IN_PROGRESS, REVOLUTIONARY_VICTORY, ECOLOGICAL_COLLAPSE, or FASCIST_CONSOLIDATION).

property is_game_over: bool

Return True if game has ended.

Returns:

Boolean indicating if outcome is not IN_PROGRESS.

get_pending_events()[source]

Return and clear pending events for collection by Simulation facade.

Observer events cannot be emitted directly to WorldState because observers run AFTER WorldState is frozen. Instead, pending events are collected by the Simulation facade and injected into the NEXT tick’s WorldState.

Return type:

list[EndgameEvent]

Returns:

List of pending SimulationEvent objects (cleared after return).

on_simulation_start(initial_state, config)[source]

Called when simulation begins.

Resets detector to initial state, allowing reuse across multiple simulation runs.

Parameters:
Return type:

None

on_tick(previous_state, new_state)[source]

Called after each tick completes with both states for delta analysis.

Checks for endgame conditions in priority order: 1. Revolutionary victory (highest priority - the people won) 2. Ecological collapse 3. Fascist consolidation (lowest priority)

If game has already ended, this is a no-op.

Parameters:
  • previous_state (WorldState) – WorldState before the tick (unused).

  • new_state (WorldState) – WorldState after the tick.

Return type:

None

on_simulation_end(final_state)[source]

Called when simulation ends.

No-op for EndgameDetector. Endgame state is already determined.

Parameters:

final_state (WorldState) – Final WorldState when simulation ends (unused).

Return type:

None