Anacreon API

General discussion for the game Anacreon
Post Reply
--Imperator--
Militia Lieutenant
Militia Lieutenant
Posts: 242
Joined: Wed Aug 10, 2016 8:35 am

SungSlaver231 wrote:
Mon Jun 25, 2018 6:46 am
Additionally, I have created an (incomplete) Python package for interacting with the Anacreon API. Perhaps someone can find it useful.
First off, this is absolutely amazing. Thank you.

I've created this thread for players to discuss usage of the Anacreon API with respect to writing scripts/bots to automate gameplay. If this isn't allowed mods please remove it, but the official policy seems very liberal.

For anyone else new to scripting/coding wondering how to set their own thing up:

1. Download all the files from here into a directory (all credit to, and courtesy of SungSlaver231).

2. Then download and install Python 3 and the requests module. You can open the "IDLE" editor program, or any other code/text editor (e.g. Notepad++, Sublime) will do. Create a new file with extension .py, in the same directory as the anacreonlib files, name it myScript.py or similar.

3. Copy paste the below into the file, changing the global fields USERNAME, PASSWORD and SOV_ID as necessary. To get SOV_ID you need to run the script (press F5 in IDLE, or just run using the command line with "python ./myScript.py")

Code: Select all

from anacreon import Anacreon

USERNAME = "imperium"
PASSWORD = "hunter2"
GAME_ID = 4365595

api = Anacreon(USERNAME,PASSWORD)
api.gameID = GAME_ID
gameList = api.get_game_list()
gameInfo = api.get_game_info()
api.sovID = int(gameInfo['userInfo']['sovereignID'])
objects = api.get_objects()
4. You can "call" any of the functions from the anacreon.py file, there are very helpful comments already there which explain what they do, and what parameters to pass into each of them. Don't edit the anacreon.py file directly, all changes go into your myScript.py file. Calling functions is done like this: "api.functionNameHere(parameters , here)".

Here is an example of a function that gets the empire names of all players in the game, even if you haven't discovered them yet:

Code: Select all

def getSovereigns():
    sovereignList = []
    for key in gameInfo['sovereigns']:
        sovereignList.append(key['name'])
    print(sovereignList)
    return sovereignList
    
getSovereigns()
You would put this below that first block of code above ^^ and when you run the script you'll see its output on the command line window:

Code: Select all

['independent', 'Mesophon Traders Union', 'Olos Guaran', 'Faorn Empire', 'Kingdom of Johenna', 'Kalidorn', 'Omnithor', 'Thuhomur Wuchaiju', 'Durandal', 'New Aelion', 'Barricade Fellowship', 'M', 'Scavengers', 'Bozonation', 'evil space pirates', 'Emdief Integration', 'Mombetsu Union', 'ANTARes', 'Velari Directorate', 'kj', 'Also Observer', 'New Nirvana', ' 𝕭', 'IMPERIUM', 'Terran Collective']
5. Last thing is that the GAME_ID changes for each game, so when Era 4 Beta is launched you'll need to update that global field. It can be found from the URL (e.g. http://anacreon.kronosaur.com/trantor.h ... ID=4365595), so the gameID is 4365595. This is also in the anacreonlib readme.

Here is a quick intro to the Python language.

Hopefully that helps people get started, if there are any questions feel free to post them in this thread and I'll do my best to answer. I have lots of questions too, don't worry.
Last edited by --Imperator-- on Wed Jun 27, 2018 6:08 am, edited 2 times in total.
--Imperator--
Militia Lieutenant
Militia Lieutenant
Posts: 242
Joined: Wed Aug 10, 2016 8:35 am

I've printed out all the objects into a text file but its hard to make sense of it. Still no luck finding the "ID" of a unit type to use.

Also one more question: the Ministry record has something called "/api/launchLAMs", which I guess is referring to launching jumpmissiles from citadels? I'm wondering if there's a way to call this when an enemy fleet is detected.
george moromisato
Developer
Developer
Posts: 2997
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

FYI: I definitely support this effort. The official policy on scripts/bots is designed to be permissive, as long as it does not interfere with the experience for other players. More here: https://forums.kronosaur.com/viewtopic.php?f=48&t=8610
whaleduck
Militia Lieutenant
Militia Lieutenant
Posts: 185
Joined: Tue Jan 01, 2013 3:31 am
Location: Dodging jumpmissiles in a Helion

