anacreonlib package#

Module contents#

class anacreonlib.Anacreon(auth_info: AnacreonApiRequest, game_info: ScenarioInfo, client: AnacreonAsyncClient | None = None)#

Bases: object

Construct an Anacreon instance directly

Consider using one of the helper class methods like log_in() instead

Parameters:
  • auth_info (AnacreonApiRequest) – A stub API request containing a valid auth token

  • game_info (ScenarioInfo) – Info about the game, such as all the traits that

  • client (Optional[AnacreonAsyncClient], optional) – The low-level API client to use in order to make HTTP requests. Defaults to None.

async abort_attack(battlefield_id: int) None#

Abort an attack in progress

Parameters:

battlefield_id (int) – The world ID of the planet that you are attacking

async attack(battlefield_id: int, objective: BattleObjective, enemy_sovereign_ids: List[int]) None#

Attack a world

Parameters:
  • battlefield_id (int) – The ID of the world that you intend to attack

  • objective (BattleObjective) – Whether you want to invade, reinforce a siege, or destroy all space defenses

  • enemy_sovereign_ids (List[int]) – A list of the sovereign ids that you wish to engage in battle with

async build_improvement(world_obj_id: int, improvement_id: int) None#

Build an improvement

Parameters:
  • world_obj_id (int) – The ID of the world to build the improvement on

  • improvement_id (int) – The trait ID of the improvement to build

async buy_item(source_obj_id: int, item_id: int, item_count: int) None#

Buy an item from the Mesophons.

As a prerequisite to calling this method, you must have a fleet stationed at the world where you wish to buy ships from.

Parameters:
  • source_obj_id (int) – The ID of the world to buy ships from

  • item_id (int) – The resource ID of the ship that you wish to buy

  • item_count (int) – The number of ships that you wish to buy. Unlike the UI, which only lets you buy ships in groups of 1000, you may specify any number here.

calculate_forces(object_or_resources: World | Fleet | Dict[int, int] | List[int]) MilitaryForceInfo#

Calculate the ground forces + space forces of a particular world/fleet

Parameters:

object_or_resources (Union[World, Fleet, IdValueMapping]) – Either the World object, the Fleet object, or a list/dict of resources.

Returns:

A dataclass containing the force information as it would be displayed in the Anacreon UI

Return type:

MilitaryForceInfo

calculate_remaining_cargo_space(fleet: Fleet | int) float#

Calculate the remaining cargo space on a fleet

Parameters:

fleet (Union[Fleet, int]) – Either the Fleet object, or the fleet ID

Raises:

LookupError – Raised if the fleet could not be found

Returns:

The remaining cargo space left in the fleet. Can be negative if uneven attrition has left more cargo in the fleet than it has space for.

Return type:

float

call_get_objects_periodically() Task[None]#

Spawns an Task that calls Anacreon.get_objects() every watch.

Returns:

The task that was spawned.

Return type:

asyncio.Task[None]

client: AnacreonAsyncClient#

the low level API client that is used to make HTTP requests to the Anacreon API

async deploy_fleet(source_obj_id: int, resources: Dict[int, int] | List[int]) Fleet | None#

Deploy a fleet

Parameters:
  • source_obj_id (int) – The world or fleet from which you wish to create the fleet

  • resources (IdValueMapping) – A mapping from resource IDs to quantities. Can either be a dict, or a flat list alternating between ID and qty.

Returns:

The newly created fleet.

Return type:

Optional[Fleet]

async designate_world(world_obj_id: int, designation_id: int) None#

Designate a world

Parameters:
  • world_obj_id (int) – The ID of the world you wish to designate

  • designation_id (int) – The trait ID of the designation you wish to give the world

async destroy_improvement(world_obj_id: int, improvement_id: int) None#

Destroy a structure/improvement on a world

Parameters:
  • world_obj_id (int) – The ID of the world on which you want to destroy the structure

  • improvement_id (int) – The trait ID of the structure you wish to destroy

async disband_fleet(fleet_obj_id: int, dest_obj_id: int) None#

Delete a fleet by forcing it to become a part of another object that it is stationed next to.

You can use this method to gift fleets to enemy sovereigns.

Parameters:
  • fleet_obj_id (int) – The ID of the fleet to disband

  • dest_obj_id (int) – The ID of the world/fleet that it should become a part of

async classmethod from_auth_token(game_id: str, auth_token: str, *, client: AnacreonAsyncClient | None = None) Anacreon#

Authenticate with the Anacreon API using an auth token

You can get an auth token by looking at your cookies for anacreon.kronosaur.com in your browser’s dev console.

Parameters:
  • game_id (str) – The game ID of the game you intend to manipulate

  • auth_token (str) – A valid Multiverse auth token

Returns:

An instance of the API client wrapper, which can be used to programmatically perform actions within the game

Return type:

Anacreon

game_info: ScenarioInfo#

The scenario info for the game

generate_production_info(world: World | int) Dict[int, ProductionInfo]#

Calculate production info for a world

Parameters:

world (Union[World, int]) – Either the World object, or the world ID.

Raises:

LookupError – Raised if world is a world ID that cannot be found

Returns:

A mapping from resource ID to ProductionInfo objects describing how much of that resource was imported/exported

Return type:

Dict[int, ProductionInfo]

async get_objects() Anacreon#

Refreshes game state from the Anacreon API to update world state, fleet state, and so on.

Returns:

this object

Return type:

Anacreon

async get_tactical(battlefield_id: str) List[Dict[str, Any]]#

Get battlefield information of a planet, such as battle groups and squadron locations

Parameters:

battlefield_id (str) – The ID of the world to check

Returns:

A list of dicts that is essentially the raw JSON returned by the API.

Return type:

List[Dict[str, Any]]

get_valid_improvement_list(world: World) List[ScenarioInfoElement]#

Returns a list of scenario elements which represent improvements that can be built on a given world.

Parameters:

world (World) – The world in question

Returns:

A list of improvements that can be built.

Return type:

List[ScenarioInfoElement]

history: Dict[int, HistoryElement]#

A list of all history popups that would appear over your worlds in the game UI

async launch_lams(source_obj_id: int, target_obj_id: int) None#

Launch jumpmissiles from a citadel

Parameters:
  • source_obj_id (int) – The world ID of the citadel you wish to launch jumpmissiles from

  • target_obj_id (int) – The world/fleet ID you wish to shoot jumpmissiles at

async classmethod log_in(game_id: str, username: str, password: str) Anacreon#

Authenticate with the Anacreon API using a Multiverse username and password

Example

>>> import asyncio
>>> async def main():
...     client = await Anacreon.log_in("8JNJ7FNZ", "username", "password")
...     # do stuff with client
...
>>> asyncio.run(main())
Parameters:
  • game_id (str) – The game ID of the game you intend to manipulate. You can find the game ID by looking at the URL when you are playing Anacreon in your browser. e.g if the URL was anacreon.kronosaur.com/trantor.hexm?gameID=8JNJ7FNZ, the game ID would be 8JNJ7FNZ.

  • username (str) – The username to your Multiverse account

  • password (str) – The password to your Multiverse account

Returns:

An instance of the API client wrapper, which can be used to programmatically perform actions within the game

Return type:

Anacreon

async rename_object(obj_id: int, new_name: str) None#

Change the name of a world/fleet

Parameters:
  • obj_id (int) – The ID of the object you wish to rename

  • new_name (str) – The object’s new name

scenario_info_objects: Dict[int, ScenarioInfoElement]#

A mapping from trait/resource ID to ScenarioInfoElement

async sell_fleet(fleet_id: int, buyer_obj_id: int, resources: Dict[int, int] | List[int]) None#

Sell a fleet (or fleet cargo) to the Mesophons

As a prerequisite to calling this method, the fleet in question must already be stationed at a mesophon world.

Parameters:
  • fleet_id (int) – The ID of the fleet to sell from

  • buyer_obj_id (int) – The ID of the Mesophon world you are selling to

  • resources (IdValueMapping) – The resources from the fleet which you are selling to the mesophons. You may choose to sell a portion of your resources, as opposed to all of the fleet’s cargo or all of the ships.

async send_message(recipient_sov_id: int, message_text: str) None#

Send a message to another empire

Parameters:
  • recipient_sov_id (int) – The sovereign ID of the recipient empire

  • message_text (str) – The text of the message

async set_fleet_destination(fleet_obj_id: int, dest_obj_id: int) None#

Send a fleet somewhere

Parameters:
  • fleet_obj_id (int) – The ID of the fleet

  • dest_obj_id (int) – The world ID of the fleet’s desired destination

async set_history_read(history_id: int) bool#

Delet a history popup that show up over a planet

You can see a list of all the history popups by looking at Anacreon.history.

Parameters:

history_id (int) – The history ID of the popup as per HistoryElement.id.

Returns:

True if the popup was successfully closed.

Return type:

bool

