Intro

Every KeeperFX level needs a script file to work. This page explains how to make a script and provides an overview of all commands.

Table of Contents

Introduction to level scripts
Script Parameters and Variables
Setup Commands
Script flow control
Flags and Timers
Adding New Creatures and Parties to the Level
Displaying information and affecting interface
Manipulating Map
Manipulating Configs
Manipulating Creature stats
Manipulating individual Creatures
Manipulating Research
Tweaking players
Tweaking computer players
Specials
Effects
Other
Functions
New or Modified Script commands - they will only work on alpha versions
Deprecated

Example scripts

Introduction to level scripts

Every map of KeeperFX, like the original game, has a script file that describes how the game works. KeeperFX has a changed and expanded level script compared to the original game. This document assumes you are writing KeeperFX script, in which case you need to include the LEVEL_VERSION(1) command in your script or KeeperFX will interpret the level as a classic DK map.

KeeperFX can also run maps that use the original Dungeon Keeper script. The commands reference for that can be found here. If you want to convert Dungeon Keeper maps to KeeperFX maps follow this guide.

Finding the level script

When you first save your level, a number of files are created in the Levels directory. For example, for level 200 (the example map), the following files are created:

Map00200.apt
Map00200.clm
Map00200.dat
Map00200.inf
Map00200.lgt
Map00200.lif
Map00200.own
Map00200.slb
Map00200.tng
Map00200.txt
Map00200.wib
Map00200.wlb

For KFX format maps, .lif/.tng/.apt/.lgt files are replaced by .lof/.tngfx/.aptfx/.lgtfx files.

You will notice that there is a .txt file included in the list. This is the script file which you will edit.

If you open it, you will see that it contains many commands which the game uses to create the level. When you have looked at the example script, open the script file of your own level.

Script layout

You can enter commands into the script in any order. The script does not run in the same way as most other programs or HTML scripts. Instead, KeeperFX stores it all in memory. This means that code guarded by IF statements will be executed immediately when their conditions are met. Bear this in mind when you are writing your scripts. When working with conditions that are disabled in the script, note that they are evaluated from 'top level' to 'bottom level'.

IF(PLAYER0,FLAG1 >= 1)
  IF(PLAYER0,MONEY < 10000)
    NEXT_COMMAND_REUSABLE
    ADD_GOLD_TO_PLAYER(PLAYER0,1000)
  ENDIF
  SET_FLAG(PLAYER0,FLAG1,0)
ENDIF

In this above example the player will never get 1000 gold from the script, because FLAG0 will be reset to 0 before the next script level is evaluated. Best practice is to indent conditions, and to remember that the script is evaluated from left to right before it is read from top to bottom. This means that code blocks within nested IF statements are executed separately to and after the preceding block; these "subblocks" execute only after the entirety of the preceding block has been executed, and only if all preceding IF statements linked to it remain true.

IF(PLAYER0,FLAG0 == 1)
    REM Main block
    IF(PLAYER0,FLAG1 == 1)
        REM Subblock 1
        IF(PLAYER0,FLAG2 == 1)
            REM Subblock 2; will not work, because subblock 1 sets condition 1 to false
        ENDIF
        SET_FLAG(PLAYER0,FLAG0,0)
    ENDIF
    REM do something; always executes, even if condition 2 is true
ENDIF

Beyond the functional, it is good to have your script readable and easy to understand. Use the REM function to add comments and information where applicable. Because Timers, Flags, Action Points and Hero Gates cannot be named, it is best practice to document these at or near the top of the script:

REM FLAGS:
REM PLAYER_GOOD,FLAG3       - Stores when the Knight has been added to the level
REM PLAYER0,CAMPAIGN_FLAG1  - Records in how many campaign levels the player found the hidden shrine

REM TIMERS:
REM PLAYER1,TIMER1 	- Started when Blue Keeper is killed, spawns parties from the east
REM PLAYER2,TIMER1 	- Started when Blue Keeper is killed, spawns parties from the west
REM PLAYER_GOOD,TIMER2  - Time between discovering the hidden treasure room and spawning a Knight

REM HERO GATES:
REM 1 - Hidden beyond the gems
REM 2 - Central room of the fortress

REM ACTION POINTS:
REM 1 - North of the red portal
REM 2 - At the entrance of the fortress

To keep the script readable and easy to look at when searching for errors, it is good practice to keep to the following format so others can look at your script without finding it incomprehensible:

- Comments
- Setup Commands
- Modified rules and creature statistics
- Availability
- Hero Parties
- Advanced script blocks
- Scenario
- Victory condition

Some example scripts are provided at the end of this documentation.

Note: There is a limit on how many commands can be used in a same script:

256 CREATE_PARTY
256 ADD_TUNNELLER_PARTY_TO_LEVEL
256 ADD_PARTY_TO_LEVEL
512 IF
2048 script values

You can track how many commands you have in your script by opening the KeeperFX log file and looking for the line "Used script resources:"

Script Parameters and Variables

This section will describe parameters to script commands available to use in Dungeon Keeper.

Players

There are nine players in the game. Each has a number and colour.

Player Player Command Colour Number
Player 1 (single player) PLAYER0 RED 0
Player 2 (enemy) PLAYER1 BLUE 1
Player 3 (enemy) PLAYER2 GREEN 2
Player 4 (enemy) PLAYER3 YELLOW 3
Hero Dungeon PLAYER_GOOD WHITE 4
Neutral PLAYER_NEUTRAL  no colour/multicoloured 5
Player 6 (enemy) PLAYER4 PURPLE 6
Player 7 (enemy) PLAYER5 BLACK 7
Player 8 (enemy) PLAYER6 ORANGE 8
All Players ALL_PLAYERS 9

Neutral is used for creatures and rooms that have not been claimed by any players, e.g. unclaimed Portals and bonus creatures hidden on the level. The name PLAYER_NEUTRAL is added as a new possible player name, but it works only on some specific commands. Use it for example to place units or modify slabs. As Neutral players have no dungeon, you cannot query information relating to the neutral dungeon structure, for example how many neutral units there are.

The player numbers start at 0 and not 1. The [target player] variables found in the script take the number. Other commands accept the 'player command' or 'colour'.

The main (red) player is player 0 and the one you will almost always use for single player games. KeeperFX allows campaigns played from a different perspective, and multiplayer games will have the client players have non-red colours too.

PLAYER_GOOD is set to 'ROAMING' by default, meaning the heroes or creatures it has do not need a dungeon to function.

Creatures

All the creatures in the Dungeon Keeper have special names which you have to use when referring to them in the script. The following list shows you their proper name and the script name you should use.

CreaturesHeroes
Name Command
Imp IMP
Horned Reaper HORNY
Skeleton SKELETON
Troll TROLL
Dragon DRAGON
Demonspawn DEMONSPAWN
Fly FLY
Dark Mistress DARK_MISTRESS
Warlock SORCEROR
Bile Demon BILE_DEMON
Beetle BUG
Vampire VAMPIRE
Spider SPIDER
Hellhound HELL_HOUND
Ghost GHOST
Tentacle TENTACLE
Orc ORC
Druid DRUID
Name Command
Wizard WIZARD
Barbarian BARBARIAN
Archer ARCHER
Monk MONK
Dwarf DWARFA
Knight KNIGHT
Avatar AVATAR
Tunneller Dwarf TUNNELLER
Witch WITCH
Giant GIANT
Fairy FAIRY
Thief THIEF
Samurai SAMURAI
Time Mage TIME_MAGE
-- --
-- --
-- --
-- --

The ANY_CREATURE command may be used on [creature] parameters to target a random creature type.

Note: There is also a FLOATING_SPIRIT creature that is mainly used when your dungeon heart is destroyed (when you click on the Possess icon), or at the very beginning of any levels (when you "enter" into the Dungeon Heart). Floating Spirits can be added into creature pool, but they are useless so you can avoid them.

Note: How you design your level is up to you but when Dungeon Keeper was being developed, they made certain creatures not come through the Portals. Ghosts are created when a creature dies from torture. Skeletons are created when a creature dies in a Prison. Horned Reapers are only available through a sacrifice in the Temple and Vampires only rise from the Graveyard. Tentacles like water and are only bonuses on those levels with water. Bear this in mind when you are scripting your level.

Criterion

There's criteria, to be used on spells like LEVEL_UP_CREATURE, that select a specific creature.