--Imperator-- wrote:
Tue Jun 26, 2018 10:51 am
Still no luck finding the "ID" of a unit type to use.
As far as I know, there are a few different kinds of ID's that the API uses
  • Object ID
    • The Object ID is the ID of particular objects in the game. For example, my capital has an ID of 90. This ID is unique for all the objects in the game i.e no other object has an ID of 90. For any particular object, its ID is the key in the dictionary returned by

      Code: Select all

      api.get_objects()
    • The value in the dictionary (which is also a dictionary) contains its ID under the key 'id'
    • If you happen to know the ID of the object you wish to interact with, you can use

      Code: Select all

      api.get_obj_by_id(id)
      to get the object's details
    • It is possible to select objects by ID in the game client by typing

      Code: Select all

      $Map.selectObjectByID(id, null)
      into the JavaScript console
  • Scenario ID
    • The scenario ID is the ID of the type of thing that the object is. Every type of object that can exist in the game has a scenario ID. For example, the structure that builds hypersonics has a scenario ID of 6, while the hypersonic units themselves have an ID of 139.
    • It is possible to get the list of all the things that can possibly exist in this Anacreon game through

      Code: Select all

      api.get_game_info()["scenarioInfo"]
      which returns a list of dictionaries that are structured like this:

      Code: Select all

      {
                  "category": "commodity",
                  "class": "resourceType",
                  "id": 0,
                  "isCargo": "true",
                  "mass": 5.0,
                  "nameDesc": "AR missile launcher",
                  "unid": "core.ARMissileLauncher"
      },
  • Tactical ID
    • This is the ID of unit groupings in a battle. You can get a list of all unit groupings at a particular battlefield by calling

      Code: Select all

      api.get_tactical(battlefield_object_id)
--Imperator-- wrote:
Tue Jun 26, 2018 10:51 am
I've printed out all the objects into a text file but its hard to make sense of it. Still no luck finding the "ID" of a unit type to use.

Also one more question: the Ministry record has something called "/api/launchLAMs", which I guess is referring to launching jumpmissiles from citadels? I'm wondering if there's a way to call this when an enemy fleet is detected.
Yes, but I haven't had the opportunity to launch jumpmissiles at anything yet, so I don't know how the request payload should be structured for that.
--Imperator--
Militia Lieutenant
Militia Lieutenant
Posts: 242
Joined: Wed Aug 10, 2016 8:35 am

Excellent, that works, thanks. I've successfully deployed fleets from the capital using API call only, without the game client. Shouldn't be a stretch to extend that to loop deploying units from shipyards, then after few calls to most_recent_fleet(), set_fleet_destination() and transfer_fleet() we'll have a "reinforcing" script.

And yes, the "scenario ID" for all the units was the one I was interested in. Surprise, surprise, it was at the top of gameInfo.txt all along.
george moromisato wrote:
Tue Jun 26, 2018 4:51 pm
FYI: I definitely support this effort. The official policy on scripts/bots is designed to be permissive, as long as it does not interfere with the experience for other players. More here: https://forums.kronosaur.com/viewtopic.php?f=48&t=8610
George, I'm thinking that more savvy players will be able to gain some unfair advantages over others with this. It's possible to automate many of the more tedious parts of the game, such as:

