Skip to content

factions

Data model and query module for political factions and player-faction detection.

tiargus.factions

Data model and SavegameModule for political factions.

Provides:

  • Faction — a political faction, including its exploration intel.
  • FactionModule (key: "factions") — parses every faction and identifies the human player's faction, which determines which bodies count as prospected.
Example
from tiargus import TerraInvictaSave, FactionModule

save = TerraInvictaSave("Autosave.gz", FactionModule)
player = save.get_module(FactionModule).player_faction
print(player.display_name, len(player.prospected_bodies), "bodies prospected")

Faction dataclass

A political faction as recorded in the save file.

Attributes:

Name Type Description
id int

Numeric game-state ID.

display_name str

Faction name as shown in-game (e.g. "The Academy").

prospected_bodies set[int]

IDs of space bodies this faction has fully prospected (intel value 1.0). Bodies that are merely detected (intel value 0.1) are excluded.

Source code in src/tiargus/factions.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@dataclass
class Faction:
    """A political faction as recorded in the save file.

    Attributes:
        id: Numeric game-state ID.
        display_name: Faction name as shown in-game (e.g. ``"The Academy"``).
        prospected_bodies: IDs of space bodies this faction has fully
            prospected (intel value ``1.0``).  Bodies that are merely detected
            (intel value ``0.1``) are excluded.
    """

    id: int
    display_name: str
    prospected_bodies: set[int]

FactionModule

Bases: SavegameModule

Parses all factions and identifies the human player's faction.

The player faction is determined by locating the non-AI player record in the save. This is used by HabSiteModule to filter the list of prospected hab sites.

Source code in src/tiargus/factions.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class FactionModule(SavegameModule):
    """Parses all factions and identifies the human player's faction.

    The player faction is determined by locating the non-AI player record in
    the save.  This is used by [HabSiteModule][tiargus.habs.HabSiteModule]
    to filter the list of prospected hab sites.
    """

    KEY = "factions"

    def __init__(self) -> None:
        self._factions: dict[int, Faction] = {}
        self._player_faction_id: int = 0

    @property
    def factions(self) -> dict[int, Faction]:
        """All factions keyed by their numeric game-state ID."""
        return self._factions

    @property
    def player_faction_id(self) -> int:
        """Numeric ID of the human player's faction."""
        return self._player_faction_id

    @property
    def player_faction(self) -> Faction:
        """The [Faction][tiargus.factions.Faction] belonging to the human player."""
        return self._factions[self._player_faction_id]

    def parse(self, gs: dict, modules: dict[str, SavegameModule]) -> None:
        for item in gs[GS_FACTION]:
            fid = item["Key"]["value"]
            faction = item["Value"]
            prospected = {
                entry["Key"]["value"]
                for entry in faction.get("intel", [])
                if entry.get("Key", {}).get("$type") == GS_SPACE_BODY
                and entry.get("Value") == 1.0
            }
            self._factions[fid] = Faction(
                id=fid,
                display_name=faction["displayName"],
                prospected_bodies=prospected,
            )

        human = next(p["Value"] for p in gs[GS_PLAYER] if not p["Value"]["isAI"])
        self._player_faction_id = human["faction"]["value"]

factions property

All factions keyed by their numeric game-state ID.

player_faction property

The Faction belonging to the human player.

player_faction_id property

Numeric ID of the human player's faction.

__init_subclass__(**kwargs)

Register subclasses in _REGISTRY at definition time.

Raises:

Type Description
TypeError

If a subclass does not define KEY.

Source code in src/tiargus/savegame.py
141
142
143
144
145
146
147
148
149
150
def __init_subclass__(cls, **kwargs: object) -> None:
    """Register subclasses in ``_REGISTRY`` at definition time.

    Raises:
        TypeError: If a subclass does not define ``KEY``.
    """
    super().__init_subclass__(**kwargs)
    if not hasattr(cls, "KEY"):
        raise TypeError(f"{cls.__name__} must define KEY as a class variable")
    SavegameModule._REGISTRY[cls.KEY] = cls

requires() classmethod

Return the KEYs of modules that must be parsed before this one.

Override this in subclasses that need data from other modules. TerraInvictaSave resolves and parses all declared dependencies (and their transitive dependencies) before calling parse() on this module.

Returns:

Type Description
list[str]

A list of KEY strings. The default implementation returns an

list[str]

empty list (no dependencies).

Source code in src/tiargus/savegame.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
@classmethod
def requires(cls) -> list[str]:
    """Return the KEYs of modules that must be parsed before this one.

    Override this in subclasses that need data from other modules.
    ``TerraInvictaSave`` resolves and parses all declared dependencies
    (and their transitive dependencies) before calling ``parse()`` on this
    module.

    Returns:
        A list of ``KEY`` strings.  The default implementation returns an
        empty list (no dependencies).
    """
    return []