criterion description
ANYWHERE Creature anywhere on the level
AT_ACTION_POINT[#] Unit at specified action point
MOST_EXPERIENCED Highest level creature
MOST_EXP_WANDERING Highest level idle creature
MOST_EXP_WORKING Highest level working creature
MOST_EXP_FIGHTING Highest level creature in combat
LEAST_EXPERIENCED Lowest level creature
LEAST_EXP_WANDERING Lowest level idle creature
LEAST_EXP_WORKING Lowest level working creature
LEAST_EXP_FIGHTING Lowest level creature in combat
NEAR_OWN_HEART Creature close to friendly dungeon heart
NEAR_ENEMY_HEART Creature close to enemy dungeon heart
ON_ENEMY_GROUND Creature on enemy tile
ON_FRIENDLY_GROUND Creature on friendly tile
ON_NEUTRAL_GROUND Unit on neutral ground, like dirt, water and neutral tiles.

Example:

REM Red units that reach action point 3 turn blue
NEXT_COMMAND_REUSABLE
CHANGE_CREATURE_OWNER(PLAYER0,ANY_CREATURE,AT_ACTION_POINT[3],PLAYER1)
Location

Script commands with the [location] variable, called [where] in the old documentation, accepts the following commands:

Command Description
Positive number Action Point of that number
Negative number Hero Gate with that number
Player name Dungeon Heart of the player
LAST_EVENT Last triggered Custom Mystery box or sacrificed unit
COMBAT[player name] The location of the last battle of the player in the brackets.
CTA[player name] The location where the Call to Arms power is cast by the player.

COMBAT and CTA can be used without brackets to get the human player, but this must not be used on multiplayer maps.

Variables

Variables are names that have a number associated with them, e.g. the MONEY variable contains the amount of gold that player has. Most variables in Dungeon Keeper are individual to each player and are constantly updated with the correct information. Some, such as the FLAGS (see SET_FLAG command for more information) need to be created and updated by the script.

The following variables are used by Dungeon Keeper FX:

variable description
MONEY The amount of money the player has
GAME_TURN The current game turn (player independent)
VIEW_TYPE What the player is currently viewing. Returns 1 when keeping, 2 in Possession, 4 on the map screen
HEART_HEALTH The amount of health the dungeon heart of the player has
TOTAL_DIGGERS The number of special diggers (Imps) that player has got
TOTAL_CREATURES The number of creatures that player has got
EVIL_CREATURES The number of evil creatures that player has got
GOOD_CREATURES The number of heroes that player has got
TOTAL_RESEARCH The amount of research points that player has got (see Manipulating Research section for more information)
TOTAL_DOORS The amount of doors that player has got
TOTAL_DOORS_MANUFACTURED The amount of doors the player created in the workshop
TOTAL_DOORS_USED The amount of doors the player placed on the map
TOTAL_TRAPS The amount of traps that player has got
TOTAL_TRAPS_MANUFACTURED The amount of traps the player created in the workshop
TOTAL_TRAPS_USED The amount of traps the player placed on the map
TOTAL_MANUFACTURED The amount of traps and doors the player created in the workshop
DOORS_SOLD How many doors the player sold
TRAPS_SOLD How many traps the player sold
MANUFACTURE_GOLD How much gold the player gained through selling traps and doors
MANUFACTURED_SOLD How many traps and doors the player sold
TOTAL_AREA The amount of tiles that player owns
TOTAL_CREATURES_LEFT The amount of creatures that have left that player's dungeon because they were annoyed
TOTAL_SALARY The amount of salary the player has payed up to this point
CURRENT_SALARY The current estimated amount of the players next payday
CREATURES_ANNOYED The number of creatures annoyed in that player's dungeon
TIMES_ANNOYED_CREATURE The number of times player did something a creature disliked
TIMES_TORTURED_CREATURE The number of times player placed any creature in torture room
TIMES_LEVELUP_CREATURE The number of times a creature gained a level in the training room
ACTIVE_BATTLES The amount of battles going on for the player. Multiple creatures can be part of a single battle.
BATTLES_WON The number of battles won by that player
BATTLES_LOST The number of battles lost by that player
ROOMS_DESTROYED The number of rooms belonging to the player which were sold or destroyed
SPELLS_STOLEN The number of spells stolen from that player
TIMES_BROKEN_INTO The number of times that players walls have been breached
DUNGEON_DESTROYED Whether that players Dungeon Heart has been destroyed (0 if still active, 1 if destroyed)
CREATURES_SCAVENGED_LOST Number of creatures lost by that player due to scavenging
CREATURES_SCAVENGED_GAINED Number of creatures gained by that player through scavenging
CREATURES_SACRIFICED Number of creatures sacrificed in the temple
CREATURES_FROM_SACRIFICE Number of creatures gained by the player through the temple
CREATURES_CONVERTED Number of creatures gained by the player through converting in the torture room
EVIL_CREATURES_CONVERTED Number of creatures gained by the player through converting in the torture room, excluding heroes and imps
GOOD_CREATURES_CONVERTED Number of heroes gained by the player through converting in the torture room, excluding tunnellers
ALL_DUNGEONS_DESTROYED Whether all the other players Dungeon Hearts (besides given player) are destroyed (0 if still active, 1 if destroyed)
KEEPERS_DESTROYED
KEEPERS_DESTROYED[player]
The amount of dungeon hearts destroyed by given player. If a player name is given then it only counts destroyed hearts of that player.
DOORS_DESTROYED The number of doors belonging to the player which were sold or destroyed
TOTAL_GOLD_MINED Total amount of gold mined by the player
GOLD_POTS_STOLEN Number of gold pots that were stolen from the player
BREAK_IN Amount of break-ins
GHOSTS_RAISED Number of Ghosts created in torture room
SKELETONS_RAISED Number of Skeletons created in prison
VAMPIRES_RAISED Number of Vampires created in graveyard
BONUS_TIME The current value of the BONUS_LEVEL_TIME timer
BOX#_ACTIVATED How many times a custom special box with number # has been activated
CREATURES_TRANSFERRED How many creatures have been send to the next realm
REWARDED[creature] How many times a specific creature type has been given as a reward from the temple
SACRIFICED[creature] How many time a creature of a specific type is currently inside the sacrificial pool. Rewards reset it to 0
TOTAL_SCORE The level score, based on quality of the dungeon and number of creatures
TIMERx The current value of the timer.
FLAGx TThe current value of the flag.
CAMPAIGN_FLAGx The current value of the campaign flag.
Game turns

A game turn is a counter that counts how many times Dungeon Keeper has run through it’s main loop. The main loop is a series of commands which tells the game to update and then draw everything on the screen. Each time it runs through these instructions, the game turn counter increases by one and the loop is run again.

When the game runs at default speed, it will do 20 turns per second. So if you want have a one minute delay, you should use 1200 game turns. Players may use frameskip to make it go faster, or use the -fps command line to make it go slower. Also, when the game will lag due to performance issues or multiplayer lag, things could run slower. However, please design for the default speed and avoid maps where players feel the need to frameskip to make the level fun.

Comparisons

The Comparisons are symbols which you can use to compare two values. These will be mainly used by the IF commands.

Command Description
== Equal to
!= Not equal to
< Less than
​> Greater than
<= Less than or equal to
​>= Greater than or equal to

Note: If possible, use ‘Less than or equal to’ or ‘Greater than or equal to’ instead of the ‘Equal to’ command because the IF command isn’t checked every game turn. This may cause the game to miss things and therefore cause errors. For example, instead of asking whether the player has 30 creatures, ask if the player has 30 creatures or more.

Action points

Action points are areas of the map that are triggered if a creature steps into it. The Action Point can only be triggered once (unless you use the RESET_ACTION_POINT command) and is player independent so you can only detect which player triggered it.

Each Action Point has a number which you will have to remember. You will use this number in the script.

Hero Gates are special Action Points that act as Portals for Heroes. They do not have trigger areas so you cannot use them as traps, only as entry points for parties or new creatures. Like the Action Points, each Hero Gate has a number and you will need to use this number in the script.

Room names
Room Command
Portal ENTRANCE
Treasure Room TREASURE
Dark Library RESEARCH
Prison PRISON
Torture Chamber TORTURE
Training Room TRAINING
Workshop WORKSHOP
Scavenger Room SCAVENGER
Temple TEMPLE
Graveyard GRAVEYARD
Barracks BARRACKS
Hatchery GARDEN
Lair LAIR
Bridge BRIDGE
Guard Post GUARD_POST
Door names
Door Command
Wooden Door WOOD
Braced Door BRACED
Steel Door STEEL
Magic Door MAGIC
Secret Door SECRET
Midas Door MIDAS
Trap names
Trap Command
Alarm Trap ALARM
Poison Gas Trap POISON_GAS
Lightning Trap LIGHTNING
Word of Power Trap WORD_OF_POWER
Lava Trap LAVA
Boulder Trap BOULDER
Demolition Trap" TNT
Default Manufacture Values

These are the default manufacture values for the doors:

Door Command Manufacture Value
Wooden Door WOOD 18000
Braced Door BRACED 24000
Steel Door STEEL 26000
Magic Door MAGIC 50000

These are the default manufacture values for the traps:

Trap Command Manufacture Value
Alarm Trap ALARM 18000
Poison Gas Trap POISON_GAS 20000
Lightning Trap LIGHTNING 20000
Word of Power Trap WORD_OF_POWER 20000
Lava Trap LAVA 20000
Boulder Trap BOULDER 25000
Power names
Power Command
Create Imp POWER_IMP
Obey POWER_OBEY
Sight of Evil POWER_SIGHT
Call to Arms POWER_CALL_TO_ARMS
Cave-in POWER_CAVE_IN
Heal Creature POWER_HEAL_CREATURE
Hold Audience POWER_HOLD_AUDIENCE
Lightning Strike POWER_LIGHTNING
Speed Creature POWER_SPEED
Protect Creature POWER_PROTECT
Conceal Creature POWER_CONCEAL
Disease POWER_DISEASE
Chicken POWER_CHICKEN
Destroy Walls POWER_DESTROY_WALLS
Armageddon POWER_ARMAGEDDON
Possess creature POWER_POSSESS
Ability to slap creatures POWER_SLAP
Power to pick creatures POWER_HAND

Note: The three last powers are given to you at start of the level, and by default you don't need library to store them.

Default Research Values

These are the default research values for the rooms:

Room Command Research Value
Treasure Room TREASURE 1000
Hatchery GARDEN 1000
Lair LAIR 1000
Library RESEARCH 1000
Training Room TRAINING 1000
Bridge BRIDGE 4600
Guard Post GUARD_POST 6700
Workshop WORKSHOP 9000
Barracks BARRACKS 12000
Prison PRISON 20000
Torture TORTURE 20000
Temple TEMPLE 25000
Graveyard GRAVEYARD 25000
Scavenger SCAVENGER 27500

These are the default research values for powers:

power Command Research Value
Create Imp POWER_IMP 1000
Sight of Evil POWER_SIGHT 3800
Speed Creature POWER_SPEED 5700
Obey POWER_OBEY 6000
Call to Arms POWER_CALL_TO_ARMS 7400
Conceal Creature POWER_CONCEAL 9400
Hold Audience POWER_HOLD_AUDIENCE 11000
Cave-in POWER_CAVE_IN 25000
Heal Creature POWER_HEAL_CREATURE 14000
Lightning Strike POWER_LIGHTNING 15000
Protect Creature POWER_PROTECT 15000
Chicken POWER_CHICKEN 20000
Disease POWER_DISEASE 20000
Armageddon POWER_ARMAGEDDON 100000
Destroy Walls POWER_DESTROY_WALLS 750000

Setup Commands

SET_GENERATE_SPEED

This command tells the game how long to wait before generating a new creature for each player.

SET_GENERATE_SPEED([a])

Where:

[a] - The number of game turns between each creature.

The type of creatures that appear cannot be scripted and will depend on the rooms the player has built. It will apply to all Portals on the map. The value can be changed within IF-statements.

Example:

REM Create a new creature for each player every 500 game turns
SET_GENERATE_SPEED(500)
COMPUTER_PLAYER

If you have placed down an enemy dungeon heart, this command tells Dungeon Keeper that a computer player needs to be assigned. Can be used inside IF-statements to change personalities mid level.

COMPUTER_PLAYER([player],[a])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[a] - A single number telling the game what attitude the computer player has. See table. Can also be set to 'ROAMING' to make it function like heroes.

Player Description
0 A general computer player with everything turned on. Builds rooms quickly and is aggressive.
1 Medium aggressive computer player. Builds rooms slowly.
2 Medium defensive computer player.
3 A defensive computer player that only builds rooms 3x3 tiles in size.
4 A defensive computer player that only builds rooms 4x4 tiles in size.
5 An aggressive computer player that only builds rooms 4x4 tiles in size.
6 General aggressive computer player.
7 General defensive computer player.
8 Constructive defensive player that builds 5x5 rooms. Doesn't dig for gold, doesn't move creatures.
9 A computer player which only moves creatures.
10 A medium computer player.
11 Medium aggressive computer player.
12 Rapid Gold Digging Computer with Imp Army.
13 Skirmish Defensive: Can randomly be selected on 1 player maps, turtles
14 Skirmish Peculiar: Can randomly be selected on 1 player maps, will build an onortodox dungeon shape
15 Skirmish Balanced: Can randomly be selected on 1 player maps, plays well rounded
16 Skirmish Rush: Can randomly be selected on 1 player maps, attacks quickly
ROAMING Roaming creatures that do not need a dungeon to function. PLAYER_GOOD is set to ROAMING by default
OFF Turns the computer back into a zombie player, without any activity.

Example:

REM Set up and aggressive computer that uses Player 2's dungeon
COMPUTER_PLAYER(PLAYER2,1)

Example 2:

REM On this map the heroes build rooms and can be defeated by killing their heart.
COMPUTER_PLAYER(PLAYER_GOOD,9)
REM And also, there are black roaming creatures on the map that belong to no dungeon and attack everybody.
COMPUTER_PLAYER(PLAYER5,ROAMING)
ALLY_PLAYERS

Sets up an alliance between two players. The difference to original DK is that this command takes 3 parameters - 2 are players, and third one is the status of the alliance. Note that computer players will not break the alliance by themselves, but human player may do so. So this command is mostly for controlling the computer players behavior.

Example:

ALLY_PLAYERS([player],[player],[state])

Where:

[player] - The player’s name, e.g. PLAYER1, which gets the alliance set.

[state] - What happens to the alliance, it can have the following values:

  • 0: Players are enemies, but may change that. Computer Players never will.
  • 1: Players are allied, but may change that. Computer Players never will.
  • 2: Players are enemies, and cannot change this.
  • 3: Players are allied, and cannot change this.

Example:

REM The Blue and Green keepers will not attack each other.
ALLY_PLAYERS(PLAYER1,PLAYER2,1)

Note that if you enable KeeperFX commands with LEVEL_VERSION(1), old ALLY_PLAYERS commands (without the extra parameter) will no longer work. Add a '1' to fix this.

START_MONEY

How much gold each player has at the start of the level.

START_MONEY([player],[gold])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[gold] - The amount of gold for that player.

Example:

REM Give all players 40000 in gold at the start of the level
START_MONEY(ALL_PLAYERS,40000)
MAX_CREATURES

The maximum number of creatures a player can have. The player can still gain creatures through Scavenging and Torturing but no more will come through the portal until the number of creatures drops below the maximum again.

MAX_CREATURES([player],[a])

Where:

[player] - The player name, e.g. PLAYER1. See Players section for more information.

[a] - The maximum number of creatures. This must be a number below 255.

Example:

REM Player 1 will not gain any more creatures through his Portal once he has 40 creatures in his dungeon
MAX_CREATURES(PLAYER1,40)
ADD_CREATURE_TO_POOL

The creature pool is a set number of creatures that can be attracted by all the players.

Imagine a large group of creatures waiting outside the Dungeon Area (all Portals share this group). A player puts down a room, e.g. a Torture Chamber, and a creature (Dark Mistress) is attracted. The Mistress is taken from this group. If there are no more Mistresses in the group then the player will not be able to gain any more unless he uses other means, e.g. scavenging. This is a first come, first serve system so players will need to hurry if they want to gain the rarest creatures. If a creature becomes angry, it will exit via an Portal and return to the pool. Dead creatures also return to the pool.

This command sets the number of creatures that are placed in this pool. If you leave any creatures off the list then they will not appear in the pool. Use it multiple times (within conditions) to add up.

ADD_CREATURE_TO_POOL([creature],[a])

Where:

[creature] - The creature’s name, e.g. BILE_DEMON. See Creatures section for more information.

[a] - The number of creature’s of that type in the pool.

Example:

ADD_CREATURE_TO_POOL(BILE_DEMON,20)
CREATURE_AVAILABLE

Tells the game whether a creature of specific kind can come through that player's Portal. Parameters of this command have been changed from the original game, and now look like this:

CREATURE_AVAILABLE([player],[creature],[can be attracted],[amount forced])

Where:

[can be attracted] - If set to 1, it is possible to attract the creature, either by rooms or by forced attraction (so it works like 4th parameter in original command).

[amount forced] - Amount of creatures of that kind which can be force-attracted (attracted even if player doesn't have rooms required by that creature). Originally there was no possibility to skip attraction conditions.

DEAD_CREATURES_RETURN_TO_POOL

Normally, when a creature dies, and its body vanishes, it is added to the creature pool again. This command allows you to ensure that all dead creatures are dead forever.

DEAD_CREATURES_RETURN_TO_POOL([a])

Where:

[a] - Logic value to control the creatures returning after death. The default value is 1, allowing dead creatures to come through portal again. Setting it to 0 will prevent dead creatures from returning.

Example:

REM Dead creatures will not return to pool on this map.
DEAD_CREATURES_RETURN_TO_POOL(0)
ROOM_AVAILABLE

This command tells the game that a specific room is available for the player to place down.

ROOM_AVAILABLE([player],[room],[can be available],[is available])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information. Works with ALL_PLAYERS.

[room] - The room’s name, e.g. TEMPLE. See Room names section for more information.

[can be available] - This value can be set to 0, 1, 2, 3 or 4.

  1. It will not become available at all.
  2. The room becomes available through research.
  3. The room becomes available when researched or when found on the map.
  4. The room may not be researched but becomes available when claimed on the map.
  5. The room becomes available for research after claimed on the map.

[is available] - This value should either be 0 or 1. If it is 1 then the room is available straight away. If it is 0 then the room can not be build until the conditions of 'can be available' are met.

Example:

REM This Treasure Room has been set so that it is available from the start of the level.
ROOM_AVAILABLE(ALL_PLAYERS,TREASURE,1,1)

REM This Torture Chamber has been set do that it needs to be researched before it becomes available.
ROOM_AVAILABLE(ALL_PLAYERS,TORTURE,1,0)
MAGIC_AVAILABLE

This command tells the game that a specific power is available for the player to cast.

MAGIC_AVAILABLE([player],[power],[can be available],[is available])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information. Works with ALL_PLAYERS.

[power] - The power’s name, e.g. POWER_LIGHTNING. See Power names section for more information.

[can be available] - This value can be set to 0 or 1. If it is 1 then you are telling the game that the power may be researched at some point.

[is available] - This value should either be 0 or 1. If it is 1 then the power is available straight away. If it is 0 then the power cannot become available until it is set to 1 or researched.

Example:

REM This Speed Creature power has been set so that it is available from the start of the level.
MAGIC_AVAILABLE(ALL_PLAYERS,POWER_SPEED,1,1)

REM This Conceal Creature power has been set do that it needs to be researched before it becomes available.
MAGIC_AVAILABLE(ALL_PLAYERS,POWER_CONCEAL,1,0)
DOOR_AVAILABLE

This command tells the game that a specific door is available for the player to construct.

DOOR_AVAILABLE([player],[door],[can be available],[number available])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information. Works with ALL_PLAYERS.

[door] - The door’s name, e.g. BRACED. See Door names section for more information.

[can be available] - This value can be set to 0 or 1. If it is 1 then you are telling the game that the door can be constructed.

[number available] - The number of doors available to the player at the start of the level or when they become available.

Example:

REM The Wooden Door is now available to the player to manufacture and none have been given to him at the start
DOOR_AVAILABLE(PLAYER1,WOOD,1,0)
TRAP_AVAILABLE

This command tells the game that a specific trap is available for the player to construct.

TRAP_AVAILABLE([player],[trap],[can be available],[number available])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information. Works with ALL_PLAYERS.

[trap] - The trap’s name, e.g. LAVA. See Trap names section for more information.

[can be available] - This value can be set to 0 or 1. If it is 1 then you are telling the game that the trap may be constructed at some point.

[number available] - The number of traps available to the player at the start of the level or when they become available.

Example:

REM *** The Word of Power Trap is now available to the player to manufacture
REM *** and none have been given to him at the start
TRAP_AVAILABLE(PLAYER1,WORD_OF_POWER,1,0)

Script flow control

LEVEL_VERSION

Lets the game know if the level was designed specially for KeeperFX. To use new script commands, you must start the script with LEVEL_VERSION(1). Without it, the new commands will not work properly, and the game will try to emulate old behavior of commands which were modified.

REM

This can be placed at the start of a line to tell the game to ignore any text after it.

Example:

REM ***** Setup Level Section *****
WIN_GAME

Tells the game that you have won the level. This command must be included in single player games to tell the player he has won. In multiplayer levels, it is not necessary. You should always use them with IF commands to make sure something happens to cause the game to end.

Example:

REM Win the level if Player 1's dungeon is destroyed
IF(PLAYER1,DUNGEON_DESTROYED==1)
  WIN_GAME
ENDIF
LOSE_GAME

Tells the game you have lost the level. This command does not always need to be included as you will automatically lose the level if you Dungeon Heart is destroyed. You should include it if there is a strict goal the player needs to attain.

Example:

REM Lose the level if Player 0's total battles lost is 30
IF(PLAYER0,BATTLES_LOST >= 30)
  LOSE_GAME
ENDIF
IF

This is used to test the differences between two values. This could either be a comparison between a variable and a number, or between two variables. If those two values agree with the comparison, the script will continue. If the two values do not agree with the comparison, the script will find the next ENDIF and continue from there.

IF([player],[variable][comparison][a])
IF([player],[variable][comparison][player],[variable])

Where:

[variable] - The name of a variable, timer, flag (all types), creature, room, trap or door.

  • Checking variable returns its value at the moment. See Variables section for more information.
  • Checking creature returns how many creatures of that kind a player owns. It doesn't matter if the player can controls them, or they're in custody.
  • Checking room returns how many slabs of that room the player owns.
  • Checking trap or door availability returns amount of deployed traps and doors owned by that player.
  • Checking TIMERx, FLAGx or CAMPAIGN_FLAGx returns its current value.

[player] - The player’s name, e.g. PLAYER1. If ALL_PLAYERS is used, then the condition has to be met for all of the players in order for the commands inside to be executed.

Example:

IF(PLAYER1,VAMPIRE > PLAYER0,VAMPIRE)
    IF(PLAYER0,VAMPIRE >= 1)
        QUICK_OBJECTIVE(1,"Blue has more vampires than you do. Attack him before scavenging starts")
    ENDIF
ENDIF
ENDIF

This command must be placed at the end of all IF statements. This tells the IF command where to jump to when the comparisons in the statement are not met.

See IF commands for examples.

IF_AVAILABLE

Checks availability of an item, and compares it to a second value. That value may be a number or variable. New option values have been added to this command:

IF_AVAILABLE([player],[variable][comparison][a])
IF_AVAILABLE([player],[variable][comparison][player],[variable])

Where:

[variable] - The name of a creature, room, power, trap or door.

  • Checking creature availability returns how many creatures of that kind can come from portal to that player. The check includes creature pool, players creature limit and whether attraction criteria are met.
  • Checking room availability returns whether the room can be built by a player. Cost of the room is not considered.
  • Checking power availability returns whether the power can be cast by a player. Cost of the power is not considered.
  • Checking trap or door availability returns amount of traps and doors a player has stored, either in workshop or in off-map storage.
  • Accepts TOTAL_CREATURES, TOTAL_DOORS and TOTAL_TRAPS

Example:

IF_AVAILABLE(PLAYER0,BOULDER > PLAYER_GOOD,TOTAL_CREATURES)
    QUICK_OBJECTIVE(1,"You have more boulders than there are heroes left. Go make pizza.")
    TRAP_AVAILABLE(PLAYER0,BOULDER,0,0)
ENDIF
IF_CONTROLS

Checks creatures controlled by a player and compares is to a second value. That value may be a number or variable. Units in an enemy prison are excluded here.

IF_CONTROLS([player],[variable][comparison][a])
IF_CONTROLS([player],[variable][comparison][player],[variable])

Where:

[variable] - The name of a creature. Returns how many creatures of given kind the player owns, excluding these under enemy control, like in his prison. Also accepts TOTAL_CREATURES, TOTAL_DIGGERS, EVIL_CREATURES and GOOD_CREATURES.

Example:

IF_CONTROLS(PLAYER0,DRAGON < PLAYER0,DRAGON)
    QUICK_OBJECTIVE(1,"Some of your Dragons are in enemy prison. Rescue them before they get converted.")
ENDIF
IF_SLAB_OWNER

Checks if a specific slab on the map belongs to specified player.

IF_SLAB_OWNER([slab x pos],[slab y pos],[player])

Where:

[slab x pos][slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

[player] - The player’s name, e.g. PLAYER1, to check against.

IF_SLAB_TYPE

Checks if a specific slab is of a specific type.

IF_SLAB_TYPE([slab x pos],[slab y pos],[slab])

Where:

[slab x pos][slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

[slab] - The name of the slab to check for. Take if from fxdata\terrain.cfg.

IF_ALLIED

Checks if a player is allied to another player, or tries to be.

IF_ALLIED([player],[target_player][comparison][a])

Where:

[player] - The player’s name, e.g. PLAYER1, who may or may not have an alliance.

[target_player] - The player name that's subject to alliance.

[a] - The value to compare against. Where '0' is not allied and '1' is.

Note that if the Red player clicks the Ally-button of Blue, comparing PLAYER0 to PLAYER1 already evaluates as true, even when blue has not done the same yet. Comparing PLAYER1 to PLAYER0 would still be false. For multiplayer games, check both sides.

Example:

SET_TIMER(PLAYER0,TIMER1)
ALLY_PLAYERS(PLAYER0,PLAYER1,1)

IF_ALLIED(PLAYER0,PLAYER1 == 0)
    QUICK_OBJECTIVE(1,"Blue will not accept this betrayal, prepare for battle.",PLAYER1)
    REM no going back now, lock as enemies
    ALLY_PLAYERS(PLAYER0,PLAYER1,2)
ENDIF
IF_ALLIED(PLAYER0,PLAYER2 == 1)
    IF_ALLIED(PLAYER0,PLAYER1 == 1)
        QUICK_OBJECTIVE(2,"Blue will not accept your alliance with Green, prepare for battle.",PLAYER1)
        REM lock blue as enemy
        NEXT_COMMAND_REUSABLE
        SET_TIMER(PLAYER0,TIMER1)
        ALLY_PLAYERS(PLAYER0,PLAYER1,2)
    ENDIF
    REM lock green as ally
    ALLY_PLAYERS(PLAYER0,PLAYER2,3)
ENDIF

IF(PLAYER0,ALL_DUNGEONS_DESTROYED == 1)
    REM Set on a timer to not win while switching allies.
    IF(PLAYER0,TIMER1 > 60)
        WIN_GAME
    ENDIF
ENDIF
IF_ACTION_POINT

Detects whether an Action Point has been trigger by one of that players creatures. A player can only trigger each Action point once unless you use the RESET_ACTION_POINT command.

IF_ACTION_POINT([action point],[player])

Where:

[action point] - Action Point number. See Action points section for more information.

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

Example:

REM If Action Point 2 has been triggered by one of Player 1's creatures then perform the following tasks
IF_ACTION_POINT(2,PLAYER1)

  ..

ENDIF
RESET_ACTION_POINT

Once an Action Point has been triggered, it cannot be triggered again unless it has been reset by this command.

RESET_ACTION_POINT([action point],[player]*)

Where:

[action point] - Action Point number. See Action points section for more information.

[player]* - Optional value, resets the Action Point only for the player name mentioned.

Example:

REM After the following line, the action point 3 can be triggered again
RESET_ACTION_POINT(3)
NEXT_COMMAND_REUSABLE

Once any action command, such as ADD_CREATURE_TO_LEVEL or SET_TIMER, has been triggered once, it cannot be triggered again. This means that you cannot create loops or generators that add heroes to the level each time one of your creatures steps foot in a room. To get around this, the Dungeon Keeper script has a special command called NEXT_COMMAND_REUSABLE. You will need to place this in front of every command in the loop to make it work (it does not need to be placed in front of IF commands)

Example:

REM *** This loop adds a new hero to the level at Hero Gate 3 every 1000 game turns. This is done by
REM *** starting a timer, adding the hero when it reaches 1000 and then resetting it again

SET_TIMER(PLAYER0,TIMER0)

IF(PLAYER0,TIMER0 >= 1000)
  NEXT_COMMAND_REUSABLE
  ADD_CREATURE_TO_LEVEL(PLAYER_GOOD,WITCH,-3,1,6,600)
  NEXT_COMMAND_REUSABLE
  SET_TIMER(PLAYER0,TIMER0)
ENDIF
RUN_AFTER_VICTORY

Lets the game know the script should continue to run after the game is won. Normally everything stops as soon as the a player wins the map, but include RUN_AFTER_VICTORY(1) in the script to have the game continue normally until the player presses the space bar. Useful if you want to give a player the chance to complete an optional objective you want to bring over to a next campaign level with a CAMPAIGN_FLAG or EXPORT_VARIABLE.

Flags and Timers

SET_FLAG

Sets up a flag that is assigned a number.

SET_FLAG([player],[flag],[a])

Where:

[player] - The player’s name, e.g. PLAYER1.

[flag] - The flag’s name.

[a] - The number assigned to the flag. This can be between -2,147,483,648 and 2,147,483,647.

There's multiple Flag types:

Type Flag names Use
FLAG FLAG0 to FLAG7 The classic flag. Will also be updated by custom sacrifice recipes. Accepts negative and very big numbers now.
CAMPAIGN_FLAG CAMPAIGN_FLAG0 to CAMPAIGN_FLAG7 Value is not forgotten at the end of a level.
BOX_ACTIVATED BOX0_ACTIVATED to BOX255_ACTIVATED Value is updated when you claim a custom special box with the respective number.
SACRIFICED SACRIFICED[creature] Shows how many units of the type are currently in the temple pool. Example SACRIFICED[FLY].
REWARDED REWARDED[creature] Shows how many units of the type the player has received from the temple.

Example:

IF(PLAYER0,MONEY == 0)
  REM All units get angry now.
  SET_FLAG(PLAYER0,SACRIFICED[VAMPIRE],2)
ENDIF

REM When player found both boxes with number 3, set the campaign flag give a unit on the next level
IF(PLAYER0,BOX3_ACTIVATED >= 2)
  SET_FLAG(PLAYER0,CAMPAIGN_FLAG1,1)
ENDIF
ADD_TO_FLAG

Adds a numeric value to the current flag value.

ADD_TO_FLAG([player],[flag],[a])

Where:

[player] - The player’s name, e.g. PLAYER1.

[flag] - The flag’s name to which you'll add the value, e.g. FLAG1, CAMPAIGN_FLAG2, BOX0_ACTIVATED

[a] - The amount added. This may be a positive or negative value, e.g. -1

Can be used to count the amount of loops, or give different weights to certain events. The values can be very large and may be negative. Example:

REM Spawn troll 3 times.
IF(PLAYER0,FLAG2 <= 3)
    IF(PLAYER_GOOD,TIMER1 >= 100)
        NEXT_COMMAND_REUSABLE
        ADD_CREATURE_TO_LEVEL(PLAYER0,TROLL,PLAYER0,1,1,0)
        NEXT_COMMAND_REUSABLE
        ADD_TO_FLAG(PLAYER0,FLAG2,1)
        NEXT_COMMAND_REUSABLE
        SET_TIMER(PLAYER_GOOD,TIMER1)
    ENDIF
ENDIF
REM If player has a lair the troll spawns two more times.
IF(PLAYER0,LAIR >= 1)
    ADD_TO_FLAG(PLAYER0,FLAG2,-2)
ENDIF
COMPUTE_FLAG

Modifies flag's value based on variables or other flags and values.

COMPUTE_FLAG([player],[flag],[operation],[src_player],[src_var],[alt])

Where:

[player] - The player’s name, e.g. PLAYER1.

[flag] - The flag’s name to which you'll set the value.

[operation] - Can be SET, INCREASE, DECREASE, MULTIPLY. SET replaces original value, the other three modify it.

[src_player] - The arg/source player’s name, e.g. PLAYER1.

[src_var] - Source variable which will be set/added/etc to [flag]

[alt] - If set to 1, creature flags will be interpreted as in IF_CONTROLS and rooms/doors/traps as in IF_AVAILABLE. Set it to 0 and it takes the value as IF uses it.

Example:

REM PLAYER0 gets a skeleton for every bile demon he has
COMPUTE_FLAG(PLAYER0,FLAG1,SET,PLAYER0,BILE_DEMON,0)
IF(PLAYER0,FLAG1 > 1)
    NEXT_COMMAND_REUSABLE
    ADD_CREATURE_TO_LEVEL(PLAYER0,SKELETON,PLAYER0,1,1,0)
    NEXT_COMMAND_REUSABLE
    ADD_TO_FLAG(PLAYER0,FLAG1,-1)
ENDIF
RANDOMISE_FLAG

Gives a flag a true random value. Can be used to get truly random level scripts.

RANDOMISE_FLAG([player],[flag],[max value]*)

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[flag] - The flag’s name.

[max value]* - The flag will get a value ranging from 1 to this max value. If set to 0 or left empty, the current value will be used as the max value.

Example 1:

REM Spawn a party from a random hero gate every 5 minutes
SET_TIMER(PLAYER_GOOD,TIMER3)
IF(PLAYER_GOOD,TIMER3 >= 6000)
	NEXT_COMMAND_REUSABLE
	RANDOMISE_FLAG(PLAYER_GOOD,FLAG3,3)
	IF(PLAYER_GOOD,FLAG3 == 1)
		NEXT_COMMAND_REUSABLE
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,demo_party,-1,1)
		NEXT_COMMAND_REUSABLE
		SET_TIMER(PLAYER_GOOD,TIMER3)
	ENDIF
	IF(PLAYER_GOOD,FLAG3 == 2)
		NEXT_COMMAND_REUSABLE
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,demo_party,-2,1)
		NEXT_COMMAND_REUSABLE
		SET_TIMER(PLAYER_GOOD,TIMER3)
	ENDIF
	IF(PLAYER_GOOD,FLAG3 == 3)
		NEXT_COMMAND_REUSABLE
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,demo_party,-3,1)
		NEXT_COMMAND_REUSABLE
		SET_TIMER(PLAYER_GOOD,TIMER3)
	ENDIF
ENDIF

Example 2:

REM Kill a random amount of the players dragons, but keep at least 2 alive.
SET_FLAG(PLAYER0,FLAG2,2)
COMPUTE_FLAG(PLAYER0,FLAG3,SET,PLAYER0,DRAGON)
RANDOMISE_FLAG(PLAYER0,FLAG3)
COMPUTE_FLAG(PLAYER0,FLAG3,DECREASE,PLAYER0,FLAG2)
IF(PLAYER0,FLAG3 > 1)
	NEXT_COMMAND_REUSABLE
	KILL_CREATURE(PLAYER0,DRAGON,ANYWHERE,1)
	NEXT_COMMAND_REUSABLE
	ADD_TO_FLAG(PLAYER0,FLAG3,-1)
ENDIF
COUNT_CREATURES_AT_ACTION_POINT

Saves the number of creatures of a specific player to a flag. Best used in a loop to keep track and trigger a condition when a certain min or max amount is reached.

COUNT_CREATURES_AT_ACTION_POINT([action_point],[player],[creature],[player],[flag])

Where:

[action_point] - Action point number.

[player] - The player’s name, e.g. PLAYER1, who owns the creature.

[creature] - The creature name, e.g. BILE_DEMON. Includes ANY_CREATURE.

[player],[flag] - The flag’s name to which you'll add the value, e.g. FLAG1, CAMPAIGN_FLAG2, BOX0_ACTIVATED

EXPORT_VARIABLE

Exports a variable to a campaign flag to use in a future campaign level. To be used together with the IMPORT command.

EXPORT_VARIABLE([player],[variable],[flag])

Where:

[player] - The player’s name, e.g. PLAYER1. Linked to both the variable and campaign flag.

[variable] - The variable that is to be exported, e.g. BATTLES_WON

[flag] - The flag’s name to which you'll export the variable. Must be a campaign flag, e.g. CAMPAIGN_FLAG1.

Example:

REM Save annoyed creatures of player1 to player1,campaign_flag1 for next level.
NEXT_COMMAND_REUSABLE
EXPORT_VARIABLE(PLAYER1,CREATURES_ANNOYED,CAMPAIGN_FLAG1)

REM Bring over how much gold player 2 has for next level
IF(PLAYER0,ALL_DUNGEONS_DESTROYED == 1)
	EXPORT_VARIABLE(PLAYER2,MONEY,CAMPAIGN_FLAG7)
	WIN_GAME
ENDIF
IMPORT

Like DRAWFROM, it is not a command itself but may replace a parameter of most other commands. At the start of the level it is replaced by the value of the specified campaign flag.

IMPORT([player],[flag])

Where:

[player] - The player’s name, e.g. PLAYER0.

[flag] - The flag’s name to which you'll export the variable. Must be a campaign flag, e.g. CAMPAIGN_FLAG1.

Example:

REM Give player 2 the gold he ended with on the previous level
ADD_GOLD_TO_PLAYER(PLAYER2,IMPORT(PLAYER2,CAMPAIGN_FLAG7))

REM Player0 gets no more creatures as he managed to annoy from player1 last level.
MAX_CREATURES(PLAYER0,IMPORT(PLAYER1,CAMPAIGN_FLAG1))
SET_TIMER

Sets up a timer that increases by 1 every game turn from when it was triggered.

SET_TIMER([player],[timer])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[timer] - The timer’s name. Each player has their own set of eight timers (TIMER0 to TIMER7) you can trigger.

Example:

REM Setup Player 0's TIMER0
SET_TIMER(PLAYER0,TIMER0)

REM When TIMER0 reaches 1000, win the game
IF(PLAYER0,TIMER0 >= 1000)
  WIN_GAME
ENDIF
ADD_TO_TIMER

Add or remove turns to the Script timer. Allows negative values.

ADD_TO_TIMER([player],[timer],[turns])
DISPLAY_TIMER

Displays a script timer on screen.

DISPLAY_TIMER([player], [timer], [clocktime]*)

Where:

[player] - The player’s name, e.g. PLAYER1.

[timer] - The timer’s name. Each player has their own set of eight timers you can trigger

[clocktime]* - Set to 1 to display the countdown in hours/minutes/seconds. Set to 0 or don't add the param to display turns.

HIDE_TIMER

Hides the timer that has been made visible with DISPLAY_TIMER

HIDE_TIMER 
BONUS_LEVEL_TIME

Sets time to be displayed on "bonus timer" - on-screen time field, used mostly for bonus levels. But now this command can be used to show bonus timer in any level, and may show clocktime instead of turns. Setting game turns to 0 will hide the timer.

BONUS_LEVEL_TIME([turns],[clocktime]*)

Where:

[turns] - The amount of game turns the timer will count down from. That's 20 per second.

[clocktime]* - Set to 1 to display the countdown in hours/minutes/seconds. Set to 0 or don't add the param to display turns.

Example:

BONUS_LEVEL_TIME(12000)
ADD_BONUS_TIME

Add or remove turns to the Bonus Level timer. Allows negative values.

ADD_BONUS_TIME([turns])

Adding New Creatures and Parties to the Level

ADD_CREATURE_TO_LEVEL

This command will add a number of new creatures to the level at the co-ordinates of a specifies Action Point. You cannot set where the creatures head for so you may need to use a party instead.

ADD_CREATURE_TO_LEVEL([player],[creature],[action point],[a],[experience],[gold])

Where:

[player] - The name of the player, e.g. PLAYER1, that the creatures belong to. See Players section for more information.

[creature] - The creature’s name, e.g. DRAGON. See Creatures section for more information.

[action point] - The number of the Action Point where the creatures will appear. Positive integer value. See Action points section for more information. If you want a creature to appear at a Hero Gate, you will need to enter the Hero Gate’s number here. The number must have a minus sign in front of it to distinguish it from the normal Action Points. For example, if you want the creature to appear at Hero Gate 4, the [action point] number will be -4. If you want a creature to appear at player's Dungeon Heart, you need to enter the player's name instead of the number (see Players section).

[a] - The number of creatures that will appear at the Action Point. This can be any number but remember that you can only have up to 255 creatures on the map at any one time so this number should not be too high.

[experience] - The experience level of the creatures.

[gold] - The amount of gold carried by the creatures.

Example:

REM Add 7 level 4 Hero Wizards who are carrying 400 gold at Action Point 3
ADD_CREATURE_TO_LEVEL(PLAYER_GOOD,WIZARD,3,7,4,400)
ADD_TUNNELLER_TO_LEVEL

This commands adds a number of Tunneller Dwarves to the level. They will immediately start digging towards their target. Tunneller Dwarves are the only creatures that can tunnel towards a target.

ADD_TUNNELLER_TO_LEVEL([player],[action point],[head for],[action point/target player],[experience],[gold])

Where:

[player] - The name of the player, e.g. PLAYER_GOOD, that the creatures belong to. See Players section for more information.

[action point] - The number of the Action Point where the Tunneller will appear. Positive integer value. See Action points section for more information. If you want the Tunneller to appear at a Hero Gate, you will need to enter the Hero Gate’s number here. The number must have a minus sign in front of it to distinguish it from the normal Action Points. For example, if you want the Tunneller to appear at Hero Gate 4, the [action point] number will be -4. If you want the Tunneller to appear at player's Dungeon Heart, you need to enter the player's name instead of the number (see Players section).

[head for] - This command tells the Tunneller what it is tunnelling to. You will specify the exact Action Point or Player number in the next command. There are a number of commands you can use:

Description Command
An Action Point ACTION_POINT
A Player’s dungeon DUNGEON
A Player’s Dungeon Heart DUNGEON_HEART
The dungeon of the player with the highest score APPROPIATE_DUNGEON

[action point/target player] - This command will tell the Tunneller which Action Point (if the [head for] command was ACTION_POINT) or Player (if the [head for] command was DUNGEON or DUNGEON_HEART) to go to. If the command was APPROPIATE_DUNGEON then this will just be 0 as the APPROPIATE_DUNGEON command sends the Tunneller to the dungeon of the player with the highest score. If you wish to put player here, you must type player number, like 1, not player name. If you will type PLAYER1, the game won't be able to recognize the number and will treat it as 0.

[experience] - The experience level of the Tunneller.

[gold] - The amount of gold carried by the Tunneller.

Example:

REM Add a level 6 Hero Tunneller at Action Point 7. He will tunnel towards Action Point 5
ADD_TUNNELLER_TO_LEVEL(PLAYER_GOOD,7,ACTION_POINT,5,6,400)

REM Add a level 4 Hero Tunneller at Action Point 3. He will tunnel towards Player 2's Dungeon Heart
ADD_TUNNELLER_TO_LEVEL(PLAYER_GOOD,3,DUNGEON_HEART,2,4,400)

REM *** Add a level 9 Hero Tunneller at Action Point 5. He will tunnel towards
REM *** the dungeon of the player with the highest score
ADD_TUNNELLER_TO_LEVEL(PLAYER_GOOD,5,APPROPIATE_DUNGEON,0,9,400)
CREATE_PARTY

This command tells the game to expect a party with a specific name.

CREATE_PARTY([party name])

Where:

[party name] - The name of the party. You can use any name you want but it must be in capitals.

Example:

CREATE_PARTY(FIRST_STRIKE)
ADD_TO_PARTY

This command adds a unit to a party. The party leader - the unit with the highest level, or most power when equal - is the one which will follow an objective, the others will follow the leader. There is a maximum of 30 party members.

ADD_TO_PARTY([party name],[creature],[experience],[gold],[objective],[countdown])

Where:

[party name] - The name of the party. This must have been declared with the CREATE_PARTY command.

[creature] - The creature’s name, e.g. HORNY. See Creatures section for more information.

[experience] - The creature’s experience level.

[gold] - The amount of gold the creatures are carrying.

[objective] - The target of the creatures and where they will make for when they enter the level. You will not need to specify the target player yet. This will be done when you place the party on the map.

These are the possible objectives:

objective description
ATTACK_DUNGEON_HEART Attack the nearest Dungeon Heart.
ATTACK_ENEMIES Attack any enemies.
ATTACK_ROOMS Attack the nearest rooms.
DEFEND_HEART Go to own heart and defend it until destroyed.
DEFEND_LOCATION Never do any objective.
DEFEND_PARTY Will not do any objective so will not assume party leadership.
DEFEND_ROOMS Defend nearest owned room, not counting portals, hearts or bridges.
SABOTAGE_ROOMS Attacks the nearest rooms. Will avoid combat if it can.
SNIPE_DUNGEON_HEART Attack the nearest Dungeon Heart, and will totally ignore anything else.
STEAL_GOLD Steal gold from the Treasure Room (amount depends on GoldHold parameter of the creature). Will avoid combat if it can.
STEAL_SPELLS Go to Library and steal one spell book. Will avoid combat if it can.

[countdown] - Number of game turns before the leader of the party start moving to the objective. Even if this is set to zero, there usually is a little delay (approx. 200 game turns) before the leader starts moving.

Note: In the original game this command could not be used inside an IF-statement, now it can.

Note 2: Parties used to be limited to 8 members, and while this limit is raised, it is generally a good idea to not go much beyond this amount.

DELETE_FROM_PARTY

Removes a unit from a defined party. Use it before the party is added to the level. When two equal units are in the party, the one that was first added will be deleted.

DELETE_FROM_PARTY([party_name], [creature], [level])

where:

[party_name] - The name as defined with the CREATE_PARTY command

[creature] - Creature model to be searched.

[level] - The experience level of the unit that is to be removed.

ADD_TUNNELLER_PARTY_TO_LEVEL

This adds a specified party of creatures to the level with a Tunneller Dwarf as it’s leader. The Tunneller will immediately dig to it’s target and the other creatures will follow.

ADD_TUNNELLER_PARTY_TO_LEVEL([player],[party name],[action point],[head for],[action point/target player],[experience],[gold])

Where:

[player] - The name of the player, e.g. PLAYER_GOOD, that the creatures belong to. See Players section for more information.

[party name] - The name of the party. This must have been declared with the CREATE_PARTY command.

[action point] - The number of the Action Point where the party will appear. Positive integer value. See Action points section for more information. If you want the party to appear at a Hero Gate, you will need to enter the Hero Gate’s number here. The number must have a minus sign in front of it to distinguish it from the normal Action Points. For example, if you want the party to appear at Hero Gate 4, the [action point] number will be -4. If you want the party to appear at player's Dungeon Heart, you need to enter the player's name instead of the number (see Players section).

[head for] - This command tells the Tunneller what it is tunnelling to. You will specify the exact Action Point or Player number in the next command. There are a number of commands you can use:

Description Command
An Action Point ACTION_POINT
A Player’s dungeon DUNGEON
A Player’s Dungeon Heart DUNGEON_HEART
The dungeon of the player with the highest score APPROPIATE_DUNGEON

[action point/target player] - This command will tell the Tunneller which Action Point (if the [head for] command was ACTION_POINT) or Player (if the [head for] command was DUNGEON or DUNGEON_HEART) to go to. If the command was APPROPIATE_DUNGEON then this will just be 0 as the APPROPIATE_DUNGEON command sends the Tunneller to the dungeon of the player with the highest score. If you wish to put player here, you must type player number, like 1, not player name. If you will type PLAYER1, the game won't be able to recognize the number and will treat it as 0.

[experience] - The experience level of the Tunneller.

[gold] - The amount of gold the Tunneller is carrying.

Example:

REM *** Add MY_PARTY to the level at Action Point 4 with a level 5 Tunneller as it's leader.
REM *** The party will head for Action Point 1
ADD_TUNNELLER_PARTY_TO_LEVEL(PLAYER_GOOD,MY_PARTY,4,ACTION_POINT,1,5,600)

REM *** Add MY_PARTY to the level at Action Point 10 with a level 4 Tunneller as it's leader.
REM *** The party will head for the dungeon of Player 1
ADD_TUNNELLER_PARTY_TO_LEVEL(PLAYER_GOOD,MY_PARTY,10,DUNGEON,1,4,600)
ADD_PARTY_TO_LEVEL

Very similar to the ADD_TUNNELLER_PARTY_TO_LEVEL command, this adds a party to the level but does not include a Tunneller Dwarf. This means the party will not be able to tunnel to their target.

ADD_PARTY_TO_LEVEL([player],[name],[action point],[a])

Where:

[player] - The name of the player, e.g. PLAYER1, that the creatures belong to. See Players section for more information.

[name] - The name of the party. This must have been declared with the CREATE_PARTY command.

[action point] - The number of the Action Point where the party will appear. Positive integer value. See Action points section for more information. If you want the party to appear at a Hero Gate, you will need to enter the Hero Gate’s number here. The number must have a minus sign in front of it to distinguish it from the normal Action Points. For example, if you want the party to appear at Hero Gate 4, the [action point] number will be -4. If you want the party to appear at player's Dungeon Heart, you need to enter the player's name instead of the number (see Players section).

[a] - The number of copies of the party to be placed down at the Action Point.

Example:

REM Add 2 copies of MY_PARTY to the level at Action Point 5. They belong to Player 3
ADD_PARTY_TO_LEVEL(PLAYER3,MY_PARTY,5,2)

Displaying information and affecting interface

DISPLAY_OBJECTIVE

Displays one of the text messages from language-specific strings banks in an Objective Box. Each Objective Box replaces previous one, and cannot be removed from the messages list. It removes itself only after level is won or lost.

DISPLAY_OBJECTIVE([a],[location])

Where:

[a] - The number of the message, assigned to it in .po or .pot translation file.

[location] - Location where the view should be centered if the player clicks on the "zoom to" icon on the Message Panel.

DISPLAY_OBJECTIVE_WITH_POS

Displays one of the text messages from language-specific strings banks in an Objective Box. Each Objective Box replaces previous one, and cannot be removed from the messages list. It removes itself only after level is won or lost.

DISPLAY_OBJECTIVE_WITH_POS([a],[x],[y])

Where:

[a] - The number of the message, assigned to it in .po or .pot translation file.

[x,y] - Coordinates of the map area to view when eye icon is clicked. In subtiles (range is 1..254 on default sized map).

DISPLAY_INFORMATION

Displays one of the text messages from language-specific strings banks in an Information Box. Each Information Box stacks over previous messages, and can be removed by right clicking. It disappears automatically some time after has been read.

DISPLAY_INFORMATION([a],[location])

Where:

[a] - The number of the message, assigned to it in .po or .pot translation file.

[location] - Location where the view should be centered if the player clicks on the "zoom to" icon on the Message Panel.

DISPLAY_INFORMATION_WITH_POS

Displays one of the text messages from language-specific strings banks in an Information Box. Each Information Box stacks over previous messages, and can be removed by right clicking. It disappears automatically some time after has been read.

DISPLAY_INFORMATION_WITH_POS([a],[x],[y])

Where:

[a] - The number of the message, assigned to it in .po or .pot translation file.

[x,y] - Coordinates of the map area to view when eye icon is clicked. In subtiles (range is 1..254 on default sized map).

QUICK_OBJECTIVE

Works like DISPLAY_OBJECTIVE, but instead of using a string from translations, allows to type it directly.

QUICK_OBJECTIVE([a],["message"],[location])

Parameters have the same meaning as in QUICK_INFORMATION command.

QUICK_OBJECTIVE_WITH_POS

Works like DISPLAY_OBJECTIVE_WITH_POS, but instead of using a string from translations, allows to type it directly.

QUICK_OBJECTIVE_WITH_POS([a],["message"],[x],[y])

Parameters have the same meaning as in QUICK_INFORMATION command.

QUICK_INFORMATION

Works like DISPLAY_INFORMATION, but instead of using a string from translations, allows to type it directly.

QUICK_INFORMATION([a],["message"],[location])

Where:

[a] - Message slot selection. There are 256 quick message slots, and each message you're making should use a different one. Using one message slot twice will lead to the first message being lost.

["message"] - The message string to be shown in a box. Message length may be up to 1024 characters.

[location] - Location where the view should be centered if the player clicks on the "zoom to" icon on the Message Panel.

QUICK_INFORMATION_WITH_POS

Works like QUICK_INFORMATION, but accepts [x,y] coordinates as the position.

QUICK_INFORMATION_WITH_POS([a],["message"],[x],[y])

Where:

[a] - Message slot selection. There are 50 quick message slots, and each message you're making should use a different one. Using one message slot twice will lead to the first message being lost.

["message"] - The message string to be shown in a box. Message length may be up to 1024 characters.

[x,y] - Coordinates of the map area to view when eye icon is clicked. In subtiles (range is 1..254 on default sized map).

DISPLAY_MESSAGE

Displays one of the text messages from language-specific strings banks as a chat message, with a specific unit or player shown as the sender. It disappears automatically after some time.

DISPLAY_MESSAGE([a], [icon])

Where:

[a] - The number of the message, assigned to it in .po or .pot translation file.

[icon] - The name of the player, creature, creature spell, Keeper power, creature instance, room, or query icon that is shown as the sender of the message. Accepts None for no icon.

QUICK_MESSAGE

Works like DISPLAY_MESSAGE, but instead of using a string from translations, allows to type it directly.

QUICK_MESSAGE([a], "[message]", [icon])

Where:

[a] - Message slot selection. There are 50 quick message slots, and each message you're making should use a different one. Using one message slot twice will lead to the first message being lost.

[message] - The message string to be shown in a box. Message length may be up to 1024 characters.

[icon] - The name of the player, creature, creature spell, Keeper power, creature instance, room, or query icon that is shown as the sender of the message. Accepts 'None' for no icon.

HEART_LOST_OBJECTIVE

Displays an Objective message when the player lost his Dungeon Heart. Works like DISPLAY_OBJECTIVE.

HEART_LOST_OBJECTIVE([a],[location])
HEART_LOST_QUICK_OBJECTIVE

Displays an Objective message when the player lost his Dungeon Heart. Works like QUICK_OBJECTIVE.

HEART_LOST_QUICK_OBJECTIVE([a],["message"],[location])
PLAY_MESSAGE

Plays a sound message or sound effect.

PLAY_MESSAGE([player],[type],[sound])

Where:

[player] - The name of the player who gets to hear the sound.

[type] - If it is a sound effect or a speech. Accepts values SPEECH and SOUND. Speeches queue, sounds play at the same time.

[sound] - The sound file to be played. Use numbers(ID's) to play sounds from the original .dat files, or a file name(between parenthesis) to play custom sounds.

Example:

PLAY_MESSAGE(PLAYER0,SPEECH,107)

Example 2:

IF_ACTION_POINT(1,PLAYER0)
	PLAY_MESSAGE(PLAYER0,SPEECH,"you_have_discovered_ruins.mp3")
	PLAY_MESSAGE(PLAYER0,SOUND,"twinkle.wav")
	PLAY_MESSAGE(PLAYER0,SOUND,"wizzing.wav")
ENDIF

When using ID's to playSOUND or SPEECH from the game, or custom sound files, the sounds come from the sound.dat file. Speeches come from the speech_***.dat files, depending on the configured language. Transcripts of the speech-messages can be found here. To hear which sounds are available use the DKSound utility from the DKtools pack.

Bundle custom sounds with the mappack or campaign to have them played. Files need to be placed in the MEDIA_LOCATION as configured in the mappack or campaign configuration file. MP3, Ogg, VOC, FLAC and WAV formats are supported. Be sure to be case sensitive (if you use capitals in the file name, use them in the script) so linux users can also play your map.

TUTORIAL_FLASH_BUTTON

Flashes a button on the toolar until the player selects it.

TUTORIAL_FLASH_BUTTON([button],[duration])

Where:

[button] - The number of the button. Each button of the interface has corresponding unique number. More information on this page.

[duration] - In game turns. Setting it to positive number controls how long the button is flashing. Setting it to 0 will flash the button until clicked, with no time limit.

Example:

ROOM_AVAILABLE(PLAYER0,WORKSHOP,1,1)
QUICK_INFORMATION(1,"Build a 3x3 workshop which is now available to you.")
TUTORIAL_FLASH_BUTTON(13,PLAYER0)
DISPLAY_COUNTDOWN

Displays on screen how long a specific script timer reaches the target turn.

DISPLAY_COUNTDOWN([player], [timer], [target], [clocktime]*)

Where:

[player] - The player’s name, e.g. PLAYER1.

[timer] - The timer’s name. Each player has their own set of eight timers to choose from.

[target] - Show the difference between the current timer value, and the target timer value.

[clocktime] - Set to 1 to display the countdown in hours/minutes/seconds. Set to 0 or don't add the param to display turns.

DISPLAY_VARIABLE

Displays a script variable on screen.

DISPLAY_VARIABLE([player], [variable], [target]*, [target_type]*)

Where:

[player] - The player’s name, e.g. PLAYER1.

[variable] - The variable that is to be exported, e.g. SKELETONS_RAISED. See Variables section for more information.

[target]* - If set, it would show the difference between the current amount, and the target amount.

[target_type]* - Can be set to 0, 1 or 2. Set to 0 it displays how much more you need to reach the target, 1 displays how many you need to lose to reach the target, 2 is like 0 but shows negative values too.

HIDE_VARIABLE

Hides the variable that has been made visible with DISPLAY_VARIABLE

HIDE_VARIABLE

Manipulating Map

REVEAL_MAP_LOCATION

Reveals square area of subtiles around given location, or the entire open space around it.

REVEAL_MAP_LOCATION([player],[location],[range])

Location meaning is identical to the one in DISPLAY_OBJECTIVE. Set the [range] to -1 will explore the entire open area from the location, as if your heart stood at that location start of level.

For example, to reveal Hero Gate no.1:

REVEAL_MAP_LOCATION(PLAYER0,-1,11)
REVEAL_MAP_RECT

Reveals rectangular map area for given player.

REVEAL_MAP_RECT([player],[x],[y],[width],[height])

Where:

[player] - The player’s name, e.g. PLAYER1.

[x,y] - Coordinates of area center point. In subtiles (range is 1..254 on a normal sized map).

[width] - The width of the area in subtiles

[height] - The height of the area in subtiles

CONCEAL_MAP_RECT

Conceals part of the map with fog of war, opposite to REVEAL_MAP_RECT

CONCEAL_MAP_RECT([Player], [x], [y], [Width], [Height], [hide revealed]*)

Where:

[player] - The player’s name, e.g. PLAYER1.

[x,y] - Coordinates of area center point. In subtiles (range is 1..254 on a normal sized map).

[width] - The width of the area in subtiles

[height] - The height of the area in subtiles

[hide revealed]* is optional, but set to 1 or ALL also hides rocks, gems and gold. On 0 it conceals slabs that are concealed at map start.

CHANGE_SLAB_OWNER

Changes the owner of a slab on the map to specified player. If it's part of a room, the entire room changes owner. Will change PATH to PRETTY_PATH.

CHANGE_SLAB_OWNER([slab x pos],[slab y pos],[player],[fill]*)

Where:

[slab x pos][slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

[player] - The player’s name, e.g. PLAYER1, of the new owner of the slab/room

[fill]* - Optional value, which can be set to:

  • NONE - The default, no matching of slabs, but will take entire room on ownership
  • MATCH - Replace only slabs of same type
  • FLOOR - Replace all slabs of the same type, and all adjacent attached floor slabs
  • BRIDGE - Like Floor, but include bridges and floor attached by the bridges

Example:

REM If the player has stolen his allies room, just give it back.
IF_SLAB_OWNER(30,65,PLAYER0)
	NEXT_COMMAND_REUSABLE
	CHANGE_SLAB_OWNER(30,65,PLAYER1)
ENDIF
CHANGE_SLAB_TYPE

Changes a slab on the map to the specified new one. It will not change an entire room, just a single slab.

CHANGE_SLAB_TYPE([slab x pos],[slab y pos],[slab],[fill]*)

Where:

[slab x pos],[slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

[slab] - The name of the new slab. Take if from fxdata\terrain.cfg.

[fill]* - Optional value, same as on CHANGE_SLAB_OWNER

Example:

REM Break open the unbreakable wall when the player reaches the first objective.
IF_ACTION_POINT(1,PLAYER0)
	CHANGE_SLAB_TYPE(13,44,PRETTY_PATH)
ENDIF
CHANGE_SLAB_TEXTURE

Changes the texture (style) of a slab on the map to the specified one.

CHANGE_SLAB_TEXTURE([slab x pos],[slab y pos],[texture],[fill]*)

Where:

[slab x pos][slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

[texture] - The name or number of the texture to set. See a map editor for possible textures.

[fill]* - Optional value, which can be set to:

  • NONE - The default, no matching of slabs
  • MATCH - Replace only slabs of same type
  • FLOOR - Replace all slabs of the same type, and all adjacent attached floor slabs
  • BRIDGE - Like Floor, but include bridges and floor attached by the bridges

Example:

REM Change all the low slabs in this area to snow
IF(PLAYER0,GAME_TURN > 5000)
	NEXT_COMMAND_REUSABLE
	CHANGE_SLAB_TEXTURE(30,65,WINTER,FLOOR)
ENDIF
SET_TEXTURE

Changes the slabs belonging to a specific player to a custom texture

SET_TEXTURE([player],[texture])

Where:

[player] - The name of the player who's slabs are changed.

[texture] - The name or number of the texture to use for the player, like 'STONE_FACE'. Accepts 'None' or '-1'.

SET_DOOR

Allows you to lock or unlock a door on a particular slab

SET_DOOR([lock state],[slab x pos],[slab y pos])

Where:

[lock state] - Either LOCKED or UNLOCKED

[slab x pos], [slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

SET_HEART_HEALTH

Set the Dungeon Heart health to a specific value for a player. Must be below the max health of the player.

SET_HEART_HEALTH([player],[health])
ADD_HEART_HEALTH

Restores or drains health from a players Dungeon Heart. Can't exceed the standard max health value.

ADD_HEART_HEALTH([player],[health],[warning])

Where:

[player] - The player’s name, e.g. PLAYER1.

[health] - The hitpoints to restore. Use negative values to take away health. Full heart is 30000 hitpoints.

[warning] - Set to 1 to give a 'heart is under attack' warning when removing hitpoints. Keep it at 0 to do not. You want 0 when you use it against computer players.

HIDE_HERO_GATE

Hides a specific hero gate, so that it can't be seen or heard by the player or by the heroes themselves.

HIDE_HERO_GATE([gate number],[hidden])

Where:

[gate number] - The number of the hero gate to be hidden. Can be positive or negative.

[hidden] - Set to 1 to hide it, and set to 0 to make it visible again.

ADD_OBJECT_TO_LEVEL

Place any object at a specific place on the map.

ADD_OBJECT_TO_LEVEL([object],[location],[property],[player]*)

Where:

[object] - The object name from fxdata\objects.cfg

[location] - The location you want the object to spawn.

[property] - If the objects has properties, set it. For Gold, it's the amount. If you use SPECBOX_CUSTOM to place the mystery box, it's the box number in the BOX#_ACTIVATED variable.

[player]* - When used it sets the owner of the object. Leave empty or set to PLAYER_NEUTRAL to get unowned object.

ADD_OBJECT_TO_LEVEL_AT_POS

Place any object at a subtile.

ADD_OBJECT_TO_LEVEL_AT_POS([object],[x],[y],[property],[player]*)

Where:

[object] - The object name from fxdata\objects.cfg

[x,y] - Coordinates of area center point. In subtiles (range is 1..254 on a normal sized map).

[property] - If the objects has properties, set it. For Gold, it's the amount. If you use SPECBOX_CUSTOM to place the mystery box, it's the box number in the BOX#_ACTIVATED variable.

[player]* - When used it sets the owner of the object. Leave empty or set to PLAYER_NEUTRAL to get unowned object.

ADD_EFFECT_GENERATOR_TO_LEVEL

Place any Effect Generator at a specific place on the map.

ADD_EFFECT_GENERATOR_TO_LEVEL([effect generator],[location],[range])

Where:

[effect generator] - The effect generator name from effects.toml.

[location] - The location you want the generator to spawn.

[range] - The range within which the generator will spawn effects.

Note: It is possible and easy to create your own effect generators.

Manipulating Configs

SET_GAME_RULE

Allows you to make changes to door values set in rules.cfg. You can make them conditional with IF statements.

SET_GAME_RULE([rulename],[val1])

Where:

[rulename] - The name of the variable you want to change.

[val1] - The value you want to give it.

  • Almost all rules are configurable, except for those in [research] and [sacrifices] blocks.

  • To set PreserveClassicBugs, add up the numbers of the bugs you want to enable

number bug explanation
1 RESURRECT_FOREVER Dead creatures can be resurrected multiple times with specials.
2 OVERFLOW_8BIT Creatures stats when growing past 255 would go to 0 again.
4 CLAIM_ROOM_ALL_THINGS Claiming a room makes spells/crates on it unuseable.
8 RESURRECT_REMOVED Fainted creatures can be resurrected (copied) with a special.
16 NO_HAND_PURGE_ON_DEFEAT When you die you can hold on to creatures in your hand.
32 MUST_OBEY_KEEPS_NOT_DO_JOBS Creatures refuse jobs they dislike even with 'Must Obey' enabled.
64 BREAK_NEUTRAL_WALLS In possession you can dig through neutral walls.
128 ALWAYS_TUNNEL_TO_RED Heroes will always target the red keeper.
256 FULLY_HAPPY_WITH_GOLD Any creature will be fully happy with any gold given.
512 FAINTED_IMMUNE_TO_BOULDER Boulders are destroyed when hitting fainted creatures.
1024 REBIRTH_KEEPS_SPELLS Vampires keep the spells they learned after resurrection.
2048 STUN_FRIENDLY_UNITS Infighting with imprisonment on will not kill your creatures.
4096 PASSIVE_NEUTRALS Neutral creatures placed in prison or torture room wander out.
8192 NEUTRAL_TORTURE_CONVERTS Neutral torture rooms convert creatures into neutral creatures.
SET_HAND_RULE

Specifies advanced rules to limit picking up units.

SET_HAND_RULE([player],[creature],[rule_slot],[rule_action],[rule]*,[param]*)

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[creature] - The creature name, e.g. BILE_DEMON. See Creatures section for more information. Works with ANY_CREATURE.

[rule_slot] - Rule slot a rule will be assigned to. There are 8 available slots per player's creature type: RULE0, RULE1, ..., RULE7

[rule_action] - ALLOW or DENY. Whether creatures that match the rule should be allowed/denied from being picked up. If you just want to disable or re-enable rule already stored in a slot, use DISABLE or ENABLE and leave the last two params (rule, param) empty.

[rule]* - only specify if rule_action is ALLOW/DENY. One of the following:

  • ALWAYS - all creatures match this rule until it is disabled or overridden
  • AGE_LOWER/AGE_HIGHER - only creatures whose time in dungeon (age) is lower/higher than [param] match this rule
  • LEVEL_LOWER/LEVEL_HIGHER - only creatures of level lower/higher than [param] match this rule
  • AT_ACTION_POINT - only creatures within action point [param] radius match this rule
  • AFFECTED_BY - only creatures affected by the spell in [param] match this rule
  • WANDERING/WORKING/FIGHTING - only creatures with these jobs match this rule
  • DROPPED_TIME_LOWER/DROPPED_TIME_HIGHER - only creatures picked up and dropped less/more turns ago match this rule

[param]* - rule parameter. See [rule] for usage info. Leave blank if rule does not use any param.

Rule checks are evaluated from the highest rule index (RULE7) to lowest (RULE0) and lower rules are ignored once a match is found.

Example:

IF_ACTION_POINT(4,PLAYER0)
    QUICK_INFORMATION(6,"This is a battle to the death, destroy these units before you proceed",4)
    SET_HAND_RULE(PLAYER0,HORNY,RULE1,DENY,AT_ACTION_POINT,4)
    ADD_CREATURE_TO_LEVEL(PLAYER_GOOD,DWARFA,4,6,5,250)
    SET_FLAG(PLAYER_GOOD,FLAG6,1)
ENDIF
IF(PLAYER_GOOD,FLAG6 == 1)
    IF(PLAYER_GOOD,DWARFA == 0)
        QUICK_INFORMATION(7,"With the dwarves destroyed, pick up horny and prepare for the next battle",4)
        SET_HAND_RULE(PLAYER0,HORNY,RULE1,DISABLE)
    ENDIF
ENDIF
SET_DOOR_CONFIGURATION

Allows you to make changes to door values set in trapdoor.cfg. Look in that file for explanations on the numbers.

SET_DOOR_CONFIGURATION([doorname],[property],[value],[second value]*)

Where:

[doorname] - The name of the door as defined in trapdoor.cfg

[property] - The name of the door property you want to change, as found in trapdoor.cfg. E.g. ManufactureRequired.

[value] - The new value you want to set it to. If you want to set the 'Crate' property, you can use both the number or the name from objects.cfg. If you want to set the value of the property named 'Properties', use a number you get by adding up these values:

number property
1 RESIST_NON_MAGIC
2 SECRET
4 THICK
8 MIDAS

[second value]* - The SymbolSprites property has 2 values to set. For other properties, do not add this parameter.

Use it to tweak doors on a per map basis. Example:

REM On this level, magic and iron doors do not give much value after several have been sold or destroyed.
IF(PLAYER0,DOORS_DESTROYED > 5)
    SET_DOOR_CONFIGURATION(MAGIC,SellingValue,150)
    SET_DOOR_CONFIGURATION(IRON,SellingValue,100)
ENDIF
NEW_OBJECT_TYPE

Adds a new object type to the list of possible objects. One that is not yet in objects.cfg.

NEW_OBJECT_TYPE([name])

Where:

[name] - The name you will define for the object. Used to reference it from now on.

Use the 'SET_OBJECT_CONFIGURATION' script command to then configure everything about the object, and 'ADD_OBJECT_TO_LEVEL' to place it. The script command is processed before other ones, and as such cannot be used inside IF-statements.

Example:

NEW_OBJECT_TYPE(MY_NEW_CRATE)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,Genre,WORKSHOPBOX)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,AnimationID,114)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,AnimationSpeed,256)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,MaximumSize,300)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,DestroyOnLava,1)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,MapIcon,531)
SET_OBJECT_CONFIGURATION(MY_NEW_CRATE,Properties,CHOWNED_ON_ROOM_CLAIM)
SET_OBJECT_CONFIGURATION