async set_industry_alloc(world_id: int, industry_id: int, pct_labor_allocated: SupportsFloat) None#

On a world, set the percent labor allocation to a structure

For example, this method can be used to set the labor allocation to defense structures to 0%.

Parameters:
  • world_id (int) – The ID of the world that the industry is on

  • industry_id (int) – The trait ID of the industry in question

  • pct_labor_allocated (SupportsFloat) – The percent of total labor on the world to allocate to this structure. This value should be between 0 and 100.

async set_product_alloc(world_id: int, industry_id: int, pct_labor_allocated_by_resource: Dict[int, int] | List[int]) None#

Within a single industry, set the percent labor allocation to a single product of the industry.

For example, this method can be used to set the labor allocation on a jumpship yards planet to spend 100% of the labor available to the yards structure on building Reliant-class jumptransports.

Parameters:
  • world_id (int) – The ID of the world in question

  • industry_id (int) – The trait ID of the industry in question

  • pct_labor_allocated_by_resource (IdValueMapping) – A mapping from resource ID to percent labor allocation (from 0 to 100). This can either be a dict, or an alternating list.

async set_trade_route(importer_id: int, exporter_id: int, alloc_type: str = TradeRouteTypes.DEFAULT, alloc_value: str | float | None = None, res_type_id: int | None = None) None#

Create/update a trade route between 2 planets

Parameters:
  • importer_id (int) – The ID of the world that is importing resources

  • exporter_id (int) – The ID of the world that is exporting resources

  • alloc_type (TradeRouteTypes, optional) – How to decide how the trade route should be set. Defaults to TradeRouteTypes.DEFAULT, which emulates the behavior of setting up a 1 way trade route between 2 unconnected planets in the game UI.

  • alloc_value (Optional[Union[str, float]], optional) – The percent of demand on the importing world to import from (between 0 and 999). Defaults to None.

  • res_type_id (Optional[int], optional) – The ID of the resource to import.

sieges: Dict[int, Siege]#

A mapping from siege ID to Siege instances

property sov_id: int#

The sovereign ID of the currently logged in player

sovereigns: Dict[int, Sovereign]#

A mapping from sovereign ID to Sovereign instance

space_objects: Dict[int, World | Fleet]#

A mapping from world/fleet ID to World or Fleet instance

async stop_trade_route(planet_id_a: int, planet_id_b: int) None#

Stop all trade between 2 planets

If you need to stop trade on only one resource, you may do the set the percent of demand to import to 0 using Anacreon.set_trade_route() with alloc_type as TradeRouteTypes.CONSUMPTION.

Parameters:
  • planet_id_a (int) – The ID of one of the worlds on the trade route

  • planet_id_b (int) – The ID of another world on the trade route

async tactical_order(battlefield_id: int, order: TacticalOrderType | str, squadron_id: int, orbit: float | None = None, target_id: int | None = None) bool#

Send an order to a tactial squadron on a world

Parameters:
  • battlefield_id (int) – The ID of the world

  • order (Union[TacticalOrderType, str]) – The order you are giving

  • squadron_id (int) – The ID of the squadron to give the order to

  • orbit (Optional[float]) – If order is TacticalOrderType.ORBIT, this should be the new orbit altitude

  • target_id (Optional[int]) – If order is TacticalOrderType.TARGET, this should be the id of the tactical squadron to target

Returns:

True if the order was successfully processed

Return type:

bool

async transfer_fleet(fleet_obj_id: int, dest_obj_id: int, resources: Dict[int, int] | List[int]) None#

Transfer ships in a fleet to another fleet/world

Parameters:
  • fleet_obj_id (int) – The ID of the fleet to transfer from

  • dest_obj_id (int) – The ID of the fleet/world to transfer to

  • resources (IdValueMapping) – The resources from the fleet to transfer

async wait_for_any_update() None#

This coroutine waits until any method that updates game state, such as Anacreon.designate_world() or Anacreon.attack(), is called.

One use case for this function is when you are just starting a script, and you spawn an Task to periodically fetch updates. Your main coroutine would have to block until the task fetches the first update.

async wait_for_get_objects() None#

This coroutine waits until Anacreon.get_objects() is called by someone else.

One use case for this function is when you have 2 long-lived async Task s running. One is caling Anacreon.get_objects() every minute, while the other is managing a fleet. The task managing the fleet could to use this method to wait for updates to the state

