Skip to content
Yani edited this page Jun 9, 2024 · 6 revisions

KeeperFX API

KeeperFX has a TCP API server that can be used for inter-process communication (IPC). This means that you can make tools to interact with the game using a simple and straightforward interface.

This page is for software developers who want to write an application that can interact with the game.

Intro

The TCP server can be configured using the API_ENABLED and API_PORT variables in keeperfx.cfg. By default the API is disabled, and the port is set to 5599. Set API_ENABLED to ON to enable the API.

The API is a simple plaintext TCP server that uses JSON for communication. One message is read and handled on every game tick. This might be a bit slow, but it does make sure nothing blocks and the game runs as smooth as possible.

When developing a program or tool that communicates with the KeeperFX API, you can use telnet to try out your commands.

Features

The KeeperFX API exposes quite a few different features that you can make use of:

  • Execute a map command (Ex: ADD_CREATURE_TO_LEVEL, Although there is no support for scope bound commands yet like WIN_GAME)
  • Execute a console command (Ex: !frametime)
  • Read a variable
  • Set a variable
  • Get all player flags
  • Subscribe to a variable (+ unsubscribe)
  • Subscribe to an event (WIN_GAME, LOSE_GAME, GAME_LOADED, GAME_SAVED + unsubscribe)
  • Get information about the current map (+ campaign)
  • Get information about KeeperFX (currently only the version)

Subscriptions

The KeeperFX API implements a subscription based system for events and the change of variables. This way you can monitor when a variable in the game changes and act however you want when it gets changed. For example, you can have your 3rd party tool display the amount of imps you have, by subscribing to the IMP variable and waiting for a var_update event . You can also monitor specific events like a game is won or lost.

How to interact with the API

You simply need to code something to connect with the TCP server and send JSON string data and read the response. Almost all messages that are sent to the server will be given a return message with "success": true.

Data involving subscribed events and variables will be sent whenever they are changed. These subscription messages should not conflict with the order of return data for other actions you sent. The first response you get after you send a message will always be the corresponding response.

Remember that only a single incoming message is handled per game turn. This is meant to protect the game from freezing. Subscriptions will be grouped and sent as multiple messages in a single game tick, after a possible response message. This way you do not need to care about the correct order of messages, and you can handle every message that isn't a response separately.

Acknowledgement IDs (ack id)

The API allows you to add an extra ack variable to requests. This variable will be returned in the response exactly as it was given. This is useful if you have a client that reads response packets asynchronously. By generating a unique ID or string and sending it with your request you can always link a response packet back to the original request.

If you use a blocking TCP client you can simply read the first response after sending a request. You will not need this extra variable in this case.

Responses

Action

Every action will return with a success value, being either true or false:

key type value
success bool true

Data

Every action that returns data will put the data in the JSON as such:

key type value
success bool true
data object {}

If you are requesting the value of a variable or some specific string it will make data either an int or string.

Actions

get_kfx_info

Gets information about the KeeperFX instance that is active. This will return data about the game of the player. Currently only the version is returned. This will most likely change in the future.

key type value
action string "get_kfx_info"

Return data struct:

key type example return value
kfx_version string 1.0.0

get_level_info / get_map_info

Gets information about the map that is being played. These 2 actions are synonyms.

key type value
action string "get_level_info" or "get_map_info"

Return data struct:

key type example return value
level_name string Name of the level
level_number int The map number of this map. Ex: 123 for map00123
players int How many players are on this map
mapsize_x int Width of the map (in slabs)
mapsize_y int Height of the map (in slabs)
is_multiplayer bool Whether or not this is a multiplayer level or not
campaign campaign struct Data about the current campaign

Campaign struct:

key type example return value
campaign_name string The name of the campaign. Ex: 'Dungeon Keeper - Original Campaign'
campaign_display_name string The display name of the campaign. Ex: 'Dungeon Keeper original campaign'
campaign_fname string The filename of the campaign. Ex: 'keeporig'
is_map_pack bool Whether or not this campaign is actually a mappack instead.

subscribe_var

Subscribe to a variable and receive messages whenever the variable changes.

key type value
action string "subscribe_var"
var string The variable name
player (optional) string/int The player this variable belongs to. (Default: PLAYER0)

Returns "success": true if we are now subscribed to the variable. This action will also return true if we are already subscribed to it.