Allows you to make changes to object values set in objects.cfg.

SET_OBJECT_CONFIGURATION([objectname],[property],[value],[second value]*)

Where:

[objectname] - The name of the object as defined in objects.cfg .

[property] - The name of the object property you want to change, as found in objects.cfg. E.g. DestroyOnLava.

[value] - The new value you want to set it to. If you want to set the value of the property named 'Properties', use a number you get by adding up these values:

number property
1 EXISTS_ONLY_IN_ROOM
2 DESTROYED_ON_ROOM_CLAIM
4 CHOWNED_ON_ROOM_CLAIM
8 DESTROYED_ON_ROOM_PLACE
16 BUOYANT
32 BEATING
64 HEART

[second value] - Some properties have 2 or more values to set. For other properties, do not add this parameter.

Use it to tweak objects on a per map basis. Example:

REM On this level gold pots look like gold bags and they can be found at the bottom of water
SET_OBJECT_CONFIGURATION(GOLD,AnimationID,933)
SET_OBJECT_CONFIGURATION(GOLD,DestroyOnLiquid,0)

Can be used to do advanced manipulations too. Example:

REM The red flag needs health when it becomes a dungeon hearth
SET_OBJECT_CONFIGURATION(GUARDFLAG_RED,Health,18000)

REM	Spawn a guard flag at action point 3 to be a backup heart
IF(PLAYER0,TIME_MAGE > 3)
	ADD_OBJECT_TO_LEVEL(GUARDFLAG_RED,1,0,PLAYER0)
	REM The red flag is now a dungeon heart, a beating heart with the update function and 18000 health
	SET_OBJECT_CONFIGURATION(GUARDFLAG_RED,Properties,96)
	SET_OBJECT_CONFIGURATION(GUARDFLAG_RED,UpdateFunction,UPDATE_DUNGEON_HEART)

	REM The soul container is just a regular object
	SET_OBJECT_CONFIGURATION(SOUL_CONTAINER,UpdateFunction,0)
	SET_OBJECT_CONFIGURATION(SOUL_CONTAINER,Health,0)
	SET_OBJECT_CONFIGURATION(SOUL_CONTAINER,Properties,4)