class anacreonlib.AnacreonObject(*, object_class: str)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'object_class': FieldInfo(annotation=str, required=True, alias='class', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: str#
class anacreonlib.AnacreonObjectWithId(*, object_class: str, id: int)#

Bases: AnacreonObject

Not all anacreon objects have an ID, most notably, UpdateObject

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

id: int#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'object_class': FieldInfo(annotation=str, required=True, alias='class', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

class anacreonlib.AuthenticationResponse(*, authToken: str, rights: List[str], scopedCredentials: int, username: str)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

auth_token: str#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'auth_token': FieldInfo(annotation=str, required=True, alias='authToken', alias_priority=1), 'rights': FieldInfo(annotation=List[str], required=True, alias='rights', alias_priority=1), 'scoped_credentials': FieldInfo(annotation=int, required=True, alias='scopedCredentials', alias_priority=1, metadata=[PlainSerializer(func=<function _convert_int_to_aeon_ipinteger>, return_type=PydanticUndefined, when_used='json-unless-none'), BeforeValidator(func=<function _convert_aeon_ipinteger_to_int>)]), 'username': FieldInfo(annotation=str, required=True, alias='username', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

rights: List[str]#
scoped_credentials: int#
username: str#
class anacreonlib.BattlePlanDetails(*, enemySovereignIDs: List[int] | None = None, objective: BattleObjective, sovereignID: int, status: str)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

enemy_sovereign_ids: List[int] | None#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'enemy_sovereign_ids': FieldInfo(annotation=Union[List[int], NoneType], required=False, alias='enemySovereignIDs', alias_priority=2), 'objective': FieldInfo(annotation=BattleObjective, required=True, alias='objective', alias_priority=1), 'sovereign_id': FieldInfo(annotation=int, required=True, alias='sovereignID', alias_priority=1), 'status': FieldInfo(annotation=str, required=True, alias='status', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

objective: BattleObjective#
sovereign_id: int#
status: str#
classmethod validate_enemy_sovereign_ids(values: Dict[str, Any]) Dict[str, Any]#
class anacreonlib.BattlePlanObject(*, object_class: Literal['battlePlan'], id: int, battlePlan: BattlePlanDetails)#

Bases: AnacreonObjectWithId

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

battle_plan: BattlePlanDetails#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'battle_plan': FieldInfo(annotation=BattlePlanDetails, required=True, alias='battlePlan', alias_priority=1), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['battlePlan'], required=True, alias='class', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: Literal['battlePlan']#
class anacreonlib.DestroyedSpaceObject(*, object_class: Literal['destroyedSpaceObject'], id: int)#

Bases: AnacreonObjectWithId

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['destroyedSpaceObject'], required=True, alias='class', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: Literal['destroyedSpaceObject']#
class anacreonlib.ExplorationGrid(*, radius: float, exploredOutline: List[List[float]])#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

explored_outline: List[List[float]]#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'explored_outline': FieldInfo(annotation=List[List[float]], required=True, alias='exploredOutline', alias_priority=1), 'radius': FieldInfo(annotation=float, required=True, alias='radius', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

radius: float#
class anacreonlib.Fleet(*, object_class: Literal['fleet'], id: int, ftlType: str, name: str, sovereignID: int, resources: List[int], news: List[News] | None = None, anchorObjID: int | None = None, battlePlan: BattlePlanDetails | None = None, pos: Tuple[float, float], dest: Tuple[float, float] | None = None, destID: int | None = None, eta: int | None = None, region: NebulaType = NebulaType.CLEAR_SPACE)#

Bases: AnacreonObjectWithId

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

anchor_obj_id: int | None#

None if this fleet is not currently stationed at a world. Otherwise, this is the ID of the world where this fleet is stationed.

battle_plan: BattlePlanDetails | None#
dest_id: int | None#
destination: Tuple[float, float] | None#
eta: int | None#

If not None, corresponds to the UpdateObject.update on which this fleet will arrive at its destination.

ftl_type: str#

Whether this is a jumpship fleet, starship/ramship fleet, or explorer fleet

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'anchor_obj_id': FieldInfo(annotation=Union[int, NoneType], required=False, alias='anchorObjID', alias_priority=1), 'battle_plan': FieldInfo(annotation=Union[BattlePlanDetails, NoneType], required=False, alias='battlePlan', alias_priority=1), 'dest_id': FieldInfo(annotation=Union[int, NoneType], required=False, alias='destID', alias_priority=1), 'destination': FieldInfo(annotation=Union[Tuple[float, float], NoneType], required=False, alias='dest', alias_priority=2), 'eta': FieldInfo(annotation=Union[int, NoneType], required=False, alias='eta', alias_priority=1), 'ftl_type': FieldInfo(annotation=str, required=True, alias='ftlType', alias_priority=1), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'news': FieldInfo(annotation=Union[List[News], NoneType], required=False, alias='news', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['fleet'], required=True, alias='class', alias_priority=2), 'pos': FieldInfo(annotation=Tuple[float, float], required=True, alias='pos', alias_priority=1), 'region': FieldInfo(annotation=NebulaType, required=False, default=<NebulaType.CLEAR_SPACE: 1>, alias='region', alias_priority=1), 'resources': FieldInfo(annotation=List[int], required=True, alias='resources', alias_priority=1), 'sovereign_id': FieldInfo(annotation=int, required=True, alias='sovereignID', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

name: str#
news: List[News] | None#

For fleets, you might get news if they were attacked by jumpmissiles

object_class: Literal['fleet']#
pos: Tuple[float, float]#
region: NebulaType#
resources: List[int]#
sovereign_id: int#
class anacreonlib.History(*, object_class: Literal['history'], history: List[HistoryElement])#

Bases: AnacreonObject

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

history: List[HistoryElement]#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'history': FieldInfo(annotation=List[HistoryElement], required=True, alias='history', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['history'], required=True, alias='class', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: Literal['history']#
class anacreonlib.HistoryElement(*, id: int, objID: int, subject: int, text: str)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

id: int#

ID of this history element, which can be passed to the setHistoryRead endpoint to clear this message

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'obj_id': FieldInfo(annotation=int, required=True, alias='objID', alias_priority=1), 'subject': FieldInfo(annotation=int, required=True, alias='subject', alias_priority=1), 'text': FieldInfo(annotation=str, required=True, alias='text', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

obj_id: int#

ID of the object this message applies to

subject: int#
text: str#
class anacreonlib.MesophonTrait(*, buyPrices: List[int | float], sellPrices: List[int | float], traitID: int)#

Bases: DeserializableDataclass

Trait applied to the Mesophon sovereign (NPE trading empire that players can buy ships from)

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

buy_prices: List[int | float]#

A list which alternates between resource ID and the number of aes this empire is willing to pay per unit (they are the buyer)

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'buy_prices': FieldInfo(annotation=List[Union[int, float]], required=True, alias='buyPrices', alias_priority=1), 'sell_prices': FieldInfo(annotation=List[Union[int, float]], required=True, alias='sellPrices', alias_priority=1), 'trait_id': FieldInfo(annotation=int, required=True, alias='traitID', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

sell_prices: List[int | float]#

A list which alternates between resource ID and the number of aes this empire is willing to accept per unit (they are the seller)

trait_id: int#
class anacreonlib.MilitaryForceInfo(space_forces: float, ground_forces: float, missile_forces: float, maneuvering_unit_forces: float)#

Bases: object

This is a dataclasses.dataclass()

ground_forces: float#

The amount of ground forces on a world/in a fleet, as would be shown in the game UI

maneuvering_unit_forces: float#

The amount of space forces that come from units that are ships (as opposed to fixed point units or satellite units)

missile_forces: float#

The amount of space forces that come from units that shoot missiles (as opposed to beam weapons)

space_forces: float#

The amount of space forces on a world/in a fleet, as would be shown in the game UI

class anacreonlib.NebulaType(value)#

Bases: int, Enum

Enum of types of space regions a world can be in

(technically, a world cannot be in a RIFT_ZONE) (these values are a guess)

CLEAR_SPACE = 1#
DARK_NEBULA = 3#
LIGHT_NEBULA = 2#
RIFT_ZONE = 4#
class anacreonlib.News(*, subject: int, text: str)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'subject': FieldInfo(annotation=int, required=True, alias='subject', alias_priority=1), 'text': FieldInfo(annotation=str, required=True, alias='text', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

subject: int#
text: str#
class anacreonlib.OwnSovereign(*, object_class: Literal['sovereign'], id: int, imperialMight: int, name: str, relationship: SovereignRelationship | None = None, doctrine: int | None = None, traits: List[MesophonTrait] | None = None, capitalID: int, stats: SovereignStats, foundedOn: int | None = None, territory: List[Tuple[float, float, float] | Tuple[float, float, float, float, float]] | None = None, adminRange: List[Tuple[float, float, float] | Tuple[float, float, float, float, float]], explorationGrid: ExplorationGrid, funds: List[int | float], secessionChance: float)#

Bases: ReigningSovereign

Represents the sovereign belonging to the user who is currently logged in

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

admin_range: List[Tuple[float, float, float] | Tuple[float, float, float, float, float]]#
exploration_grid: ExplorationGrid#
funds: List[int | float]#

Alternating list between resource ID and resource quantity As long as is only one currency (aes), this list will only have 2 elements max

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'admin_range': FieldInfo(annotation=List[Union[Tuple[float, float, float], Tuple[float, float, float, float, float]]], required=True, alias='adminRange', alias_priority=1), 'capital_id': FieldInfo(annotation=int, required=True, alias='capitalID', alias_priority=1), 'doctrine': FieldInfo(annotation=Union[int, NoneType], required=False, alias='doctrine', alias_priority=1), 'exploration_grid': FieldInfo(annotation=ExplorationGrid, required=True, alias='explorationGrid', alias_priority=1), 'founded_on': FieldInfo(annotation=Union[int, NoneType], required=False, alias='foundedOn', alias_priority=1), 'funds': FieldInfo(annotation=List[Union[int, float]], required=True, alias='funds', alias_priority=1), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'imperial_might': FieldInfo(annotation=int, required=True, alias='imperialMight', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['sovereign'], required=True, alias='class', alias_priority=2), 'relationship': FieldInfo(annotation=Union[SovereignRelationship, NoneType], required=False, alias='relationship', alias_priority=1), 'secession_chance': FieldInfo(annotation=float, required=True, alias='secessionChance', alias_priority=1), 'stats': FieldInfo(annotation=SovereignStats, required=True, alias='stats', alias_priority=1), 'territory': FieldInfo(annotation=Union[List[Union[Tuple[float, float, float], Tuple[float, float, float, float, float]]], NoneType], required=False, alias='territory', alias_priority=1), 'traits': FieldInfo(annotation=Union[List[MesophonTrait], NoneType], required=False, alias='traits', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

secession_chance: float#
stats: SovereignStats#
class anacreonlib.OwnedWorld(*, object_class: Literal['world'], id: int, culture: int, designation: int, efficiency: float, name: str, nearObjIDs: List[int] | None = None, orbit: List[float], population: int, pos: Tuple[float, float], resources: List[int] | None = None, sovereignID: int, techLevel: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], traits: List[int | Trait | Rebellion], worldClass: int, tradeRoutes: List[TradeRoute] | None = None, revIndex: RevIndex, battlePlan: BattlePlanDetails | None = None, targetTechLevel: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | None = None, targetPopulation: int | None = None, region: NebulaType = NebulaType.CLEAR_SPACE, baseConsumption: List[int | None], news: List[News] | None = None, tradeRouteMax: int | None = None)#

Bases: World

This is a world we know belongs to the current user because you are guaranteed to see certain fields

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

base_consumption: List[int | None]#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'base_consumption': FieldInfo(annotation=List[Union[int, NoneType]], required=True, alias='baseConsumption', alias_priority=1), 'battle_plan': FieldInfo(annotation=Union[BattlePlanDetails, NoneType], required=False, alias='battlePlan', alias_priority=1), 'culture': FieldInfo(annotation=int, required=True, alias='culture', alias_priority=1), 'designation': FieldInfo(annotation=int, required=True, alias='designation', alias_priority=1), 'efficiency': FieldInfo(annotation=float, required=True, alias='efficiency', alias_priority=1, metadata=[Ge(ge=0), Le(le=100)]), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'near_obj_ids': FieldInfo(annotation=Union[List[int], NoneType], required=False, alias='nearObjIDs', alias_priority=2), 'news': FieldInfo(annotation=Union[List[News], NoneType], required=False, alias='news', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['world'], required=True, alias='class', alias_priority=2), 'orbit': FieldInfo(annotation=List[float], required=True, alias='orbit', alias_priority=1), 'population': FieldInfo(annotation=int, required=True, alias='population', alias_priority=1), 'pos': FieldInfo(annotation=Tuple[float, float], required=True, alias='pos', alias_priority=1), 'region': FieldInfo(annotation=NebulaType, required=False, default=<NebulaType.CLEAR_SPACE: 1>, alias='region', alias_priority=1), 'resources': FieldInfo(annotation=Union[List[Annotated[int, PlainSerializer, BeforeValidator]], NoneType], required=False, alias='resources', alias_priority=1), 'rev_index': FieldInfo(annotation=RevIndex, required=True, alias='revIndex', alias_priority=1), 'sovereign_id': FieldInfo(annotation=int, required=True, alias='sovereignID', alias_priority=1), 'target_population': FieldInfo(annotation=Union[int, NoneType], required=False, alias='targetPopulation', alias_priority=1), 'target_tech_level': FieldInfo(annotation=Union[Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], NoneType], required=False, alias='targetTechLevel', alias_priority=1), 'tech_level': FieldInfo(annotation=Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], required=True, alias='techLevel', alias_priority=1), 'trade_route_max': FieldInfo(annotation=Union[int, NoneType], required=False, alias='tradeRouteMax', alias_priority=1), 'trade_routes': FieldInfo(annotation=Union[List[TradeRoute], NoneType], required=False, alias='tradeRoutes', alias_priority=1), 'traits': FieldInfo(annotation=List[Union[int, Trait, Rebellion]], required=True, alias='traits', alias_priority=1), 'world_class': FieldInfo(annotation=int, required=True, alias='worldClass', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

news: List[News] | None#
rev_index: RevIndex#
trade_route_max: int | None#
class anacreonlib.ProductionInfo(available: float = 0, consumed: float = 0, exported: float = 0, imported: float = 0, produced: float = 0, consumed_optimal: float = 0, exported_optimal: float = 0, imported_optimal: float = 0, produced_optimal: float = 0)#

Bases: object

This is a dataclasses.dataclass()

available: float = 0#

Amount of resource that is stockpiled on the world

consumed: float = 0#

Amount of resource that was consumed last watch

consumed_optimal: float = 0#

Amount of resource that would have been consumed last watch if there were no resource shortages

exported: float = 0#

Amount of resource that was exported last watch

exported_optimal: float = 0#

Amount of resource that would have been exported last watch if there were no resource shortages

imported: float = 0#

Amount of resource that was imported last watch

imported_optimal: float = 0#

Amount of resource that would have been imported last watch if there were no resource shortages

produced: float = 0#

Amount of resource that was produced last watch

produced_optimal: float = 0#

Amount of resource that would have been produced last watch if there were no resource shortages

class anacreonlib.Rebellion(*, popularSupport: float, rebelForces: float, rebellionStart: int, traitID: int)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'popular_support': FieldInfo(annotation=float, required=True, alias='popularSupport', alias_priority=1), 'rebel_forces': FieldInfo(annotation=float, required=True, alias='rebelForces', alias_priority=1), 'rebellion_start': FieldInfo(annotation=int, required=True, alias='rebellionStart', alias_priority=1), 'trait_id': FieldInfo(annotation=int, required=True, alias='traitID', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

popular_support: float#

if popular support is greater than 0`, it indicates rebel support if it is less than 0`, it indicates imperial support

rebel_forces: float#
rebellion_start: int#
trait_id: int#
class anacreonlib.RegionObject(*, object_class: Literal['region'], id: int, shape: List[RegionShape], type: int)#

Bases: AnacreonObjectWithId

Typically used to encode the location of nebulas, rift zones, and clear space

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['region'], required=True, alias='class', alias_priority=2), 'shape': FieldInfo(annotation=List[RegionShape], required=True, alias='shape', alias_priority=1), 'type': FieldInfo(annotation=int, required=True, alias='type', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: Literal['region']#
shape: List[RegionShape]#
type: int#

Corresponds to the ScenarioInfoElement for this region type

class anacreonlib.RegionShape(*, holes: List[List[float]] | None = None, outline: List[float])#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

holes: List[List[float]] | None#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'holes': FieldInfo(annotation=Union[List[List[float]], NoneType], required=False, alias='holes', alias_priority=1), 'outline': FieldInfo(annotation=List[float], required=True, alias='outline', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

outline: List[float]#
class anacreonlib.ReigningSovereign(*, object_class: Literal['sovereign'], id: int, imperialMight: int, name: str, relationship: SovereignRelationship | None = None, doctrine: int | None = None, traits: List[MesophonTrait] | None = None, capitalID: int, stats: SovereignStats, foundedOn: int | None = None, territory: List[Tuple[float, float, float] | Tuple[float, float, float, float, float]] | None = None)#

Bases: Sovereign

Some Sovereigns are abdicated. This class is only for sovereigns currently playing the game.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

capital_id: int#
founded_on: int | None#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'capital_id': FieldInfo(annotation=int, required=True, alias='capitalID', alias_priority=1), 'doctrine': FieldInfo(annotation=Union[int, NoneType], required=False, alias='doctrine', alias_priority=1), 'founded_on': FieldInfo(annotation=Union[int, NoneType], required=False, alias='foundedOn', alias_priority=1), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'imperial_might': FieldInfo(annotation=int, required=True, alias='imperialMight', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['sovereign'], required=True, alias='class', alias_priority=2), 'relationship': FieldInfo(annotation=Union[SovereignRelationship, NoneType], required=False, alias='relationship', alias_priority=1), 'stats': FieldInfo(annotation=SovereignStats, required=True, alias='stats', alias_priority=1), 'territory': FieldInfo(annotation=Union[List[Union[Tuple[float, float, float], Tuple[float, float, float, float, float]]], NoneType], required=False, alias='territory', alias_priority=1), 'traits': FieldInfo(annotation=Union[List[MesophonTrait], NoneType], required=False, alias='traits', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

stats: SovereignStats#
territory: List[Tuple[float, float, float] | Tuple[float, float, float, float, float]] | None#
class anacreonlib.Relationship(*, object_class: Literal['relationship'], id: int, relationship: SovereignRelationship)#

Bases: AnacreonObjectWithId

Partial update for sovereigns

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['relationship'], required=True, alias='class', alias_priority=2), 'relationship': FieldInfo(annotation=SovereignRelationship, required=True, alias='relationship', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: Literal['relationship']#
relationship: SovereignRelationship#
class anacreonlib.RevIndex(value)#

Bases: str, Enum

Enum of social orders a world can have

AGGRIEVED = 'aggrieved'#
CIVIL_WAR = 'civil war'#
CONTENT = 'content'#
DISSATISFIED = 'dissatisfied'#
HAPPY = 'happy'#
REBELLING = 'rebelling'#
RIOTING = 'rioting'#
class anacreonlib.Selection(*, object_class: Literal['selection'], id: int)#

Bases: AnacreonObjectWithId

The API returns this object if it wants the UI to select something as a result of the API request

For example, when you deploy a fleet, the API returns one of these objects in order to signal that the new fleet should be selected.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['selection'], required=True, alias='class', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

object_class: Literal['selection']#
class anacreonlib.Siege(*, object_class: Literal['siege'], id: int, anchorObjID: int, attackForces: float, defenseForces: float, name: str, news: List[News] | None = None, pos: Tuple[float, float], resources: List[float] | None = None, sovereignID: int, status: SiegeStatus | None = None, timeleft: int | None = None)#

Bases: AnacreonObjectWithId

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

anchor_obj_id: int#
attack_forces: float#
defense_forces: float#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'anchor_obj_id': FieldInfo(annotation=int, required=True, alias='anchorObjID', alias_priority=1), 'attack_forces': FieldInfo(annotation=float, required=True, alias='attackForces', alias_priority=1), 'defense_forces': FieldInfo(annotation=float, required=True, alias='defenseForces', alias_priority=1), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'news': FieldInfo(annotation=Union[List[News], NoneType], required=False, alias='news', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['siege'], required=True, alias='class', alias_priority=2), 'pos': FieldInfo(annotation=Tuple[float, float], required=True, alias='pos', alias_priority=1), 'resources': FieldInfo(annotation=Union[List[float], NoneType], required=False, alias='resources', alias_priority=1), 'sovereign_id': FieldInfo(annotation=int, required=True, alias='sovereignID', alias_priority=1), 'status': FieldInfo(annotation=Union[SiegeStatus, NoneType], required=False, alias='status', alias_priority=1), 'timeLeft': FieldInfo(annotation=Union[int, NoneType], required=False, alias='timeleft', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

name: str#
news: List[News] | None#
object_class: Literal['siege']#
pos: Tuple[float, float]#
resources: List[float] | None#
sovereign_id: int#
status: SiegeStatus | None#
timeLeft: int | None#
class anacreonlib.Sovereign(*, object_class: Literal['sovereign'], id: int, imperialMight: int, name: str, relationship: SovereignRelationship | None = None, doctrine: int | None = None, traits: List[MesophonTrait] | None = None)#

Bases: AnacreonObjectWithId

Any sovereign that has ever played in the current game

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

doctrine: int | None#
imperial_might: int#

A measure of the empire’s strength relative to you

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'doctrine': FieldInfo(annotation=Union[int, NoneType], required=False, alias='doctrine', alias_priority=1), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'imperial_might': FieldInfo(annotation=int, required=True, alias='imperialMight', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['sovereign'], required=True, alias='class', alias_priority=2), 'relationship': FieldInfo(annotation=Union[SovereignRelationship, NoneType], required=False, alias='relationship', alias_priority=1), 'traits': FieldInfo(annotation=Union[List[MesophonTrait], NoneType], required=False, alias='traits', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

name: str#
object_class: Literal['sovereign']#
relationship: SovereignRelationship | None#
traits: List[MesophonTrait] | None#
class anacreonlib.SovereignActions(*, attacksInitiated: int, offensivesInitiated: int, worldsConquered: int)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

attacks_initiated: int#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'attacks_initiated': FieldInfo(annotation=int, required=True, alias='attacksInitiated', alias_priority=1), 'offensives_initiated': FieldInfo(annotation=int, required=True, alias='offensivesInitiated', alias_priority=1), 'worlds_conquered': FieldInfo(annotation=int, required=True, alias='worldsConquered', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

offensives_initiated: int#
worlds_conquered: int#
class anacreonlib.SovereignRelationship(*, firstContact: int, ourActions: SovereignActions, theirActions: SovereignActions)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

first_contact: int#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'first_contact': FieldInfo(annotation=int, required=True, alias='firstContact', alias_priority=1), 'our_actions': FieldInfo(annotation=SovereignActions, required=True, alias='ourActions', alias_priority=1), 'their_actions': FieldInfo(annotation=SovereignActions, required=True, alias='theirActions', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

our_actions: SovereignActions#
their_actions: SovereignActions#
class anacreonlib.SovereignStats(*, fleets: int, population: int, resources: List[int] | None = None, techLevel: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], worlds: int)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

fleets: int#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'fleets': FieldInfo(annotation=int, required=True, alias='fleets', alias_priority=1, metadata=[PlainSerializer(func=<function _convert_int_to_aeon_ipinteger>, return_type=PydanticUndefined, when_used='json-unless-none'), BeforeValidator(func=<function _convert_aeon_ipinteger_to_int>)]), 'population': FieldInfo(annotation=int, required=True, alias='population', alias_priority=1), 'resources': FieldInfo(annotation=Union[List[Annotated[int, PlainSerializer, BeforeValidator]], NoneType], required=False, alias='resources', alias_priority=1), 'tech_level': FieldInfo(annotation=Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], required=True, alias='techLevel', alias_priority=1), 'worlds': FieldInfo(annotation=int, required=True, alias='worlds', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

population: int#
resources: List[int] | None#
tech_level: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]#
worlds: int#
class anacreonlib.TradeRoute(*, imports: List[float | None] | None = None, exports: List[float | None] | None = None, importTech: Tuple[int, int] | Tuple[int, int, Any] | None = None, exportTech: Tuple[int, int] | Tuple[int, int, Any] | None = None, partnerObjID: int, reciprocal: bool | None = None)#

Bases: DeserializableDataclass

Variables:
  • import_tech – tuple of the desired tech level to acheive, and how many levels uplifted the planet actually is

  • reciprocal – if true, the data for this trade route is attached to the partner object.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

export_tech: Tuple[int, int] | Tuple[int, int, Any] | None#
exports: List[float | None] | None#
import_tech: Tuple[int, int] | Tuple[int, int, Any] | None#

Third tuple element is usually not present. If present, it indicates why the world cannot be uplifted to the desired tech level.

imports: List[float | None] | None#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'export_tech': FieldInfo(annotation=Union[Tuple[int, int], Tuple[int, int, Any], NoneType], required=False, alias='exportTech', alias_priority=1), 'exports': FieldInfo(annotation=Union[List[Union[float, NoneType]], NoneType], required=False, alias='exports', alias_priority=1), 'import_tech': FieldInfo(annotation=Union[Tuple[int, int], Tuple[int, int, Any], NoneType], required=False, alias='importTech', alias_priority=1), 'imports': FieldInfo(annotation=Union[List[Union[float, NoneType]], NoneType], required=False, alias='imports', alias_priority=1), 'partner_obj_id': FieldInfo(annotation=int, required=True, alias='partnerObjID', alias_priority=1), 'reciprocal': FieldInfo(annotation=Union[bool, NoneType], required=False, alias='return', alias_priority=2)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

partner_obj_id: int#
reciprocal: bool | None#
class anacreonlib.Trait(*, allocation: float, buildData: List[float | None | List[Any]], isPrimary: bool | None = None, productionData: List[float | None] | None = None, isFixed: bool | None = None, targetAllocation: float, traitID: int, buildComplete: int | None = None, workUnits: float)#

Bases: DeserializableDataclass

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

allocation: float#
build_complete: int | None#
build_data: List[float | None | List[Any]]#
is_fixed: bool | None#
is_primary: bool | None#

True` if this structure is the primary industry on the world (i.e it belongs to the designation)

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'allocation': FieldInfo(annotation=float, required=True, alias='allocation', alias_priority=1), 'build_complete': FieldInfo(annotation=Union[int, NoneType], required=False, alias='buildComplete', alias_priority=1), 'build_data': FieldInfo(annotation=List[Union[float, NoneType, List[Any]]], required=True, alias='buildData', alias_priority=1), 'is_fixed': FieldInfo(annotation=Union[bool, NoneType], required=False, alias='isFixed', alias_priority=1), 'is_primary': FieldInfo(annotation=Union[bool, NoneType], required=False, alias='isPrimary', alias_priority=1), 'production_data': FieldInfo(annotation=Union[List[Union[float, NoneType]], NoneType], required=False, alias='productionData', alias_priority=1), 'target_allocation': FieldInfo(annotation=float, required=True, alias='targetAllocation', alias_priority=1), 'trait_id': FieldInfo(annotation=int, required=True, alias='traitID', alias_priority=1), 'work_units': FieldInfo(annotation=float, required=True, alias='workUnits', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

production_data: List[float | None] | None#
target_allocation: float#
trait_id: int#
work_units: float#
class anacreonlib.UpdateObject(*, object_class: Literal['update'], nextUpdateTime: int, sequence: int, update: float, year0: int)#

Bases: AnacreonObject

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'next_update_time': FieldInfo(annotation=int, required=True, alias='nextUpdateTime', alias_priority=1), 'object_class': FieldInfo(annotation=Literal['update'], required=True, alias='class', alias_priority=2), 'sequence': FieldInfo(annotation=int, required=True, alias='sequence', alias_priority=1, metadata=[PlainSerializer(func=<function _convert_int_to_aeon_ipinteger>, return_type=PydanticUndefined, when_used='json-unless-none'), BeforeValidator(func=<function _convert_aeon_ipinteger_to_int>)]), 'update': FieldInfo(annotation=float, required=True, alias='update', alias_priority=1), 'year0': FieldInfo(annotation=int, required=True, alias='year0', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

next_update_time: int#

Number of milliseconds until the next watch update happens on the server

object_class: Literal['update']#
sequence: int#

This is a unique ID associated with each state update. Using this number, the Anacreon server can know exactly what data it needs to send us in order to catch us up to speed with what changed since we last talked.

update: float#

Number of watches that have occured since the game started

year0: int#

The in-game calendar year in which the game started (e.g 4021)

class anacreonlib.World(*, object_class: Literal['world'], id: int, culture: int, designation: int, efficiency: float, name: str, nearObjIDs: List[int] | None = None, orbit: List[float], population: int, pos: Tuple[float, float], resources: List[int] | None = None, sovereignID: int, techLevel: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], traits: List[int | Trait | Rebellion], worldClass: int, tradeRoutes: List[TradeRoute] | None = None, revIndex: RevIndex | None = None, battlePlan: BattlePlanDetails | None = None, targetTechLevel: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | None = None, targetPopulation: int | None = None, region: NebulaType = NebulaType.CLEAR_SPACE)#

Bases: AnacreonObjectWithId

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

battle_plan: BattlePlanDetails | None#
culture: int#

This is a trait ID that represents something intrinsic about the world’s population

designation: int#

This trait ID corresponds to which designation the world has

efficiency: float#
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'alias_generator': <function _snake_case_to_lower_camel>, 'ignored_types': (<class 'functools.cached_property'>, <class 'set'>)}#

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

model_fields: ClassVar[dict[str, FieldInfo]] = {'battle_plan': FieldInfo(annotation=Union[BattlePlanDetails, NoneType], required=False, alias='battlePlan', alias_priority=1), 'culture': FieldInfo(annotation=int, required=True, alias='culture', alias_priority=1), 'designation': FieldInfo(annotation=int, required=True, alias='designation', alias_priority=1), 'efficiency': FieldInfo(annotation=float, required=True, alias='efficiency', alias_priority=1, metadata=[Ge(ge=0), Le(le=100)]), 'id': FieldInfo(annotation=int, required=True, alias='id', alias_priority=1), 'name': FieldInfo(annotation=str, required=True, alias='name', alias_priority=1), 'near_obj_ids': FieldInfo(annotation=Union[List[int], NoneType], required=False, alias='nearObjIDs', alias_priority=2), 'object_class': FieldInfo(annotation=Literal['world'], required=True, alias='class', alias_priority=2), 'orbit': FieldInfo(annotation=List[float], required=True, alias='orbit', alias_priority=1), 'population': FieldInfo(annotation=int, required=True, alias='population', alias_priority=1), 'pos': FieldInfo(annotation=Tuple[float, float], required=True, alias='pos', alias_priority=1), 'region': FieldInfo(annotation=NebulaType, required=False, default=<NebulaType.CLEAR_SPACE: 1>, alias='region', alias_priority=1), 'resources': FieldInfo(annotation=Union[List[Annotated[int, PlainSerializer, BeforeValidator]], NoneType], required=False, alias='resources', alias_priority=1), 'rev_index': FieldInfo(annotation=Union[RevIndex, NoneType], required=False, alias='revIndex', alias_priority=1), 'sovereign_id': FieldInfo(annotation=int, required=True, alias='sovereignID', alias_priority=1), 'target_population': FieldInfo(annotation=Union[int, NoneType], required=False, alias='targetPopulation', alias_priority=1), 'target_tech_level': FieldInfo(annotation=Union[Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], NoneType], required=False, alias='targetTechLevel', alias_priority=1), 'tech_level': FieldInfo(annotation=Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], required=True, alias='techLevel', alias_priority=1), 'trade_routes': FieldInfo(annotation=Union[List[TradeRoute], NoneType], required=False, alias='tradeRoutes', alias_priority=1), 'traits': FieldInfo(annotation=List[Union[int, Trait, Rebellion]], required=True, alias='traits', alias_priority=1), 'world_class': FieldInfo(annotation=int, required=True, alias='worldClass', alias_priority=1)}#

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

name: str#
near_obj_ids: List[int] | None#

This is a list of IDs of fleets that are stationed at this world

object_class: Literal['world']#
orbit: List[float]#
population: int#
pos: Tuple[float, float]#
region: NebulaType#
property resource_dict: Dict[int, float]#

A dict mapping from resource ID to resource qty on the world

resources: List[int] | None#

This is a list alternating between resource ID and quantity stockpiled on the world

rev_index: RevIndex | None#
sovereign_id: int#
property squashed_trait_dict: Dict[int, int | Trait]#

Return a dict mapping from trait ID to either trait ID or trait object

target_population: int | None#

If the population is going to change, the value of this field is what the planet is heading towards

Unit is millions of people

target_tech_level: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | None#

If the world is going to change tech levels soon, the value of this field is the target tech level

tech_level: Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]#
property trade_route_partners: Dict[int, TradeRoute] | None#

Returns a set of all of the trade route partners of this world

trade_routes: List[TradeRoute] | None#
traits: List[int | Trait | Rebellion]#
world_class: int#

Submodules#

anacreonlib.exceptions module#

exception anacreonlib.exceptions.AuthenticationException#

Bases: Exception

Thrown when we have issues authenticating

exception anacreonlib.exceptions.HexArcException#

Bases: Exception

Thrown when we try to make a request that violates some invariant of Anacreon

For example,
  • You cannot sell resources that you don’t have

  • You cannot designate a world that doesn’t belong to you

and so on.

anacreonlib.utils module#

Utility function to help with decode information from the Anacreon API

Where possible, function signatures have been ordered with partial application (see functools.partial()) in mind.

anacreonlib.utils.dist(pointA: Tuple[float, float], pointB: Tuple[float, float]) float#

Retuns the distance between 2 points

Example

>>> pointA = (0, 0)
>>> pointB = (3, 4)
>>> utils.dist(pointA, pointB)
5.0
Parameters:
  • pointA (Location) – An (x, y) coordinate pair

  • pointB (Location) – An (x, y) coordinate pair

Returns:

The distance between the two points

Return type:

float

anacreonlib.utils.does_trait_depend_on_trait(scninfo: List[ScenarioInfoElement], trait_a: int, trait_b: int) bool#

Check if a trait_b has another trait_a anywhere in the chain of requirements.

For example, a sealed arcology (trait ID 218) is an upgrade to a domed city (trait id 88). So, the call utils.does_trait_depend_on_trait(scninfo, 218, 88) would return True because trait ID 218 needs trait ID 88 to be built first.

Note that there can be multiple upgrade paths to a more advanced trait/improvement. For example, the the sealed arcology ruins (ID 219) are also a predecessor to the sealed arcology (ID 218).

Parameters:
  • scninfo (List[ScenarioInfoElement]) – The scenario info

  • trait_a (int) – The ID of the ‘more advanced’ trait

  • trait_b (int) – The ID of the ‘less advanced’ trait

Returns:

Whether trait_a needs trait_b to be built first.

Return type:

bool

anacreonlib.utils.flat_list_to_n_tuples(n: int, lst: List[T]) List[Tuple[T, ...]]#

Converts a list [1,2,3,4,5,6,...] into a list of tuples [(1,2,3), (4,5,6), ...] where the length of each tuple is specified by the parameter n

Example

One use case of this function is to handle import data

>>> imports = [130, 100, 5700, None, 260, 100, 6400, 500]
>>> for res_id, pct, optimal, actual in flat_list_to_n_tuples(4, imports):
...     print(f"Imported {actual or optimal} units of resource id {res_id} (optimal: {optimal})")
...
Imported 5700 units of resource id 130 (optimal: 5700)
Imported 500 units of resource id 260 (optimal: 6400)
Parameters:
  • n (int) – The length of each tuple in the returned list

  • lst (List[T]) – A flat list of all of the items

Returns:

A list of tuples, where each item in the original list appears exactly once.

Return type:

List[Tuple[T, …]]

anacreonlib.utils.flat_list_to_tuples(lst: Sequence[T]) List[Tuple[T, T]]#

Turn a flat list of alternating key-value pairs into a list of tuples

Example

A common use case of this function is to iterate over a resources list

>>> resources = [130, 500, 159, 15000]
>>> for res_id, res_qty in utils.flat_list_to_tuples(resources):
...     print(f"We have {res_qty} of resource id {res_id}")
...
We have 500 of resource id 130
We have 15000 of resource id 159
Parameters:

lst (Sequence[T]) – A flat sequence of alternating key-value pairs

Returns:

A list of key-value tuples

Return type:

List[Tuple[T, T]]

anacreonlib.utils.get_world_primary_industry_products(world: World) List[int] | None#

Get the list of resource IDs that a planet produces with its primary industry

Parameters:

world (World) – The world in question

Returns:

A list of resource IDs that the planet’s designation produces. If this is None, then the planet’s designation does not produce items (e.g it may be a foundation world, or autonomous)

Return type:

Optional[List[int]]

anacreonlib.utils.trait_inherits_from_trait(scninfo: List[ScenarioInfoElement], child_trait: Trait | int, parent_trait: Trait | int) bool#

Check if a trait inherits from another trait

Traits can extend other traits. For example, the trait for having abundant chronimium deposits, ID 50, inherits from the trait for having any chronimium deposits, ID 56. A world that has trait ID 50 also has trait ID 56. However, this is only implied by the inheritance hierarchy of traits – the world object as returned by the API does would only give the “most specific” trait. In this case, it would only explicitly say the world has trait ID 50. This function can be used to figure out that the world also has trait ID 56 as a result.

Parameters:
  • scninfo (List[ScenarioInfoElement]) – The scenario info

  • child_trait (Union[Trait, int]) – The ‘more advanced/specific’ trait (e.g the trait id for abundant chronimium deposits)

  • parent_trait (Union[Trait, int]) – The ‘less advanced/specific’ trait (e.g the trait id for chronimium deposits)

Raises:
  • LookupError – Raised if the child trait ID could not be found in the

  • scenario info

Returns:

True if the child trait supplants the parent trait, like how a

sealed arcology supplants a domed city. False otherwise.

Return type:

bool

anacreonlib.utils.trait_under_construction(squashed_trait_dict: Dict[int, int | Trait], trait_id: int) bool#

Check whether a world is still building a trait

Parameters:
Returns:

True if the world has the trait, and it is still building. False if the world has fully built the trait, or if it does not have the trait at all.

Return type:

bool

anacreonlib.utils.world_has_fully_built_trait(scninfo: List[ScenarioInfoElement], world: World, target_trait_id: int) bool#

Check that a world has fully built a trait to completion.

This function is aware of the trait inheritance hierarchy. So, for example, we would consider a planet that has a sealed arcology (trait ID 218) to have ‘fully built’ a domed city (trait ID 88), because a sealed arcology upgrades a domed city.

Parameters:
  • scninfo (List[ScenarioInfoElement]) – The scenario info for the game

  • world (World) – The world to check for

  • target_trait_id (int) – The trait ID to check for

Returns:

True if the world has the specified trait, or a successor to the specified trait. False otherwise.

Return type:

bool

anacreonlib.utils.world_has_trait(scninfo: List[ScenarioInfoElement], world: World, target_trait_id: int, include_world_characteristics: bool = True) bool#

Checks whether a world has a given trait, or a child trait extends the given trait

Parameters:
  • scninfo (List[ScenarioInfoElement]) – The scenario info for the game.

  • world (World) – The world to check

  • target_trait_id (int) – The trait to check the presence of

  • include_world_characteristics (bool, optional) – Whether or not we should take intrinsic world characteristics (e.g world type, designation) into account. Defaults to True.

Returns:

Whether or not the planet has the given trait.

Return type:

bool

anacreonlib.anacreon_async_client module#

class anacreonlib.anacreon_async_client.AnacreonAsyncClient(*, base_url: str = 'https://anacreon.kronosaur.com/api/')#

Bases: Consumer

A coroutine-based asynchronous API client to interact with anacreon

abort_attack = <uplink.commands.RequestDefinitionBuilder object>#
attack = <uplink.commands.RequestDefinitionBuilder object>#
authenticate_user = <uplink.commands.RequestDefinitionBuilder object>#
build_improvement = <uplink.commands.RequestDefinitionBuilder object>#
buy_item = <uplink.commands.RequestDefinitionBuilder object>#
deploy_fleet = <uplink.commands.RequestDefinitionBuilder object>#
designate_world = <uplink.commands.RequestDefinitionBuilder object>#
destroy_improvement = <uplink.commands.RequestDefinitionBuilder object>#
disband_fleet = <uplink.commands.RequestDefinitionBuilder object>#
get_game_info = <uplink.commands.RequestDefinitionBuilder object>#
get_game_list = <uplink.commands.RequestDefinitionBuilder object>#
get_objects = <uplink.commands.RequestDefinitionBuilder object>#
get_tactical = <uplink.commands.RequestDefinitionBuilder object>#
launch_lams = <uplink.commands.RequestDefinitionBuilder object>#
rename_object = <uplink.commands.RequestDefinitionBuilder object>#
sell_fleet = <uplink.commands.RequestDefinitionBuilder object>#
send_message = <uplink.commands.RequestDefinitionBuilder object>#
set_fleet_destination = <uplink.commands.RequestDefinitionBuilder object>#
set_history_read = <uplink.commands.RequestDefinitionBuilder object>#
set_industry_alloc = <uplink.commands.RequestDefinitionBuilder object>#
set_product_alloc = <uplink.commands.RequestDefinitionBuilder object>#
set_trade_route = <uplink.commands.RequestDefinitionBuilder object>#
stop_trade_route = <uplink.commands.RequestDefinitionBuilder object>#
tactical_order = <uplink.commands.RequestDefinitionBuilder object>#
transfer_fleet = <uplink.commands.RequestDefinitionBuilder object>#

anacreonlib.anacreon module#

The Anacreon class is a wrapper around AnacreonAsyncClient that handles basic functionality (such as state management and merging partial updates).

class anacreonlib.anacreon.Anacreon(auth_info: AnacreonApiRequest, game_info: ScenarioInfo, client: AnacreonAsyncClient | None = None)#

Bases: object

Construct an Anacreon instance directly

Consider using one of the helper class methods like log_in() instead

Parameters:
  • auth_info (AnacreonApiRequest) – A stub API request containing a valid auth token

  • game_info (ScenarioInfo) – Info about the game, such as all the traits that

  • client (Optional[AnacreonAsyncClient], optional) – The low-level API client to use in order to make HTTP requests. Defaults to None.

async abort_attack(battlefield_id: int) None#

Abort an attack in progress

Parameters:

battlefield_id (int) – The world ID of the planet that you are attacking

async attack(battlefield_id: int, objective: BattleObjective, enemy_sovereign_ids: List[int]) None#

Attack a world

Parameters:
  • battlefield_id (int) – The ID of the world that you intend to attack

  • objective (BattleObjective) – Whether you want to invade, reinforce a siege, or destroy all space defenses

  • enemy_sovereign_ids (List[int]) – A list of the sovereign ids that you wish to engage in battle with

async build_improvement(world_obj_id: int, improvement_id: int) None#

Build an improvement

Parameters:
  • world_obj_id (int) – The ID of the world to build the improvement on

  • improvement_id (int) – The trait ID of the improvement to build

async buy_item(source_obj_id: int, item_id: int, item_count: int) None#

Buy an item from the Mesophons.

As a prerequisite to calling this method, you must have a fleet stationed at the world where you wish to buy ships from.

Parameters:
  • source_obj_id (int) – The ID of the world to buy ships from

  • item_id (int) – The resource ID of the ship that you wish to buy

  • item_count (int) – The number of ships that you wish to buy. Unlike the UI, which only lets you buy ships in groups of 1000, you may specify any number here.

calculate_forces(object_or_resources: World | Fleet | Dict[int, int] | List[int]) MilitaryForceInfo#

Calculate the ground forces + space forces of a particular world/fleet

Parameters:

object_or_resources (Union[World, Fleet, IdValueMapping]) – Either the World object, the Fleet object, or a list/dict of resources.

Returns:

A dataclass containing the force information as it would be displayed in the Anacreon UI

Return type:

MilitaryForceInfo

calculate_remaining_cargo_space(fleet: Fleet | int) float#

Calculate the remaining cargo space on a fleet

Parameters:

fleet (Union[Fleet, int]) – Either the Fleet object, or the fleet ID

Raises:

LookupError – Raised if the fleet could not be found

Returns:

The remaining cargo space left in the fleet. Can be negative if uneven attrition has left more cargo in the fleet than it has space for.

Return type:

float

call_get_objects_periodically() Task[None]#

Spawns an Task that calls Anacreon.get_objects() every watch.

Returns:

The task that was spawned.

Return type:

asyncio.Task[None]

client: AnacreonAsyncClient#

the low level API client that is used to make HTTP requests to the Anacreon API

async deploy_fleet(source_obj_id: int, resources: Dict[int, int] | List[int]) Fleet | None#

Deploy a fleet

Parameters:
  • source_obj_id (int) – The world or fleet from which you wish to create the fleet

  • resources (IdValueMapping) – A mapping from resource IDs to quantities. Can either be a dict, or a flat list alternating between ID and qty.

Returns:

The newly created fleet.

Return type:

Optional[Fleet]

async designate_world(world_obj_id: int, designation_id: int) None#

Designate a world

Parameters:
  • world_obj_id (int) – The ID of the world you wish to designate

  • designation_id (int) – The trait ID of the designation you wish to give the world

async destroy_improvement(world_obj_id: int, improvement_id: int) None#

Destroy a structure/improvement on a world

Parameters:
  • world_obj_id (int) – The ID of the world on which you want to destroy the structure

  • improvement_id (int) – The trait ID of the structure you wish to destroy

async disband_fleet(fleet_obj_id: int, dest_obj_id: int) None#

Delete a fleet by forcing it to become a part of another object that it is stationed next to.

You can use this method to gift fleets to enemy sovereigns.

Parameters:
  • fleet_obj_id (int) – The ID of the fleet to disband

  • dest_obj_id (int) – The ID of the world/fleet that it should become a part of

async classmethod from_auth_token(game_id: str, auth_token: str, *, client: AnacreonAsyncClient | None = None) Anacreon#

Authenticate with the Anacreon API using an auth token

You can get an auth token by looking at your cookies for anacreon.kronosaur.com in your browser’s dev console.

Parameters:
  • game_id (str) – The game ID of the game you intend to manipulate

  • auth_token (str) – A valid Multiverse auth token

Returns:

An instance of the API client wrapper, which can be used to programmatically perform actions within the game

Return type:

Anacreon

game_info: ScenarioInfo#

The scenario info for the game

generate_production_info(world: World | int) Dict[int, ProductionInfo]#

Calculate production info for a world

Parameters:

world (Union[World, int]) – Either the World object, or the world ID.

Raises:

LookupError – Raised if world is a world ID that cannot be found

Returns:

A mapping from resource ID to ProductionInfo objects describing how much of that resource was imported/exported

Return type:

Dict[int, ProductionInfo]

async get_objects() Anacreon#

Refreshes game state from the Anacreon API to update world state, fleet state, and so on.

Returns:

this object

Return type:

Anacreon

async get_tactical(battlefield_id: str) List[Dict[str, Any]]#

Get battlefield information of a planet, such as battle groups and squadron locations

Parameters:

battlefield_id (str) – The ID of the world to check

Returns:

A list of dicts that is essentially the raw JSON returned by the API.

Return type:

List[Dict[str, Any]]

get_valid_improvement_list(world: World) List[ScenarioInfoElement]#

Returns a list of scenario elements which represent improvements that can be built on a given world.

Parameters:

world (World) – The world in question

Returns:

A list of improvements that can be built.

Return type:

List[ScenarioInfoElement]

history: Dict[int, HistoryElement]#

A list of all history popups that would appear over your worlds in the game UI

async launch_lams(source_obj_id: int, target_obj_id: int) None#

Launch jumpmissiles from a citadel

Parameters:
  • source_obj_id (int) – The world ID of the citadel you wish to launch jumpmissiles from

  • target_obj_id (int) – The world/fleet ID you wish to shoot jumpmissiles at

async classmethod log_in(game_id: str, username: str, password: str) Anacreon#

Authenticate with the Anacreon API using a Multiverse username and password

Example

>>> import asyncio
>>> async def main():
...     client = await Anacreon.log_in("8JNJ7FNZ", "username", "password")
...     # do stuff with client
...
>>> asyncio.run(main())
Parameters:
  • game_id (str) – The game ID of the game you intend to manipulate. You can find the game ID by looking at the URL when you are playing Anacreon in your browser. e.g if the URL was anacreon.kronosaur.com/trantor.hexm?gameID=8JNJ7FNZ, the game ID would be 8JNJ7FNZ.

  • username (str) – The username to your Multiverse account

  • password (str) – The password to your Multiverse account

Returns:

An instance of the API client wrapper, which can be used to programmatically perform actions within the game

Return type:

Anacreon

async rename_object(obj_id: int, new_name: str) None#

Change the name of a world/fleet

Parameters:
  • obj_id (int) – The ID of the object you wish to rename

  • new_name (str) – The object’s new name

scenario_info_objects: Dict[int, ScenarioInfoElement]#

A mapping from trait/resource ID to ScenarioInfoElement

async sell_fleet(fleet_id: int, buyer_obj_id: int, resources: Dict[int, int] | List[int]) None#

Sell a fleet (or fleet cargo) to the Mesophons

As a prerequisite to calling this method, the fleet in question must already be stationed at a mesophon world.

Parameters:
  • fleet_id (int) – The ID of the fleet to sell from

  • buyer_obj_id (int) – The ID of the Mesophon world you are selling to

  • resources (IdValueMapping) – The resources from the fleet which you are selling to the mesophons. You may choose to sell a portion of your resources, as opposed to all of the fleet’s cargo or all of the ships.

async send_message(recipient_sov_id: int, message_text: str) None#

Send a message to another empire

Parameters:
  • recipient_sov_id (int) – The sovereign ID of the recipient empire

  • message_text (str) – The text of the message

async set_fleet_destination(fleet_obj_id: int, dest_obj_id: int) None#

Send a fleet somewhere

Parameters:
  • fleet_obj_id (int) – The ID of the fleet

  • dest_obj_id (int) – The world ID of the fleet’s desired destination

async set_history_read(history_id: int) bool#

Delet a history popup that show up over a planet

You can see a list of all the history popups by looking at Anacreon.history.

Parameters:

history_id (int) – The history ID of the popup as per HistoryElement.id.

Returns:

True if the popup was successfully closed.

Return type:

bool

async set_industry_alloc(world_id: int, industry_id: int, pct_labor_allocated: SupportsFloat) None#

On a world, set the percent labor allocation to a structure

For example, this method can be used to set the labor allocation to defense structures to 0%.

Parameters:
  • world_id (int) – The ID of the world that the industry is on

  • industry_id (int) – The trait ID of the industry in question

  • pct_labor_allocated (SupportsFloat) – The percent of total labor on the world to allocate to this structure. This value should be between 0 and 100.

async set_product_alloc(world_id: int, industry_id: int, pct_labor_allocated_by_resource: Dict[int, int] | List[int]) None#

Within a single industry, set the percent labor allocation to a single product of the industry.

For example, this method can be used to set the labor allocation on a jumpship yards planet to spend 100% of the labor available to the yards structure on building Reliant-class jumptransports.

Parameters:
  • world_id (int) – The ID of the world in question

  • industry_id (int) – The trait ID of the industry in question

  • pct_labor_allocated_by_resource (IdValueMapping) – A mapping from resource ID to percent labor allocation (from 0 to 100). This can either be a dict, or an alternating list.

async set_trade_route(importer_id: int, exporter_id: int, alloc_type: str = TradeRouteTypes.DEFAULT, alloc_value: str | float | None = None, res_type_id: int | None = None) None#

Create/update a trade route between 2 planets

Parameters:
  • importer_id (int) – The ID of the world that is importing resources

  • exporter_id (int) – The ID of the world that is exporting resources

  • alloc_type (TradeRouteTypes, optional) – How to decide how the trade route should be set. Defaults to TradeRouteTypes.DEFAULT, which emulates the behavior of setting up a 1 way trade route between 2 unconnected planets in the game UI.

  • alloc_value (Optional[Union[str, float]], optional) – The percent of demand on the importing world to import from (between 0 and 999). Defaults to None.

  • res_type_id (Optional[int], optional) – The ID of the resource to import.

sieges: Dict[int, Siege]#

A mapping from siege ID to Siege instances

property sov_id: int#

The sovereign ID of the currently logged in player

sovereigns: Dict[int, Sovereign]#

A mapping from sovereign ID to Sovereign instance

space_objects: Dict[int, World | Fleet]#

A mapping from world/fleet ID to World or Fleet instance

async stop_trade_route(planet_id_a: int, planet_id_b: int) None#

Stop all trade between 2 planets

If you need to stop trade on only one resource, you may do the set the percent of demand to import to 0 using Anacreon.set_trade_route() with alloc_type as TradeRouteTypes.CONSUMPTION.

Parameters:
  • planet_id_a (int) – The ID of one of the worlds on the trade route

  • planet_id_b (int) – The ID of another world on the trade route

async tactical_order(battlefield_id: int, order: TacticalOrderType | str, squadron_id: int, orbit: float | None = None, target_id: int | None = None) bool#

Send an order to a tactial squadron on a world

Parameters:
  • battlefield_id (int) – The ID of the world

  • order (Union[TacticalOrderType, str]) – The order you are giving

  • squadron_id (int) – The ID of the squadron to give the order to

  • orbit (Optional[float]) – If order is TacticalOrderType.ORBIT, this should be the new orbit altitude

  • target_id (Optional[int]) – If order is TacticalOrderType.TARGET, this should be the id of the tactical squadron to target

Returns:

True if the order was successfully processed

Return type:

bool

async transfer_fleet(fleet_obj_id: int, dest_obj_id: int, resources: Dict[int, int] | List[int]) None#

Transfer ships in a fleet to another fleet/world

Parameters:
  • fleet_obj_id (int) – The ID of the fleet to transfer from

  • dest_obj_id (int) – The ID of the fleet/world to transfer to

  • resources (IdValueMapping) – The resources from the fleet to transfer

update_obj: UpdateObject | None#
async wait_for_any_update() None#

This coroutine waits until any method that updates game state, such as Anacreon.designate_world() or Anacreon.attack(), is called.

One use case for this function is when you are just starting a script, and you spawn an Task to periodically fetch updates. Your main coroutine would have to block until the task fetches the first update.

async wait_for_get_objects() None#

This coroutine waits until Anacreon.get_objects() is called by someone else.

One use case for this function is when you have 2 long-lived async Task s running. One is caling Anacreon.get_objects() every minute, while the other is managing a fleet. The task managing the fleet could to use this method to wait for updates to the state

class anacreonlib.anacreon.MilitaryForceInfo(space_forces: float, ground_forces: float, missile_forces: float, maneuvering_unit_forces: float)#

Bases: object

This is a dataclasses.dataclass()

ground_forces: float#

The amount of ground forces on a world/in a fleet, as would be shown in the game UI

maneuvering_unit_forces: float#

The amount of space forces that come from units that are ships (as opposed to fixed point units or satellite units)

missile_forces: float#

The amount of space forces that come from units that shoot missiles (as opposed to beam weapons)

space_forces: float#

The amount of space forces on a world/in a fleet, as would be shown in the game UI

class anacreonlib.anacreon.ProductionInfo(available: float = 0, consumed: float = 0, exported: float = 0, imported: float = 0, produced: float = 0, consumed_optimal: float = 0, exported_optimal: float = 0, imported_optimal: float = 0, produced_optimal: float = 0)#

Bases: object

This is a dataclasses.dataclass()

available: float = 0#

Amount of resource that is stockpiled on the world

consumed: float = 0#

Amount of resource that was consumed last watch

consumed_optimal: float = 0#

Amount of resource that would have been consumed last watch if there were no resource shortages

exported: float = 0#

Amount of resource that was exported last watch

exported_optimal: float = 0#

Amount of resource that would have been exported last watch if there were no resource shortages

imported: float = 0#

Amount of resource that was imported last watch

imported_optimal: float = 0#

Amount of resource that would have been imported last watch if there were no resource shortages

produced: float = 0#

Amount of resource that was produced last watch

produced_optimal: float = 0#

Amount of resource that would have been produced last watch if there were no resource shortages

Subpackages#