Possible errors:

error description
MISSING_VAR No variable supplied
UNKNOWN_VAR Unable to map given variable to game variable
SUB_FAILED Failed to sub to variable

unsubscribe_var

Unsubscribe a variable we previously subscribed to.

key type value
action string "unsubscribe_var"
var string The variable name
player (optional) string/int The player this variable belongs to. (Default: PLAYER0)

Returns "success": true if we are now unsubscribed. This action will also return true if we are not subscribed to it.

Possible errors:

error description
MISSING_VAR No variable supplied
UNKNOWN_VAR Unable to map given variable to game variable
UNSUB_FAILED Failed to unsubscribe the variable

subscribe_event

Subscribe to a game event. After subscribing to this game event the API will notify us of whenever this event happens.

key type value
action string "subscribe_event"
event string The event name (in capital letters)

Returns "success": true if we are now subscribed to the event. This action will also return true if we are already subscribed to it.

Possible events:

event name description
LOSE_GAME When the player loses the game
WIN_GAME When the player wins the game
GAME_SAVED When the player saves the game
GAME_LOADED When the player loads the game
GAME_STARTED When the player starts the map

Possible errors:

error description
MISSING_EVENT No event supplied
STRING_TOO_LONG The given event string is too long
SUB_FAILED Failed to sub to event

unsubscribe_event

Unsubscribe from a game event.

key type value
action string "unsubscribe_event"
event string The event name (in capital letters)

This returns "success": true if the command was successful.

This follows the same events as subscribe_event.

Possible errors:

error description
MISSING_EVENT No event supplied
STRING_TOO_LONG The given event string is too long
SUB_FAILED Failed to sub to event

unsubscribe_all

Unsubscribe from a all events and variable updates.

key type value
action string "unsubscribe_event"

This always returns "success": true.

map_command

Runs a map command in the given map.

key type value
action string "map_command"
command string The map command

This returns "success": true if the command was successful.

Scopes and multi-line commands do NOT work (yet) ! There are some commands that do not work as a single line either, like WIN_GAME or LOSE_GAME. This will most likely be changed in a future version.

Running commands when the game is paused does not work either, and you will get a "success": false back with the corresponding error.

Possible errors:

error description
GAME_IS_PAUSED The game is paused
MISSING_COMMAND You did not supply a command
FAILED_TO_EXECUTE_MAP_COMMAND The map command failed to execute. It's possible that this map command does not exist

console_command

Execute a console command for the specified player.

key type value
action string "console_command"
command string The console command
player (optional) string/int The player we want to have execute this console command

This returns "success": true if the command was successful.

Possible errors:

error description
GAME_IS_PAUSED The game is paused
MISSING_COMMAND You did not supply a command
FAILED_TO_EXECUTE_CONSOLE_COMMAND The console command failed to execute. It's possible that this map command does not exist or something else went wrong.

get_all_player_flags

Get a list of all player flags.

key type value
action string "get_all_player_flags"

Return data struct:

key type example return value
PLAYER0 flag struct {}
... flag struct {}
PLAYER6 flag struct {}
PLAYER_GOOD flag struct {}
PLAYER_NEUTRAL flag struct {}

Flag struct:

key type value
FLAG0 int <value>
... int <value>
FLAG7 int <value>

read_var

Get a the value of a game variable.

key type value
action string "read_var"
var string The variable name
player (optional) string/int The player this variable belongs to. (Default: PLAYER0)

Return data:

key type value
success bool true
data int <variable value>

Possible errors:

error description
MISSING_VAR No variable supplied
UNKNOWN_VAR Unable to map given variable to game variable

set_var

Set the value of a game variable.

key type value
action string "set_var"
var string The variable name
player (optional) string/int The player this variable belongs to. (Default: PLAYER0)
value int The value this variable should be set to

Possible variable types to update: FLAG, CAMPAIGN_FLAG, BOX_ACTIVATED, SACRIFICED, REWARDED

Return data:

key type value
success bool true

Possible errors:

error description
MISSING_VAR No variable supplied
UNKNOWN_VAR Unable to map given variable to game variable
UNABLE_TO_SET_VAR Unable to set this kind of variable (look above)
VALUE_MUST_BE_INT The given value must be an integer
Clone this wiki locally