1. Deploying reinforcements to the capital from all the shipyards (what I'm doing)
2. Looking for worlds at certain TLs that don't have upgraded habitat structures/arcologies, then building them.
3. Buying fleets from Mesophon in quantities greater than 1000 at a time.
4. Creating "standing orders" for fleets, such as a call to attack() when the fleet arrives at its destination.

... among others.

If all the "busywork" or micromanagement is automated, players who have access to scripts have more time to focus on fighting other players, as opposed to managing their own empire, which is a clear-cut advantage. I'm definitely not saying "ban scripting altogether", but for future Eras maybe provide some of these "features" to regular players, things like: a button to automatically build structures, the ability to purchase more than 1000 ships at a time from Mesophon... etc. Just my two cents.
--Imperator--
Militia Lieutenant
Militia Lieutenant
Posts: 242
Joined: Wed Aug 10, 2016 8:35 am

Updated the instructions: we can call api.get_game_info() first and get api.sovID from the gameInfo dict without having to Ctrl-F it from a text file. More convenient this way.

Also: I forgot to add that people will need to install requests, as SungSlaver's anacreonlib uses that module but IIRC it doesn't come included by default in a new Python install.

Reference

Here is the list of unit IDs for this scenario:

Code: Select all

[['Helion', 100],
 ['Vanguard', 101],
 ['Cerberus', 117],
 ['Hammerhead', 118],
 ['Minotaur', 119],
 ['Sirius', 120],
 ['Adamant', 156],
 ['Undine', 157],
 ['Eldritch', 161],
 ['Stinger', 164],
 ['Reliant', 167],
 ['Warphant', 168],
 ['Behemoth', 226],
 ['Megathere', 227],
 ['Typhon', 228],
 ['Victory', 229],
 ['Cyclops', 230],
 ['Defiance', 231],
 ['Gorgos', 232],
 ['Manta', 233]]

[['armored infantry brigade', 26],
 ['exotroop brigade', 99],
 ['imperial guards brigade', 141],
 ['infantry brigade', 148]]
george moromisato
Developer
Developer
Posts: 2997
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

--Imperator-- wrote:
Wed Jun 27, 2018 2:29 am
George, I'm thinking that more savvy players will be able to gain some unfair advantages over others with this. It's possible to automate many of the more tedious parts of the game, such as:

1. Deploying reinforcements to the capital from all the shipyards (what I'm doing)
2. Looking for worlds at certain TLs that don't have upgraded habitat structures/arcologies, then building them.
3. Buying fleets from Mesophon in quantities greater than 1000 at a time.
4. Creating "standing orders" for fleets, such as a call to attack() when the fleet arrives at its destination.

... among others.

If all the "busywork" or micromanagement is automated, players who have access to scripts have more time to focus on fighting other players, as opposed to managing their own empire, which is a clear-cut advantage. I'm definitely not saying "ban scripting altogether", but for future Eras maybe provide some of these "features" to regular players, things like: a button to automatically build structures, the ability to purchase more than 1000 ships at a time from Mesophon... etc. Just my two cents.
I agree. I plan a two-pronged approach:

1. For obvious busywork (e.g., building habitats/arcologies) we should change the game to add some choices. See here: https://ministry.kronosaur.com/record.hexm?id=79886
2. If we can't remove the busywork from the game, we should take the best scripts and turn them into features for all players.

Script writers today are blazing the trail and exploring the kinds of features that we'll want in the future.
--Imperator--
Militia Lieutenant
Militia Lieutenant
Posts: 242
Joined: Wed Aug 10, 2016 8:35 am

george moromisato wrote:
Wed Jun 27, 2018 4:16 pm
I agree. I plan a two-pronged approach:
A sensible compromise.

I'm hoping to create a commandline interface (using SungSlaver's package as a framework), as an extension to the Anacreon game client, which provides quality-of-life type features to address some of the more tedious parts of the game. Hopefully in a user-friendly manner (See below)

A preview, inspired by the old R4021 news page:

Capture.PNG
Capture.PNG (81.22 KiB) Viewed 19189 times
Capture 1.PNG
Capture 1.PNG (30.02 KiB) Viewed 19189 times
Capture.PNG
Capture.PNG (158.85 KiB) Viewed 19168 times
So far, the order to reinforce worlds is working as expected. It asks the user for the type of shipyards they want to reinforce from, then iterates over every world they own of that type, deploys all available forces from it to the world name they set as the destination. Of course, if 2 of their worlds have the same name it won't work, so players shouldn't do that. What it doesn't do (yet) is merge all the fleets down to the destination, but fingers crossed a "Merge Fleet" action will feature in Era 4 (it was requested and tagged on Ministry too)

When this little project is complete I'll release it on the forums for all players to use as they wish, so no one has an "unfair" advantage. I'm planning to add a lot more to the "available orders" list, such as:

1. Build spaceports, habitats and arcologies on worlds that don't have them.
2. Buy fleets in quantities greater than 1000 at a time from Mesophon (if this still isn't implemented in Era 4)
3. Deploy transports, collect resources from worlds, then sell them to Mesophon (more complicated)
4. Automatically launch jumpmissiles against sovereigns designated as "enemy"
5. Set defense production to 0% for resource-only worlds.

Era 4 players feel free to add ideas for more orders that would be useful to perform.
Last edited by --Imperator-- on Thu Jun 28, 2018 10:56 am, edited 4 times in total.
whaleduck
Militia Lieutenant
Militia Lieutenant
Posts: 185
Joined: Tue Jan 01, 2013 3:31 am
Location: Dodging jumpmissiles in a Helion

--Imperator-- wrote:
Thu Jun 28, 2018 3:55 am
Era 4 players feel free to add ideas for more orders that would be useful to perform.
The endpoint /api/disbandFleet exists (on the server only, I can't find a reference to it in the client JavaScript), and I've added support for it in the latest commit. It allows one to instantly transfer the entire fleet down to another planet or fleet, even if the target planet/fleet belongs to another sovereign. Perhaps it would be useful to reinforce worlds in an area belonging to another empire in case of war?
--Imperator--
Militia Lieutenant
Militia Lieutenant
Posts: 242
Joined: Wed Aug 10, 2016 8:35 am

SungSlaver231 wrote:
Thu Jun 28, 2018 8:35 am
It allows one to instantly transfer the entire fleet down to another planet or fleet, even if the target planet/fleet belongs to another sovereign.
It appears so. Interesting.

I suggest keeping this as intended behavior, as players requested being able to "gift" units to other players:
Wayward Device wrote:
Sun Apr 29, 2018 3:28 pm
Diplomacy

- The ability to abandon words.
- The ability to gift ships to another player.
- The ability to gift worlds to another player.

All of these are possible (and already exploitable with alts etc) with the current mechanics. People want to do this and are already doing it, let's make it easy.
Post Reply