ENDIF

If you have custom sprites, you can use this command to set a custom sprite for an object. If it is rotatable, you could even set the direction. Use the custom sprite name and the wind direction for that.

Example:

SET_OBJECT_CONFIGURATION(STATUE5,AnimationID,BANNER:NORTHWEST)
NEW_TRAP_TYPE

Adds a new trap type to the list of possible traps. One that is not yet in trapdoor.cfg.

NEW_TRAP_TYPE([name])

Where:

[name] - The name you will define for the trap. Used to reference it from now on.

Use the 'SET_TRAP_CONFIGURATION' script command to then configure everything about the trap. It can then be made available to the player like all other traps. The script command is processed before other ones, and as such cannot be used inside IF-statements.

SET_TRAP_CONFIGURATION

Allows you to make changes to trap values set in trapdoor.cfg. Look in that file for explanations on the numbers.

SET_TRAP_CONFIGURATION([trapname],[property],[value],[second value]*,[third value]*,[fourth value]*)

Where:

[trapname] - The name of the trap as defined in trapdoor.cfg

[property] - The name of the trap property you want to change, as found in trapdoor.cfg. E.g. ManufactureLevel.

[value] - The new value you want to set it to. If you want to set the 'Crate' property, you can use both the number or the name from objects.cfg

[second value] - Some properties have 2 or more values to set. For other properties, do not add this parameter.

