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.
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.
The KeeperFX API exposes quite a few different features that you can make use of:
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.
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.
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.
Every action will return with a success value, being either true or false:
key | type | value |
---|---|---|
success | bool | true |
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.
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 |