[third value] - Some properties have 3 or more values to set. For other properties, do not add this parameter.

[forth value] - The FlameAnimationOffset property has 4 values to set. For other properties, do not add this parameter.

Use it to tweak traps on a per map basis.

Example:

REM On this level, alarm traps are replaced by exploding barrels
SET_TRAP_CONFIGURATION(ALARM,Shots,1)
SET_TRAP_CONFIGURATION(ALARM,Model,931)
SET_TRAP_CONFIGURATION(ALARM,TriggerType,2)
SET_TRAP_CONFIGURATION(ALARM,ActivationType,5)
SET_TRAP_CONFIGURATION(ALARM,EffectType,2)
SET_TRAP_CONFIGURATION(ALARM,Hidden,0)

REM And gas traps will hurt you from a distance.
SET_TRAP_CONFIGURATION(POISON_GAS,Shots,5)
SET_TRAP_CONFIGURATION(POISON_GAS,TimeBetweenShots,200)
SET_TRAP_CONFIGURATION(POISON_GAS,TriggerType,3)
SET_TRAP_CONFIGURATION(POISON_GAS,ActivationType,5)
SET_TRAP_CONFIGURATION(POISON_GAS,EffectType,5)
NEW_CREATURE_TYPE

Adds a new creature type to the creature list, and loads the related config for it. So a creature that is not yet in creatures.cfg.

NEW_CREATURE_TYPE([name])

Where:

[name] - The name of the creature to add. Will load [name].cfg from the (campaign) creatures folder.

Mapmakers can bundle their map with a config and sprite that needs to be placed in the correct folder, but without any need to modify game files.

SET_CREATURE_CONFIGURATION

Allows you to make changes to attribute values set in the unit configuration files. E.g. Imp.cfg.

SET_CREATURE_CONFIGURATION([creature],[variable],[value],[second value]*)

Where:

[creature] - Creature model to be modified.

[attribute] - The name of the creature property you want to change, as found in the [attributes], [job], [attraction], [sound] or [sprites] blocks in the unit configs. E.g. SlapsToKill.

[value] - The new value you want to set it to. It accepts the values as used in the config files.

[second value]* - If there are two values to the attribute, use this value.

Use it to tweak creatures on a per map basis.

Example:

REM On this level, Bile Demons costs lots of gold and would like to sit back.
SET_CREATURE_CONFIGURATION(BILE_DEMON,Pay,200)
SET_CREATURE_CONFIGURATION(BILE_DEMON,AttackPreference,RANGED)
SET_EFFECT_GENERATOR_CONFIGURATION

Allows you to make changes to effect generator values set in effects.toml. Look in that file for the possible properties.

SET_EFFECT_GENERATOR_CONFIGURATION([generator][property][value][second value]*[third value]*)

Where:

[generator] - The name of the effect generator as defined in effects.toml.

[property] - The name of the trap property you want to change, as found in effects.toml. E.g. SpawnHeight.

[value] - The new value you want to set it to. If you want to set the 'EffectModel' property, negative numbers are effect elements, positive effects. It accepts names too.

[second value]* - Some properties have 2 or more values to set. For other properties, do not add this parameter.

[third value]* - Some properties have 3 values to set. For other properties, do not add this parameter.

Use it to effect generators on a per map basis, changed within IF-statements. Example:

REM A 4 second eruption happens in the lava lake where lava effect generators are placed.
IF(PLAYER0,TIMER3 > 400)
  SET_EFFECT_GENERATOR_CONFIGURATION(EFFECTGENERATOR_LAVA,EffectModel,EFFECT_BOULDER_BREAK_WATER)
ENDIF
IF(PLAYER0,TIMER3 > 480)
  SET_EFFECT_GENERATOR_CONFIGURATION(EFFECTGENERATOR_LAVA,EffectModel,EFFECTELEMENT_LAVA_FLAME_STATIONARY)
ENDIF
SET_POWER_CONFIGURATION

Makes changes to keeper powers, as originally set in magic.cfg.

SET_POWER_CONFIGURATION([power],[property],[value 1],[value 2/slot/toggle]*)

Where:

[power] - Power model to be modified.

[property] - The name of the power property you want to change, as found in magic.cfg. E.g. 'Castability'.

[value] - The new value you want to set it to. It accepts the values as used in the config files. For 'Properties' and 'Castability' put the value between "quotation marks" if you want to set multiple values at once.

[value 2/slot/toggle]*

  • If there are two values to the property, use this value.
  • For Power and Cost, there are 9 slots to edit. Enter a value between 1~9 here.
  • For Properties and Castability, leave this empty to set [value] as the only value, set to 0 to remove the value from the list of values, set to 1 to add it to the list of values.

Example:

REM Sight no longer shows the progress of the active power
SET_POWER_CONFIGURATION(POWER_SIGHT,Properties,HAS_PROGRESS,0)

REM IF the player has over 50 creatures he can blow them up with time bomb, no longer just imps.
IF(PLAYER0,TOTAL_CREATURES > 50
  SET_POWER_CONFIGURATION(POWER_TIME_BOMB,Castability,"ALL_GROUND OWNED_CRTRS BOUND_CRTRS NEEDS_DELAY")
ENDIF

REM It makes no sense fully charged disease is so expensive, make cheaper
SET_POWER_CONFIGURATION(POWER_DISEASE,Cost,8600,9)

Example 2:

REM Put time bomb on first power page, cave in not used so moved to second page
SET_POWER_CONFIGURATION(POWER_TIME_BOMB,PanelTabIndex,9) 
SET_POWER_CONFIGURATION(POWER_CAVE_IN,PanelTabIndex,18)
SWAP_CREATURE

Replaces a creature with custom creature. Allows you to replaces for example 'FLY', all preplaced ones and all that will spawn on the level, with a 'SWAMP_RAT', provided 'SWAMP_RAT' was added to 'SwapCreatures' in creature.cfg and a file called swamp_rat.cfg is placed in the creatures folder.

It cannot be used inside IF statements and will do the swap before the level is loaded.

SWAP_CREATURE([new_creature],[creature])

Multiple different new creature types can be added to the creature.cfg file, and any number of existing units can be swapped out, this guarantees there are never more than 32 different kinds on a map, but allows for many more over the course of a campaign. At this point, only sprites (how the creature looks) that are already in the game can be used when making a swap creature config.

Example:

REM Since there are no beetles on the map, swap in a super knight to be used as a landlord
SWAP_CREATURE(LORD,BUG)
SET_CREATURE_PROPERTY(KNIGHT,LORD,0)

REM Spawn the powered up knight as the lord of the land
IF_ACTION_POINT(1,PLAYER0)
	ADD_CREATURE_TO_LEVEL(PLAYER_GOOD,BUG,-1,1,10,0)
ENDIF
NEW_ROOM_TYPE

Adds a new room type to the list of possible rooms. One that is not yet in terrain.cfg.

NEW_ROOM_TYPE([name])

Where:

[name] - The name you will define for the room. Used to reference it from now on.

Use the SET_ROOM_CONFIGURATION script command to then configure everything about the room. It can then be made available to the player like all other rooms. The script command is processed before other ones, and as such cannot be used inside IF-statements.

SET_ROOM_CONFIGURATION

Allows you to make changes to room values set in terrain.cfg. Look in that file for explanations on the numbers.

SET_ROOM_CONFIGURATION([roomname],[property],[value],[second value]*,[third value]*)

Where:

[roomname] - The name of the room as defined in terrain.cfg

[property] - The name of the room property you want to change, as found in terrain.cfg. E.g. CreatureCreation.

[value] - The new value you want to set it to. If you want to set roles, you can use numbers instead of names too.

[second value]* - Some properties have 2 or more values to set. For other properties, do not add this parameter.

[third value]* - Some properties have 3 values to set. For other properties, do not add this parameter.

Use it to tweak rooms on a per map basis.

  • To set Properties with numbers, add up the numbers of the properties you want to enable.
number property description
1 HAS_NO_ENSIGN The room does not display a room flag with.
2 CANNOT_VANDALIZE The room slabs cannot be attacked by creatures.
4 BUILD_TILL_BROKE Computers will spend their last gold building this.
8 CANNOT_BE_SOLD The room slabs cannot be sold.
16 CANNOT_BE_CLAIMED The room cannot be claimed.
  • To set Roles with numbers, add up the numbers of the roles you want to enable.
number role description
0 ROOM_ROLE_NONE Can be used to disable others roles if set as first value.
1 ROOM_ROLE_KEEPER_STORAGE The room is a storage for keeper soul (dungeon heart).
2 ROOM_ROLE_LAIR_STORAGE The room is a storage for creature lair totems.
4 ROOM_ROLE_GOLD_STORAGE The room is a storage for gold.
8 ROOM_ROLE_FOOD_STORAGE The room is a storage for food for creatures.
16 ROOM_ROLE_CRATES_STORAGE The room is a storage for crates (trap and door boxes).
32 ROOM_ROLE_POWERS_STORAGE The room is a storage for keeper powers (spellbooks and specials).
64 ROOM_ROLE_PRISON The room is a prison, forcing friends and foes to stay within.
128 ROOM_ROLE_DEAD_STORAGE The room is a storage for dead bodies.
256 ROOM_ROLE_POOL_SPAWN The room is a spawn point for creatures coming into dungeon from creature pool.
512 ROOM_ROLE_CONDITIONAL_SPAWN The room is a spawn point for creatures with special spawn conditions programmed.
1024 ROOM_ROLE_SACRIFICE The room can be used to sacrifice creatures and gain rewards.
2048 ROOM_ROLE_PURIFY_SPELLS The room can be used to cancel negative spells affecting creatures.
4096 ROOM_ROLE_FOOD_SPAWN The room is a spawn place for food.
8192 ROOM_ROLE_CRATES_MANUFACTURE The room is a manufacture place for trap crates.
16384 ROOM_ROLE_RESEARCH The room is a research place for spellbooks and rooms.
32768 ROOM_ROLE_TORTURE The room is a torture chamber, allowing torture of friends and foes.
65536 ROOM_ROLE_HAPPY_PRAY The room makes its workers increase their happiness by praying.
131072 ROOM_ROLE_HEAL_SLEEP The room makes its workers to heal by sleeping.
262144 ROOM_ROLE_SCAVENGE The room makes its workers scavenge enemy creatures.
524288 ROOM_ROLE_TRAIN_EXP The room makes its workers increase their experience by training.
1048576 ROOM_ROLE_MAKE_GROUP The room makes its workers form a group of creatures.
2097152 ROOM_ROLE_GUARD The room makes its workers guard the room area for enemies.
4194304 ROOM_ROLE_POOL_LEAVE The room is a gate which allows a creature to leave the players dungeon back to pool.
8388608 ROOM_ROLE_PASS_WATER The room is a bridge for use over water.
16777216 ROOM_ROLE_PASS_LAVA The room is a bridge for use over lava.
SET_SACRIFICE_RECIPE

Creates or modifies a Temple recipe.

SET_SACRIFICE_RECIPE([command],[reward],[creature1],[creature2].....[creature5])

Where:

[command] - The possible commands as listed in the sacrifices section in rules.cfg. Additionally, CUSTOMREWARD and CUSTOMPUNISH may be used. These play the respective sounds, and may increase the flag as configured for the reward parameter.

[reward] - The Creature, Spell or Unique function that is triggered when the Sacrifice completes, as seen in rules.cfg. Use FLAG0-FLAG7 to indicate which flag is raised when a player completes the sacrifice.

[creature1] to [creature5] are creature names, like HORNY. Only the first one is mandatory.

Example:

SET_SACRIFICE_RECIPE(CUSTOMREWARD, FLAG3, WIZARD, MONK)
IF(PLAYER0,FLAG3 >= 1)
  QUICK_INFORMATION(2, "If you give the dark gods wizards and monks, we'll give you gold", ALL_PLAYERS)
  NEXT_COMMAND_REUSABLE
  ADD_GOLD_TO_PLAYER(PLAYER0,666)
  NEXT_COMMAND_REUSABLE
  SET_FLAG(PLAYER0,FLAG3,0)
ENDIF

REM Sacrifice 5 heroes for the avatar to attack from the temple
SET_SACRIFICE_RECIPE(MkGoodHero,AVATAR,KNIGHT,SAMURAI,WIZARD,GIANT,MONK)
REMOVE_SACRIFICE_RECIPE

Removes a Temple recipe.

REMOVE_SACRIFICE_RECIPE([creature1],[creature2].....[creature5])

Where [creature2] to [creature5] are only needed when they are used in the recipe.

Example:

IF(PLAYER0,REWARDED[BILE_DEMON] >= 2)
  QUICK_INFORMATION(1, "You have sacrificed enough spiders. No more.", LAST_EVENT)
  REMOVE_SACRIFICE_RECIPE(SPIDER, SPIDER, SPIDER)
ENDIF

IF(PLAYER0,SACRIFICED[IMP] >= 12)
  QUICK_INFORMATION(2, "The gods don't need any more imps.",ALL_PLAYERS)
  REMOVE_SACRIFICE_RECIPE(IMP)
  SET_SACRIFICE_RECIPE(NegUniqFunc,COSTLIER_IMPS,IMP)
ENDIF
SET_MUSIC

Chooses what music track to play

SET_MUSIC([track])

Where:

[track] - The music track to be played. Numbers 2~7 select from original tracks, or a file name(between parenthesis) to set custom music.

Example:

REM Play custom track when the heroes made it into the player dungeon
IF(PLAYER0,TIMES_BROKEN_INTO >= 1)
	SET_MUSIC("high_tension_sonata4.mp3")
	SET_TIMER(PLAYER0,TIMER1)
ENDIF
REM Set it back to track 3 after at least 15 seconds and all fights are over
IF(PLAYER0,TIMER1 > 300)
	IF(PLAYER0,ACTIVE_BATTLES == 0)
		SET_MUSIC(3)
	ENDIF
ENDIF

Bundle custom tracks with the mappack or campaign to have them played. Files need to be placed in the MEDIA_LOCATION as configured in the mappack or campaign configuration file. MP3, Ogg, VOC, FLAC and WAV formats are supported. Be sure to be case sensitive (if you use capitals in the file name, use them in the script) so linux users can also play your map.

Note that if the player does not have the -nocd command line option enabled to play music from disk instead of cd, it will not play custom music files.

Manipulating Creature stats

SET_CREATURE_INSTANCE

Allows you to change which instances creatures learn at which levels.

SET_CREATURE_INSTANCE([creature], [slot], [instance], [level gained])

Where:

[creature] - Creature model to be modified.

[slot] - The spell slot to configure. 1~10.

[instance] - The name of the ability, as listed in creature.cfg. Allows NULL.

[level gained] - The level where the unit acquires the ability.

Example:

REM Remove imps ability to teleport at level 10
SET_CREATURE_INSTANCE(IMP,10,NULL,0)
SET_CREATURE_MAX_LEVEL

This command sets the maximum experience level the creature can train to. You can use this to stop certain creatures from becoming too powerful.

SET_CREATURE_MAX_LEVEL([player],[creature],[max experience])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[creature] - The creature name, e.g. SKELETON.

[max experience] - The maximum experience level for that creature. The highest and default maximum experience level of any creature is 10, but setting it to 10 with this command has influence on the game - it prevents creatures from transforming when they reach level 10 and are still training.

Example:

REM Do not allow human player Hell Hounds to go higher than level 5
SET_CREATURE_MAX_LEVEL(PLAYER0,HELL_HOUND,5)
SET_CREATURE_PROPERTY
SET_CREATURE_PROPERTY([creature],[property],[enable])

Where:

[creature] - The creature name, e.g. BILE_DEMON.

[property] - The name of the creature property you want to set, e.g. NEVER_CHICKENS. See imp.cfg for options.

[enable] - Set this to 1 to enable the property, or 0 to disable to property.

Example:

REM Make sure ghosts don't like farts and imps cannot be brought to the graveyard
SET_CREATURE_PROPERTY(IMP,NO_CORPSE_ROTTING,1)
SET_CREATURE_PROPERTY(GHOST,IMMUNE_TO_GAS,0)
SET_CREATURE_TENDENCIES

Allows to set tendencies: IMPRISON and FLEE, for a player's creatures. Example:

SET_CREATURE_TENDENCIES(PLAYER2,FLEE,1)

Note that a player must have prison when IMPRISON command is triggered; otherwise, it won't make any change.

CREATURE_ENTRANCE_LEVEL

Sets the level at which units come from the portal.

CREATURE_ENTRANCE_LEVEL ([player],[level])

Manipulating individual Creatures

TRANSFER_CREATURE

Transfers specific creatures to the next realm.

TRANSFER_CREATURE([player],[creature],[criterion],[count]*)

Where:

[player] - The name of the player who owns the creature, e.g. PLAYER1.

[creature] - Creature model to be searched. Accepts 'ANY_CREATURE'.

[criterion] - Creature selection criterion.

[count] - Amount of creatures transferred.

Can transfer creatures for any player, including heroes. The player must be present on the next level, for units to spawn at the player heart. Heroes may also spawn at a hero gate if there is no hearth, it would use the hero gate with the lowest number.

KILL_CREATURE

Kills given amount of creatures based on given criterion.

KILL_CREATURE([player],[creature],[criterion],[count])

Where:

[player] - The player who owns creatures to be affected.

[creature] - Creature model to be searched.

[criterion] - Creature selection criterion.

[count] - Amount of creatures affected.

LEVEL_UP_CREATURE

Levels up given creature based on given criterion.

LEVEL_UP_CREATURE([player],[creature],[criterion],[levels])

Where:

[player] - The player who owns creatures to be affected.

[creature] - Creature model to be searched.

[criterion] - Creature selection criterion.

[levels] - Number of times the unit levels up. Allows negative values.

Example:

REM The Lord that remain inside hero dungeon will level up every 3 minutes
IF(PLAYER_GOOD,TIMER1 >= 3600)
	NEXT_COMMAND_REUSABLE
	LEVEL_UP_CREATURE(PLAYER_GOOD,KNIGHT,ON_FRIENDLY_GROUND,1)
	NEXT_COMMAND_REUSABLE
	SET_TIMER(PLAYER_GOOD,TIMER1)
ENDIF
MOVE_CREATURE

Moves given amount of creatures to location based on given criterion.

MOVE_CREATURE([player],[creature],[criterion],[count],[location],[effect]*)

Where:

[player] - The player’s name, e.g. PLAYER1, who owns the creature.

[creature] - The creature name, e.g. BILE_DEMON. Includes ANY_CREATURE.

[criterion] - Creature selection Criterion.

[count] - Amount of creatures affected.

[location] - The location you want the creature to be teleported to.

[effect]* - The effect to spawn. Can be any effect or effect element that is in game, like the hearts that appear when healing, or the red smoke when claiming a room. When set to 0 it shows no effect, left empty it takes a standard player color specific puff. Positive numbers are Effects, Negative numbers are Effect Elements. Also accepts the names as provided in effects.toml

CHANGE_CREATURE_OWNER

Changes the owner of given creature based on given criterion.

CHANGE_CREATURE_OWNER([player_from],[creature],[criterion],[player_to])

Where:

[player_from] - The player who owns creatures to be affected.

[creature] - Creature model to be searched.

[criterion] - Creature selection criterion.

[player_to] - The player who will receive the creature.

Example:

REM If the player has too many heroes in his army, the barbarians will escape when possible.
IF_CONTROLS(PLAYER0,GOOD_CREATURES >= 20)
	NEXT_COMMAND_REUSABLE
	CHANGE_CREATURE_OWNER(PLAYER0,BARBARIAN,ON_ENEMY_GROUND,PLAYER_GOOD)
ENDIF
CHANGE_CREATURES_ANNOYANCE

Can set, increase or decrease the happiness level of all your units.

CHANGE_CREATURES_ANNOYANCE([player],[creature],[operation],[annoyance])

Where:

[player] - The player’s name, e.g. PLAYER1.

[creature] - The creature name, e.g. BILE_DEMON. Includes ANY_CREATURE.

[operation] - Can be SET, INCREASE, DECREASE, MULTIPLY. SET replaces original value, the other three modify it.

[annoyance] - The value to set/increase/decrease. Check the unit configs (like imp.cfg and horny.cfg) to see useful values.

Example:

REM Warlocks become happy from seeing a vampire sacrificed, other vampires hate it.
IF(PLAYER0,SACRIFICED[VAMPIRE] >= 1)
  CHANGE_CREATURES_ANNOYANCE(PLAYER0,VAMPIRE,INCREASE,1000)
  CHANGE_CREATURES_ANNOYANCE(PLAYER0,SORCEROR,SET,0)
ENDIF
LEVEL_UP_PLAYERS_CREATURES

Levels up all creatures of a specific kind for the player.

LEVEL_UP_PLAYERS_CREATURES([player],[creature],[count])

Where:

[player] - The name of the player who gets leveled up creatures, e.g. PLAYER1.

[creature] - Creature model that will level up. Accepts 'ANY_CREATURE'.

[count] - The amount of times the creature levels up. Accepts negative values to level down.

Manipulating Research

RESEARCH

Changes amount of research points needed to discover an item in library. It doesn't affect research order, only amount of points. If the item never was in research list, it's added at end.

RESEARCH([player],[research type],[room or power],[a])

Where:

[player] - The player’s name, e.g. PLAYER1.

[research type] - Whether it is a room or power you are researching. Use one of the following commands:

Research Type Command
Rooms ROOM
Powers MAGIC

[room or power] - The name of the room or power you want to adjust, e.g. TEMPLE or POWER_CHICKEN. See Room names section and Power names section for more information.

[a] - The new research value. This must be a number below 16777216.

Example:

RESEARCH(PLAYER1,MAGIC,POWER_CHICKEN,10000)
RESEARCH_ORDER

When this command is first called, the research list for specified players is cleared. Using it you may create a research list from beginning. Note that if you won't place an item on the list, it will not be possible to research it. So if you're using this command, you must add all items available on the level to the research list.

Example:

RESEARCH_ORDER(ALL_PLAYERS,ROOM,SCAVENGER,50000)
[...] - more RESEARCH_ORDER commands should follow.

Tweaking players

ADD_GOLD_TO_PLAYER

Allows to add some off-map gold as a reward to a player. Accepts negative values too. Example:

ADD_GOLD_TO_PLAYER(PLAYER0,5000)
SET_PLAYER_COLOR

Does a color swap for a player.

SET_PLAYER_COLOR([player],[color])

Where:

[player] - The name of the player who gets the different color, e.g. PLAYER1.

[color] - The color it will become. Accepts: 'RED, BLUE, YELLOW, GREEN, WHITE, PURPLE, ORANGE, BLACK'

Note: The change is only visual, and swapping PLAYER0 to Blue without Swapping PLAYER1 to another color will have 2 indistinguishable players.

SET_PLAYER_MODIFIER

Allows you to make change to modifiers values to a specific player. Default value is set to 100.

Accepts PLAYER_GOOD and ALL_PLAYERS.

The value is a percentage, 100 means there is no change applied. Recommended range: 20~500.

SET_PLAYER_MODIFIER([player],[modifier],[value])

Where:

[player] - The player’s name, e.g. PLAYER1.

[modifier] - The name of the modifier you want to change.

[value] - The new value you want to set it to.

Modifier Description
Health Affects maximum health, preplaced or already existing creatures aren't affected.
Strength Affects the damage of attacks strength based.
Armour Affects damage reduction, max armour is 255.
SpellDamage Affects the damage of attacks not strength based.
Speed Affects the speed, preplaced or already existing creatures aren't affected.
Salary Affects the salary.
TrainingCost Affects the cost for training.
ScavengingCost Affects the cost for scavenging.
Loyalty Affects the loyalty, resistance to scavenging.
ADD_TO_PLAYER_MODIFIER

Allows you to increase or decrease the current value of choosen modifier for a specific player.

Refers to SET_PLAYER_MODIFIER command to know more about the modifiers.

Accepts PLAYER_GOOD and ALL_PLAYERS. Accepts negative values.

ADD_TO_PLAYER_MODIFIER([player],[modifier],[value])

Where:

[player] - The player’s name, e.g. PLAYER_GOOD.

[modifier] - The name of the modifier you want to manipulate.

[value] - The value you want to add or substract.

Example:

REM *** Every minute, increases Strength modifier of PLAYER_GOOD by 1% and
REM *** decreases Armour modifier of PLAYER_GOOD by 1%.
SET_TIMER(PLAYER_GOOD,TIMER0)
IF(PLAYER_GOOD,TIMER0 >= 1200)
	NEXT_COMMAND_REUSABLE
	ADD_TO_PLAYER_MODIFIER(PLAYER_GOOD,Strength,1)
	NEXT_COMMAND_REUSABLE
	ADD_TO_PLAYER_MODIFIER(PLAYER_GOOD,Armour,-1)
	NEXT_COMMAND_REUSABLE
	SET_TIMER(PLAYER_GOOD,TIMER0)
ENDIF

Tweaking computer players

Note that some processes are only used for some of the computer player types. To make sure your commands won't be inactive, you should set up the computer player type 0 (see COMPUTER_PLAYER command), e.g.

REM Set up standard computer player to be sure no processes will be skipped when AI takes action.
COMPUTER_PLAYER(PLAYER1,0)
COMPUTER_DIG_TO_LOCATION

Makes a computer player dig somewhere.

COMPUTER_DIG_TO_LOCATION([player],[origin],[destination])

Where:

[player] - The player’s name, e.g. PLAYER1.

[origin] - The origin location, e.g. PLAYER1 or 1 to go from an action point.

[destination] - The location to dig to, e.g. PLAYER0.

Note that it marks the places for digging. If the computer has no imps, or the marked earth does not touch the dungeon it will not be dug out.

SET_COMPUTER_PROCESS

Changes conditions and parameters for one of the computer processes. A process is started if the computer player realizes that any action is needed. Some of the processes have more than one version, and specific one is selected by checking variables inside the processes.

SET_COMPUTER_PROCESS([player],["process name"],[priority],[data1],[data2],[data3],[data4])

Where:

[player] - The computer player’s name, e.g. PLAYER1. See Players section for more information.

["process name"] - Text name of the process which is being changed. See Computer Player Control Parameters for more information.

[priority] - Priority of the process. This parameter controls which process to choose if more than one process has met the conditions to be conducted.

[data1],[data2],[data3],[data4] - These parameters can have different meaning for different values of ["process name"].

Example 1: Digging to gold processes

In this case, the function definition is:

SET_COMPUTER_PROCESS([player],["process name"],[priority],[money minimum],[turn scale],[gold dug at once],[max distance])

Where:

["process name"] - Can be one of the following:

DIG TO CLOSE GOLD
DIG TO GOLD
DIG TO GREEDY GOLD
DIG TO GREEDY GOLD2

[money minimum] - Minimal amount of money to use the specific process. If a computer player has less gold than [money minimum], it will not use the process, but will check the more "greedy" one. If minimal amount of money is not reached for any process, computer will use its "fail safe" gold digging process.

[turn scale] - Number of game turns to wait before thinking of digging to next vein. The computer will always wait these turns before creating next process for digging gold. Setting small value (like 10) here will allow computer to dig many veins at once.

[gold dug at once] - Number of the gold tiles selected at one time.

[max distance] - Maximum distance from the gold vein to the nearest of computer player’s rooms. The proper values are from 1 to 84.

Note: If you will use all the gold process commands with very small range, the computer player will still dig for far gold when he'll run completely out of it. This is due to a "fail safe" process which exist after these four. To disable digging for gold, you will have to place a first vein just next to the player, and use very large value of [turn scale], e.g. 144000 will make the computer not to dig for gold in 2 hours after digging the first vein.

Example:

REM *** Dig safely for gold if more than 1250 is in treasury; search for vein in 20 squares,
REM *** wait 30 secs before the next digging
SET_COMPUTER_PROCESS(PLAYER1,"DIG TO CLOSE GOLD",0,1250,600,5,20)

REM Don't dig for gold in two hours after first time digging greedly for gold.
SET_COMPUTER_PROCESS(PLAYER1,"DIG TO GREEDY GOLD", 0,  100,76666,5,50)
SET_COMPUTER_PROCESS(PLAYER1,"DIG TO GREEDY GOLD2",0,    0,76666,5,60)
Example 2: Build a specific room processes

In this case, the function definition is:

SET_COMPUTER_PROCESS([player],["process name"],[priority],[room width],[room height],[room index],[required index])

Where:

["process name"] - Can be one of the following:

BUILD A TREASURE ROOM
BUILD A LAIR ROOM
BUILD A LAIR ROOM 4x4
BUILD A HATCHERY
BUILD A TRAINING ROOM
BUILD A RESEARCH ROOM
BUILD A WORKSHOP ROOM
BUILD A BARRACK ROOM
BUILD A GRAVEYARD ROOM
BUILD A TEMPLE ROOM
BUILD A SCAVENGER ROOM
BUILD A TORTURE ROOM
BUILD A PRISON ROOM

[room width] - Number of tiles width the room should have. Minimum is 2.

[room height] - Number of tiles height the room should have. Minimum is 2. This value shouldn't differ from room width by more than 1. If it will, then a room with non rectangular shape will result.

[room index] - Index of the room. should always correspond to the room in a ["process name"].

Process names Room indices Descriptions
n/a 0 None (can be used as [required index])
BUILD A TREASURE ROOM 2 Treasure Room
BUILD A RESEARCH ROOM 3 Library
BUILD A PRISON ROOM 4 Prison
BUILD A TORTURE ROOM 5 Torture Chamber
BUILD A TRAINING ROOM 6 Training Room
BUILD A WORKSHOP ROOM 8 Workshop
BUILD A SCAVENGER ROOM 9 Scavenger Room
BUILD A TEMPLE ROOM 10 Temple
BUILD A GRAVEYARD ROOM 11 Graveyard
BUILD A BARRACK ROOM 12 Barracks
BUILD A HATCHERY 13 Hatchery
BUILD A LAIR ROOM / BUILD A LAIR ROOM 4x4 14 Lair (you can only enlarge the lair, making it smaller usually won't work)

[required index] - Index of the room that should exist when building the new room.

Maximum size of a room is restricted only by amount of tiles which a player can mark for digging. Rooms of size up to 23x23 are usually created properly.

Note: You can't build rooms where width and height differ by more than one. If e.g. you will set width to 4, you can only use height values of 3, 4 or 5.

The important rooms: Treasure Room, Lair, Hatchery, Library and Training Room, should have priority around 0. Other rooms should have priority around -10. This will make sure AI will conduct other processes when neccessery.

Example:

REM Build 4x3 treasure room at start
SET_COMPUTER_PROCESS(PLAYER1,"BUILD A TREASURE ROOM",     0,4,3, 2,0)

REM Build only 2x3 hatchery
SET_COMPUTER_PROCESS(PLAYER1,"BUILD A HATCHERY",      0,2,3,13,0)

REM Build 3x3 scavenger room, only  after the Prison has been built
SET_COMPUTER_PROCESS(PLAYER1,"BUILD A SCAVENGER ROOM",-10,3,3,9,8)
SET_COMPUTER_CHECKS

If no important event is occuring, the computer player searches for things that need to be done using checks. Checks are similar to IF commands which allows computer player to undertake a process under some circumstances determined by values of variables.

SET_COMPUTER_CHECKS([player],["checks name"],[check every],[data1],[data2],[data3],[data4])

Where:

[player] - The computer player’s name, e.g. PLAYER1. See Players section for more information.

["checks name"] - Text name of the check which is being altered. See Computer Player Control Parameters for more information.

[check every] - Number of turns before repeating the test.

[data1],[data2],[data3],[data4] - These parameters can have different meaning for different values of ["checks name"].

SET_COMPUTER_GLOBALS

Allows the player to configure the behavior of an AI for specific criteria.

SET_COMPUTER_GLOBALS([player],[dig_stack_size],[processes_time],[click_rate],[max_room_build_tasks],[turn_begin],[sim_before_dig],[min_drop_delay])

Where:

[player] - The computer player’s name, e.g. PLAYER1. See Players section for more information.

[dig_stack_size] - how much digging a computer starts, as a percentage of the current dungeon area

[processes_time] - game turns between performing processes

[click_rate] - game turns between actions: each room tile placed, each dirt highlighted, each unit dropped

[max_room_build_tasks] - how many rooms can be built at once

[turn_begin] - game turns until AI initializes

[sim_before_dig] - simulate outcome before starting action

[min_drop_delay] - when the click rate is faster, take this as a minimum delay between dropping units

SET_COMPUTER_EVENT

Event is a sudden situation that needs a process to be undertaken. Unlike checks, events are triggered by often complicated logic conditions. Both checks and events are used to test if a process should be started.

SET_COMPUTER_EVENT([player],["event name"],[value3],[param1],[param2],[param3],[param4])

Where:

[player] - The computer player’s name, e.g. PLAYER1.

["event name"] - Text name of the event which is being altered. See fxdata\keepcompp.cfg.

[value3] - Updates the third number listed at Values. (test_interval)

[param#] - Updates the four numbers listed at Params. The first 3 have different meanings for different event types, the 4th one is the gameturn the event has last been used.

Use it to tweak computer player behavior on a per map basis. Example:

REM Blue should not add new rooms when at max capacity beyond 36 tiles
SET_COMPUTER_EVENT(PLAYER1,"EVENT CHECK ROOMS FULL",400,0,0,36,0)

Note that without level_version(1) only Param1 and Param2 can be set.

Specials

USE_SPECIAL_INCREASE_LEVEL

Activates the effect of an 'Increase Level' dungeon special.

USE_SPECIAL_INCREASE_LEVEL([player],[count])

Where:

[player] - The name of the player who owns the creature, e.g. PLAYER1.

[count] - How many times the special is activated. Accepts negative values.

USE_SPECIAL_MULTIPLY_CREATURES

Activates the effect of an 'Multiply Creatures' dungeon special.

USE_SPECIAL_MULTIPLY_CREATURES([player],[count])
USE_SPECIAL_TRANSFER_CREATURE

Opens the transfer creature special menu for the player, allowing the transfer of a creature.

USE_SPECIAL_TRANSFER_CREATURE([player])

Note that the player could - on purpose or by accident - close the menu without transferring a creature. An updated objective will close the menu. Use the CREATURES_TRANSFERRED variable (see Variables) to be sure a creature is transferred.

SET_BOX_TOOLTIP

Creates a custom tooltip for Custom special boxes.

SET_BOX_TOOLTIP([boxnumber],"[Custom tooltip]")

Where:

[boxnumber] - The ID of the custom box. With a new ADiKtEd or the ADD_OBJECT_TO_LEVEL command you can set a number. Multiple boxes may have the same number, and they will get the same tooltip and functionality.

[custom tooltip] - The text that will be displayed when you hover your mouse over the Special box. Adding a colon (:) will immediately show all text before the colon, and scroll text shown after. Eg. "All of this is visible: But this text will scroll."

Example:

SET_BOX_TOOLTIP(4, "Cast Rebound on your creatures.")

REM Place a Special box with ID 4 on action point 2.
ADD_OBJECT_TO_LEVEL(SPECBOX_CUSTOM, 2, 4)
SET_BOX_TOOLTIP_ID

Sets a Tooltip on a custom special box, with a text from the language files.

SET_BOX_TOOLTIP_ID([boxnumber],[a])

Where:

[boxnumber] - The ID of the custom box.

[a] - The number of the message, assigned to it in .po or .pot translation file.

Effects

CREATE_EFFECT

Create an Effect at a location.

CREATE_EFFECT([effect],[location],[height]*)

[effect] - The effect to spawn. Can be any effect or effect element that is in game, like the hearts that appear when healing, or the red smoke when claiming a room.
Positive numbers are Effects, Negative numbers are Effect Elements. Also accepts the names as provided in effects.toml

[location] - The location where the view should be centered if the player clicks on the "zoom to" icon on the Message Panel.

[height]* - The z-position of the effect. However, when using -41 as the 'effect' parameter, this is the gold amount displayed instead.

CREATE_EFFECT_AT_POS

Create an Effect at a subtile.

CREATE_EFFECT_AT_POS([effect],[x],[y],[height]*)

[effect] - The effect to spawn. Can be any effect or effect element that is in game, like the hearts that appear when healing, or the red smoke when claiming a room.

[x,y] - Coordinates of area center point. In subtiles (range is 1..254 on a normal sized map).

[height]* - The z-position of the effect. However, when using -41 as the 'effect' parameter, this is the gold amount displayed instead.

CREATE_EFFECTS_LINE

Spawns an effect multiple times, forming a line.

CREATE_EFFECTS_LINE([origin],[destination],[curvature], [distance], [speed], [effect])

Where:

[origin] - The origin location, where the first effect spawns. E.g. PLAYER1 or 1 to go from an action point.

[destination] - The location where the line is drawn towards.

[curvature] - 0 to go in a straight line, with bigger values to get a bigger curve. At 64 if you go from the the central top slab to the central bottom slab of a square room, it will go clockwise through the outer right slab. Use negative values to go counter-clockwise.

[distance] - How far apart the effects forming the line are. Where 24 spawns effects a single slab apart

[speed] - The delay between effects. The number represents 'number of effects per 4 game turns', set it to '2' to spawn 10 effects per second. Use 0 to spawn all effects at once. Max value is 127.

[effect] - The effect to spawn. Can be any effect or effect element that is in game, like the hearts that appear when healing, or the red smoke when claiming a room. Also accepts the names as provided in effects.toml

Other

ZOOM_TO_LOCATION

Moves the camera of a player to a specific location like an action point.

ZOOM_TO_LOCATION([player],[location])

Where:

[player] - The player’s name, e.g. PLAYER1. See Players section for more information.

[location] - The location the camera will zoom to.

Example:

REM Show the players the heroes that will spawn at hero gate 4.
IF(PLAYER0,TOTAL_CREATURES >= 15)
  REM Make sure player is not in possession or on the map
  IF(PLAYER0,VIEW_TYPE == 1)
    ZOOM_TO_LOCATION(PLAYER0,-4)
  ENDIF
ENDIF
USE_POWER

Casts an untargeted keeper power through the level script.

USE_POWER([caster_player],[power_name],[free])

Where:

[caster_player] - The player who counts as the casting player. Most powers cannot be cast by PLAYER_GOOD.

[power_name] - The name of the power to cast. E.g. POWER_HOLD_AUDIENCE. Get the names from fxdata\magic.cfg or in Power names section.

[free] - When at 0, the price of the power is deducted from the player's gold reserves. At 1 the power is free.

Example:

REM Blue will end the level when at 25 units
IF(PLAYER1,TOTAL_CREATURES >= 25)
  USE_POWER(PLAYER1,POWER_ARMAGEDDON,1)
ENDIF
USE_POWER_AT_LOCATION

Casts a keeper power at specific map location through the level script.

USE_POWER_AT_LOCATION([caster_player],[location],[power_name],[power_level],[free])

Where:

[caster_player] - The player who counts as the casting player.

[location] - The location you want to cast on.

[power_name] - The name of the power to cast. E.g. POWER_CAVE_IN. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - When at 0, the price of the power is deducted from the player's gold reserves. At 1 the power is free.

USE_POWER_AT_POS

Casts a keeper power somewhere at the map through the level script.

USE_POWER_AT_POS([caster_player],[subtile_x],[subtile_y],[power_name],[power_level],[free])

Where:

[caster_player] - The player who counts as the casting player.

[subtile_x][subtile_y] - The subtile where the power is cast. Range 1-254.

[power_name] - The name of the power to cast. E.g. POWER_CAVE_IN. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - When at 0, the price of the power is deducted from the player's gold reserves. At 1 the power is free.

Example:

REM If Red has a fortified wall at the breach point, blue will break it with a lvl3 cast of destroy walls
IF_SLAB_TYPE(14,11,DRAPE_WALL)
  USE_POWER_AT_POS(PLAYER1,44,35,POWER_DESTROY_WALLS,3,1)
ENDIF
USE_POWER_ON_CREATURE

Casts a keeper power on a specific creature. It also accepts non-targeted powers like POWER_SIGHT, which will simply use the location of the unit.

USE_POWER_ON_CREATURE([player],[creature],[criterion],[caster_player],[power_name],[power_level],[free])

Where:

[player] - The name of the player who owns the creature, e.g. PLAYER1.

[creature] - Creature model to be searched.

[criterion] - Creature selection criterion.

[caster_player] - The player which counts as the casting player.

[power_name] - The name of the power to cast. E.g. POWER_HEAL_CREATURE. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - When at 0, the price of the power is deducted from the players gold reserves. At 1 the power is free.

Example:

REM Stop Red from claiming Blue tiles
IF(PLAYER1,FLAG1 == 1)
  NEXT_COMMAND_REUSABLE
  USE_POWER_ON_CREATURE(PLAYER0,IMP,ON_ENEMY_GROUND,PLAYER1,POWER_CAVE_IN,1,1)
ENDIF
USE_SPELL_ON_CREATURE

Casts a unit spell on a specific creature. Only abilities with actual spell effects can be used. So Freeze yes, Fireball, no.

USE_SPELL_ON_CREATURE([player],[creature],[criterion],[spell],[spell_level]*)

Where:

[player] - The name of the player who owns the creature, e.g. PLAYER1.

[creature] - Creature model to be searched. Accepts 'ANY_CREATURE'.

[criterion] - Creature selection criterion.

[spell] - The spell to cast, use the spell name from fxdata\magic.cfg. You can only use Freeze, Armour, Rebound, Heal, Invisibility, Teleport, Speed, Slow, Fly, Sight, Light, Disease and Chicken.

[spell_level]* - Higher level units cast some spells with more spell power. It's the spells keepers can cast too. For these spells, give the level of the creature, otherwise use 0 or leave it off.

Example:

REM Freeze the blue dragon.
IF(PLAYER1,FLAG1 == 1)
  USE_SPELL_ON_CREATURE(PLAYER1,DRAGON,ANYWHERE,SPELL_FREEZE,0)
ENDIF
USE_SPELL_ON_PLAYERS_CREATURES

Casts a unit spell on all of a players creatures of a type.

USE_SPELL_ON_PLAYERS_CREATURES([player],[creature],[spell],[spell_level]*)

Where:

[player] - The name of the player who owns the creature, e.g. PLAYER1.

[creature] - Creature model to be searched. Accepts 'ANY_CREATURE'.

[spell] - The spell to cast, use the spell name from fxdata\magic.cfg. You can only use Freeze, Armour, Rebound, Heal, Invisibility, Teleport, Speed, Slow, Fly, Sight, Light, Disease and Chicken.

[spell_level]* - Higher level units cast some spells with more spell power. It's the spells keepers can cast too. For these spells, give the level of the creature, otherwise use 0 or leave it off.

USE_POWER_ON_PLAYERS_CREATURES

Casts a keeper power on all creatures of a specific type. It also accepts non-targeted powers which will simply use the location of the units.

USE_POWER_ON_PLAYERS_CREATURES([player],[creature],[caster_player],[power_name],[power_level],[free])

Where:

[player] - The name of the player who owns the creatures, e.g. PLAYER1.

[creature] - Creature model to be searched. Accepts 'ANY_CREATURE'.

[caster_player] - The player which counts as the casting player.

[power_name] - The name of the power to cast. E.g. POWER_HEAL_CREATURE. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - When at 0, the price of the power is deducted from the players gold reserves. At 1 the power is free.

LOCATE_HIDDEN_WORLD

Has the same effect as a 'Locate Hidden World' dungeon special.

LOCATE_HIDDEN_WORLD
MAKE_SAFE

Has the same effect as a 'Make Safe' dungeon special for the player.

MAKE_SAFE([player])
MAKE_UNSAFE

Removes all the fortifications of the Dungeon Wall of target player.

MAKE_UNSAFE([player])
SET_HAND_GRAPHIC

Changes the sprite of the power hand to a different one.

SET_HAND_GRAPHIC([player],[hand])

Where:

[player] - The name of the player who gets the different graphic, e.g. PLAYER1.

[hand] - The name of the hand, as defined in powerhands.toml.

SET_INCREASE_ON_EXPERIENCE

Allows you to make change to "IncreaseOnExp" variable, originally set in creature.cfg.

You can make them conditional with IF statements.

SET_INCREASE_ON_EXPERIENCE([valname],[valnum])

Where:

[valname] - The name of the variable you want to change.

[valnum] - The value you want to give it. 0 for no increase on experience. Range 0..32767.

valname description
SizeIncreaseOnExp Percentage of creature size increase for every experience level.
PayIncreaseOnExp Percentage of creature pay increase for every experience level.
SpellDamageIncreaseOnExp Percentage of creature damage increase for every experience level.
RangeIncreaseOnExp Percentage of spell range/area of effect increase for every experience level.
JobValueIncreaseOnExp Percentage of creature job value increase for every experience level.
HealthIncreaseOnExp Percentage of creature health increase for every experience level.
StrengthIncreaseOnExp Percentage of creature strength increase for every experience level.
DexterityIncreaseOnExp Percentage of creature dexterity increase for every experience level.
DefenseIncreaseOnExp Percentage of creature defense increase for every experience level.
LoyaltyIncreaseOnExp Percentage of creature loyalty increase for every experience level.
ExpForHittingIncreaseOnExp Percentage ExperienceForHitting increase for every experience level.
TrainingCostIncreaseOnExp Percentage of creature training cost increase for every experience level.
ScavengingCostIncreaseOnExp Percentage of creature scavenging cost increase for every experience level.

Functions

DRAWFROM

Is not a command itself but may replace a parameter of most other commands. Replaces the old RANDOM command.

DRAWFROM(a,b,c,d,e,f,g,h)

It draws at random one value or number from up to eight parameters. Examples:

REM Human player will have random start gold between 10000 and 15000
START_MONEY(PLAYER0,DRAWFROM(10000,11000,12000,13000,14000,15000))

REM One bug type creature will be added to pool
ADD_CREATURE_TO_POOL(DRAWFROM(FLY,BUG,SPIDER),5)

REM Add one of three predefined Hero parties to Hero gate 6 or 9
ADD_PARTY_TO_LEVEL(PLAYER0,DRAWFROM(thugs,fiends,dudes),DRAWFROM(-6,-9),1)

It is also possible to draw a value from a range of numbers using a tilde(~). Example:

REM Spawn a BUG at a random time at the start or near the end of the level
IF(PLAYER0,TIMER1 >= DRAWFROM(0~12000,72000~108000))
    ADD_CREATURE_TO_LEVEL(PLAYER_GOOD,BUG,-1,1,1,500)
ENDIF

Ranges can be combined with values. The '~' is a separate parameter. Combining two values between a tilde will act as three total parameters.
Example with the maximum eight parameters:

DRAWFROM(1~4,6,8~11,13)

A range cannot be used for hero gates, action points or any non-consecutive values.

Value represented by DRAWFROM is selected at start of a map, and never changes during the gameplay.

Script commands added or edited after the latest release

Note: They will only work on alpha versions!

ADD_TO_PARTY

This command adds a unit to a party. The party leader - the unit with the highest level, or most power when equal - is the one which will follow an objective, the others will follow the leader. There is a maximum of 30 party members.

ADD_TO_PARTY([party name],[creature],[experience],[gold],[objective],[countdown])

Where:

[party name] - The name of the party. This must have been declared with the CREATE_PARTY command.

[creature] - The creature’s name, e.g. HORNY. See Creatures section for more information.

[experience] - The creature’s experience level.

[gold] - The amount of gold the creatures are carrying.

[objective] - The target of the creatures and where they will make for when they enter the level. You will not need to specify the target player yet. This will be done when you place the party on the map.

These are the possible objectives:

objective description
ATTACK_DUNGEON_HEART Attack the nearest Dungeon Heart.
ATTACK_ENEMIES Attack any enemies.
ATTACK_ROOMS Attack the nearest rooms.
DEFEND_HEART Go to own heart and defend it until destroyed.
DEFEND_LOCATION Never do any objective.
DEFEND_PARTY Will not do any objective so will not assume party leadership.
DEFEND_ROOMS Defend nearest owned room, not counting portals, hearts or bridges.
SABOTAGE_ROOMS Attacks the nearest rooms. Will avoid combat if it can.
SNIPE_DUNGEON_HEART Attack the nearest Dungeon Heart, and will totally ignore anything else.
STEAL_GOLD Steal gold from the Treasure Room (amount depends on GoldHold parameter of the creature). Will avoid combat if it can.
STEAL_SPELLS Go to Library and steal one spell book. Will avoid combat if it can.

[countdown] - Number of game turns before the leader of the party start moving to the objective. Even if this is set to zero, there usually is a little delay (approx. 200 game turns) before the leader starts moving.

Note: In the original game this command could not be used inside an IF-statement, now it can.

Note 2: Parties used to be limited to 8 members, and while this limit is raised, it is generally a good idea to not go much beyond this amount.

ADD_TO_PARTY

This command adds a unit to a party. The party leader - the unit with the highest level, or most power when equal - is the one which will follow an objective, the others will follow the leader. There is a maximum of 30 party members.

ADD_TO_PARTY([party name],[creature],[experience],[gold],[objective],[countdown])

Where:

[party name] - The name of the party. This must have been declared with the CREATE_PARTY command.

[creature] - The creature’s name, e.g. HORNY. See Creatures section for more information.

[experience] - The creature’s experience level.

[gold] - The amount of gold the creatures are carrying.

[objective] - The target of the creatures and where they will make for when they enter the level. You will not need to specify the target player yet. This will be done when you place the party on the map.

These are the possible objectives: objective description ATTACK_DUNGEON_HEART Attack the nearest Dungeon Heart. ATTACK_ENEMIES Attack any enemies. ATTACK_ROOMS Attack the nearest rooms. DEFEND_HEART Go to own heart and defend it until destroyed. DEFEND_LOCATION Never do any objective. DEFEND_PARTY Will not do any objective so will not assume party leadership. DEFEND_ROOMS Defend nearest owned room, not counting portals, hearts or bridges. SABOTAGE_ROOMS Attacks the nearest rooms. Will avoid combat if it can. SNIPE_DUNGEON_HEART Attack the nearest Dungeon Heart, and will totally ignore anything else. STEAL_GOLD Steal gold from the Treasure Room (amount depends on GoldHold parameter of the creature). Will avoid combat if it can. STEAL_SPELLS Go to Library and steal one spell book. Will avoid combat if it can.

[countdown] - Number of game turns before the leader of the party start moving to the objective, in addition to the default 400 turns. Accepts negative values down to -400 to make them act sooner.

Note: In the original game this command could not be used inside an IF-statement, now it can.

Note 2: Parties used to be limited to 8 members, and while this limit is raised, it is generally a good idea to not go much beyond this amount.

Location

Script commands with the [location] variable, called [where] in the old documentation, accepts the following commands:

Command Description
Positive number Action Point of that number
Negative number Hero Gate with that number
Player name Dungeon Heart of the player
LAST_EVENT Last triggered Custom Mystery box or sacrificed unit
LAST_DEATH_EVENT[playername] The most recent location a creature with the EVENTFUL_DEATH property of the player died.
COMBAT[playername] The most recent location the player in the brackets had a battle.
CTA[playername] The location where the Call to Arms power is cast by the player.

COMBAT, LAST_DEATH_EVENT, and CTA can be used without brackets to get the human player, but this must not be used on multiplayer maps.

PLACE_DOOR

Places a door through the script. It needs to be placed on a valid location.

PLACE_DOOR([player],[doorname],[slab x pos],[slab y pos],[lock state],[free]

Where:

[player] - The player’s name, e.g. PLAYER1, that will own the door.

[doorname] - The name of the door as defined in trapdoor.cfg.

[slab x pos][slab y pos] - The x and y coordinates of the slab. Range 0-85 on a normal sized map.

[lock state] - Either LOCKED or UNLOCKED.

[free] - Set to PAID (0) or FREE (1). When it is paid the price of the power is deducted from the player's gold reserves, otherwise it is free.

Note: When using ALL_PLAYERS, it will place a door that matches the owner of the slab. Using another player will fail if the slab owner is different from the desired door owner.

Example:

IF_SLAB_OWNER(33,44,PLAYER1)
  IF_SLAB_TYPE(33,44,PRETTY_PATH)
    IF_ACTION_POINT(3,PLAYER0)
      QUICK_MESSAGE(1,"You are getting too close, I will place a door to keep you out",PLAYER1)
      PLACE_DOOR(PLAYER1,STEEL,33,44,LOCKED,FREE)
    ENDIF
  ENDIF
ENDIF
SET_CREATURE_CONFIGURATION

Allows you to make changes to attribute values set in the unit configuration files. E.g. Imp.cfg.

SET_CREATURE_CONFIGURATION([creature],[variable],[value],[second value]*)

Where:

[creature] - Creature model to be modified.

[attribute] - The name of the creature property you want to change, works on every one. E.g. Strength, SlapsToKill, Smoke.

[value] - The new value you want to set it to. It accepts the values as used in the config files. If the attribute is Powers, PowersLevelRequired or LevelsTrainValues it is the slot number instead (so, e.g. 4).

[second value]* - If there are two values to the attribute, use this value. If [value] was a slot, this is the first value instead.

Use it to tweak creatures on a per map basis.

Example:

REM On this level, Bile Demons costs lots of gold and would like to sit back.
SET_CREATURE_CONFIGURATION(BILE_DEMON,Pay,200)
SET_CREATURE_CONFIGURATION(BILE_DEMON,AttackPreference,RANGED)
USE_POWER

Casts an untargeted keeper power through the level script.

USE_POWER([caster_player],[power_name],[free])

Where:

[caster_player] - The player who counts as the casting player. Most powers cannot be cast by PLAYER_GOOD.

[power_name] - The name of the power to cast. E.g. POWER_HOLD_AUDIENCE. Get the names from fxdata\magic.cfg or in Power names section.

[free] - Set to PAID (0) or FREE (1). When it is paid the price of the power is deducted from the player's gold reserves, otherwise it is free.

Example:

REM Blue will end the level when at 25 units
IF(PLAYER1,TOTAL_CREATURES >= 25)
  USE_POWER(PLAYER1,POWER_ARMAGEDDON,1)
ENDIF
USE_POWER_AT_LOCATION

Casts a keeper power at specific map location through the level script.

USE_POWER_AT_LOCATION([caster_player],[location],[power_name],[power_level],[free])

Where:

[caster_player] - The player who counts as the casting player.

[location] - The location you want to cast on.

[power_name] - The name of the power to cast. E.g. POWER_CAVE_IN. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - Set to PAID (0) or FREE (1). When it is paid the price of the power is deducted from the player's gold reserves, otherwise it is free.

USE_POWER_AT_POS

Casts a keeper power somewhere at the map through the level script.

USE_POWER_AT_POS([caster_player],[subtile_x],[subtile_y],[power_name],[power_level],[free])

Where:

[caster_player] - The player who counts as the casting player.

[subtile_x][subtile_y] - The subtile where the power is cast. Range 1-254.

[power_name] - The name of the power to cast. E.g. POWER_CAVE_IN. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - Set to PAID (0) or FREE (1). When it is paid the price of the power is deducted from the player's gold reserves, otherwise it is free.

Example:

REM If Red has a fortified wall at the breach point, blue will break it with a lvl3 cast of destroy walls
IF_SLAB_TYPE(14,11,DRAPE_WALL)
  USE_POWER_AT_POS(PLAYER1,44,35,POWER_DESTROY_WALLS,3,1)
ENDIF
USE_POWER_ON_CREATURE

Casts a keeper power on a specific creature. It also accepts non-targeted powers like POWER_SIGHT, which will simply use the location of the unit.

USE_POWER_ON_CREATURE([player],[creature],[criterion],[caster_player],[power_name],[power_level],[free])

Where:

[player] - The name of the player who owns the creature, e.g. PLAYER1.

[creature] - Creature model to be searched.

[criterion] - Creature selection criterion.

[caster_player] - The player which counts as the casting player.

[power_name] - The name of the power to cast. E.g. POWER_HEAL_CREATURE. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - Set to PAID (0) or FREE (1). When it is paid the price of the power is deducted from the player's gold reserves, otherwise it is free.

Example:

REM Stop Red from claiming Blue tiles
IF(PLAYER1,FLAG1 == 1)
  NEXT_COMMAND_REUSABLE
  USE_POWER_ON_CREATURE(PLAYER0,IMP,ON_ENEMY_GROUND,PLAYER1,POWER_CAVE_IN,1,1)
ENDIF
USE_POWER_ON_PLAYERS_CREATURES

Casts a keeper power on all creatures of a specific type. It also accepts non-targeted powers which will simply use the location of the units.

USE_POWER_ON_PLAYERS_CREATURES([player],[creature],[caster_player],[power_name],[power_level],[free])

Where:

[player] - The name of the player who owns the creatures, e.g. PLAYER1.

[creature] - Creature model to be searched. Accepts 'ANY_CREATURE'.

[caster_player] - The player which counts as the casting player.

[power_name] - The name of the power to cast. E.g. POWER_HEAL_CREATURE. Get the names from fxdata\magic.cfg or in Power names section.

[power_level] - The charge level of the power. Range 1-9. Is ignored for powers that cannot be charged.

[free] - Set to PAID (0) or FREE (1). When it is paid the price of the power is deducted from the player's gold reserves, otherwise it is free.

Deprecated

SET_CREATURE_STRENGTH

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

This command sets the strength of all the creatures of that type on the level. Each creature has a default strength which can be found in the creature.cfg file, e.g. the BILE_DEMON has a strength level of 80.

SET_CREATURE_STRENGTH([creature],[a])

Where:

[creature] - The creature’s name, e.g. HORNY. See Creatures section for more information.

[a] - The new strength of that creature. The strength must be between 0 and 255. Putting higher values will not be taken into account.

Example:

REM Set the demon spawn strength to 190
SET_CREATURE_STRENGTH(DEMON_SPAWN,190)
SET_CREATURE_HEALTH

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

This command sets the health of all the creatures of that type on the level. Each creature has a default full health level which can be found in the creature.cfg file, e.g. the DRAGON has a full health level of 900.

SET_CREATURE_HEALTH([creature],[a])

Where:

[creature] - The creature’s name, e.g. ORC. See Creatures section for more information.

[a] - The new health level of that creature. The health level must be between 0 and 7895. If the value is greater, some creatures may instantly die when reaching certain level of experience.

Example:

REM Set the orc health to 1000
SET_CREATURE_HEALTH(ORC,1000)
SET_CREATURE_ARMOUR

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

This command sets the armour of all the creatures of that type on the level. Each creature has a default armour level which can be found in the creature.cfg file, e.g. the Dark Mistress has a armour level of 50.

SET_CREATURE_ARMOUR([creature],[a])

Where:

[creature] - The creature’s name, e.g. HORNY. See Creatures section for more information.

[a] - The new armour level of that creature. The armour level must be between 0 and 255. Putting higher values will still make a final value smaller than 256.

Example:

REM Set the demon spawn armour to 60
SET_CREATURE_ARMOUR(DEMON_SPAWN,60)
SET_CREATURE_FEAR

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

This command sets the fear of all the creatures of that type on the level. Each creature has a default fear which can be found in the creature.cfg file, e.g. the FLY has a fear level of 30.

SET_CREATURE_FEAR([creature],[a])

Where:

[creature] - The creature’s name, e.g. BUG. See Creatures section for more information.

[a] - The new fear level of that creature. The fear level must be between 0 and 255. Putting higher values will still make a final value smaller than 256.

Example:

REM Set the spider fear to 190
SET_CREATURE_FEAR(SPIDER,190)
SET_CREATURE_FEAR_STRONGER

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

SET_CREATURE_FEAR_WOUNDED

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

SET_CREATURE_FEARSOME_FACTOR

Note: Although this command is functional, it is recommended to use SET_CREATURE_CONFIGURATION instead

RANDOM

The RANDOM() function of original DK has been replaced by DRAWFROM. This command is currently unimplemented - use DRAWFROM instead.

It is meant to be a function used in same way as DRAWFROM, but selecting value each time during gameplay instead of doing it once at start of the level.

SET_CAMPAIGN_FLAG

Use SET_FLAG instead, because campaign_flags can be used like other flags, the only difference is that the value is not forgotten at the end of a level.

ADD_TO_CAMPAIGN_FLAG

Use ADD_TO_FLAG instead, because campaign_flags can be used like other flags, the only difference is that the value is not forgotten at the end of a level.

SET_HATE

Script command to make a computer player hate another one, which should cause him to attack. Non-functional in both the original game and KeeperFX.

USE_SPECIAL_LOCATE_HIDDEN_WORLD

Replaced with LOCATE_HIDDEN_WORLD

USE_SPECIAL_MAKE_SAFE

Replaced with MAKE_SAFE

Example scripts

Reduce prison and torture effectiveness once the player gets a big army
IF(PLAYER0,TOTAL_CREATURES > 20)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(StunEvilEnemyChance, 80)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(StunGoodEnemyChance, 60)
ENDIF
IF(PLAYER0,TOTAL_CREATURES > 25)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(StunEvilEnemyChance, 60)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(StunGoodEnemyChance, 20)
ENDIF
IF(PLAYER0,TOTAL_CREATURES < 18)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(StunEvilEnemyChance, 100)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(StunGoodEnemyChance, 85)
ENDIF
IF(PLAYER0,GOOD_CREATURES > 8)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(TortureDeathChance, 20)
ENDIF
IF(PLAYER0,GOOD_CREATURES > 12)
	NEXT_COMMAND_REUSABLE
	SET_GAME_RULE(TortureDeathChance, 60)
ENDIF
Parties that spawn in a loop based on a timer
REM: Every few minutes spawn party melee at one of the Fortress entrances. Loop stops when Heroes have no BARRACKS left.
IF(PLAYER_GOOD,BARRACKS >= 1)
	REM First an extra delay of 3000 turns and spawn a 1 time party
	IF(PLAYER_GOOD,TIMER1 >= 3000)
		SET_TIMER(PLAYER_GOOD,TIMER2)
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,melee,-11,1)
	ENDIF
	REM Now every 8000 turns spawn the party from hero gate 4
	IF(PLAYER_GOOD,TIMER2 >= 8000)
		NEXT_COMMAND_REUSABLE
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,melee,-4,1)
		NEXT_COMMAND_REUSABLE
		SET_TIMER(PLAYER_GOOD,TIMER2)
	ENDIF
	REM At 7000 turns, spawn another one time party and start a second loop.
	IF(PLAYER_GOOD,TIMER1 >= 7000)
		SET_TIMER(PLAYER_GOOD,TIMER6)
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,melee,-4,1)
	ENDIF
	REM Now every 8000 turns spawn the party from hero gate 11 as well
	IF(PLAYER_GOOD,TIMER6 >= 8000)
		NEXT_COMMAND_REUSABLE
		ADD_PARTY_TO_LEVEL(PLAYER_GOOD,melee,-11,1)
		NEXT_COMMAND_REUSABLE
		SET_TIMER(PLAYER_GOOD,TIMER6)
	ENDIF
ENDIF
REM The parties stop spawning when the heroes have no more barracks, show the player by hiding the hero gates
IF(PLAYER_GOOD,BARRACKS == 0)
	HIDE_HERO_GATE(-4,1)
	HIDE_HERO_GATE(-11,1)
ENDIF