Gameplay Log in to Edit

This page lists all internal gameplay mechanics and is VERY SPOILERISH. For non-spoiler version, consider reading the [Manual] page instead.

YOU HAVE BEEN WARNED! SPOILERS AHEAD!

World

The game world consists of large map, separated into 4 isolated continents. The basic layout is predetermined, but it gets "salted" for each new game.

Each continent takes exactly 64 x 64 tiles and is surrounded by water. When player travels between continents, he always enters them at predetermined locations (see below).

A scepter is hidden somewhere on the map. Finding it is winning the game. The location is picked at random, as per "salting".

Coordinates start from the bottom of the screen, so '0,0' is a bottom-left corner. Note, that player is allowed to stand on corner tiles, at which point the missing tiles are depicted as water.

Hard-coded locations

  • X=11 Y=19 Archmage's alcove
  • X=11 Y=07 Home castle
  • X=11 Y=03 Starting point for continent 1
  • X=01 Y=37 Starting point for continent 2
  • X=14 Y=62 Starting point for continent 3
  • X=09 Y=01 Starting point for continent 4
  • X=27 Y=11 Plains dwelling at continent 0

  • All towns and castles

  • All boat starting positions (per town)
  • All town gate positions (per town)

Salting

max_grass    0   1   2   3
table       644 844 465 600
  1. Load original map.
  2. Hide Scepter:
    A. scepter_key = rand(0x00, 0xff)
    B. continent = rand(100, 400) / 100 - 1 //0-3
    C. N = rand(0, max_grass_on_this_continent)
    D. Find Nth grass (0x00 or 0x80) tile on continent
    E. Put scepter there!
  3. Generate character.
  4. Generate spells for sale in towns (see below).
  5. Adjust world for sorceress.
    A. Remove magic alcove from map
  6. Salt each continent (check each tile, replace):
    A. Ensure 2 artifacts, 1 navmap, 1 orb, 2 telecaves, 10 dwellings and 5 friendly foes.
    C. Populate Foes encountered on the map.
    D. Populate dwelling at 0,1b,b with peasants (hard coded).
  7. Populate all castles.

Populating all castles

Table: villains per continent
       06 04 04 03
  1. Give all castles to monsters. All castles start as "unoccupied".
  2. On each continent, repeat villains_per_continent times:
    A. Find random castle, that is unoccupied
    B. Give ownership to villain.
    C. Occupy, using pre-determined troops and numbers:
  3. Populate rest of the castles, still owned by monsters (see below).

Creatures and their numbers are:

    TROOP TYPES (hex)

    Villain  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
    Slot
       0    00 0B 01 03 02 01 02 09 07 04 04 16 06 08 17 17 18
       1    03 02 01 07 02 0D 08 14 0F 05 05 18 10 0A 15 18 18
       2    02 02 04 08 08 0E 0A 13 11 0D 0D 0F 16 12 14 12 18
       3    00 00 05 11 09 14 12 0A 16 15 15 07 0B 0E 06 0E 17
       4    00 00 0F 0C 10 14 0E 01 03 17 17 06 00 18 00 14 15

TROOP NUMBERS (dec)

    Villain  0   1   2   3   4   5   6   7   8   9  10  11  12  13   14  15  16 
    Slot        
       0    50  10  70  30  50 250 100  30 150 500 600  30 300  35   30  50 100
       1    20  30  50  20  50  10  20  30  20 100 200   5  40 100   50  10  25
       2    25  20  20  10  10  10  20  10  10  30  50  30  20  80  100 200  25
       3    30  60  20   2  10   4  15  30   5  10  25 200 100  60  500 250 100 
       4    25  40  4    6   5   4  15 300  80   6  10 200 700   5 5000  60 100

Placing dwellings.

Each continent has a number of pre-defined dwellings, and generates the
rest randomly.

Predefined dwellings are:

Continent
        0  00 01 07 04 03 06
        1  0C 05 0B 09 0F 09
        2  0D 10 11 13
        3  16 15 14 18 17

Note: different continents have different numbers of troops (6, 6, 4, 5).

When this list is exhausted, troop type is randomly picked within those ranges:

Continent
        0  0x00 - 0x0e (peasant-knight)
        1  0x01 - 0x0e (sprites-knight)
        2  0x02 - 0x0e (militia-knight)
        3  0x14 - 0x18 (archmag-dragon)

Note: as troop type is returned, and not dwelling type, a conversion must
be performed to figure appropriate map tile.

All dwellings start fully populated.

Sell spells

1. Set spells for all towns to 0xFF
2. Set spell for town[0x15] to 0x07 // huntersville sells bridge!   
3. Foreach Spell (except 0x07):
       A. Pick random Town with spell == 0xFF
       B. Set spell for that Town = Spell
4. Foreach Town that still sells 0xFF:
       A. Town.spell = rand(0, 0x0D) // random spell

Generating armies

Dwelling-to-troop table:

Dwelling  0-PLAINS      1-FOREST   2-HILL     3-DUNGEON 
   Index

       0  00 peasant    01 sprite  07 orc     04 skeleton
       1  03 wolf       06 gnome   0c dwarf   05 zombie
       2  0b nomad      09 elf     0f ogre    0d ghost
       3  10 barbarian  11 troll   16 giant   15 vampire
       4  14 archmage   13 druid   18 dragon  17 demon

When generating armies, a "difficulty curve" is used. It determines
the chances to get higher order troop for a given dwelling.

Difficulty ranges from 0 to 3.

Castles have their own preset difficulty value (see table in "Castle").

Foes have their value equal to the continent they are on (so, 0-3).

Troop chance table:

Difficulty  0  1  2  3
     Index

         0  3C 14 0A 03 
         1  5A 46 14 06
         2  62 5F 32 0A
         3  65 63 5A 28

Note: for difficulty 3, it's very easy to get index "4", as 1d100 will likely roll something > 0x28, however, for difficulty 0, it is impossible, as 1d100 can never roll anything > 0x65.

Troop numbers table:

Difficulty  0  1  2  3
     Troop

  Peasants  0A 14 32 64
   Sprites  14 32 64 7F
   Militia  0A 14 32 64
    Wolves  05 0F 1E 50
 Skeletons  05 0A 19 32
   Zombies  05 0A 19 4B
    Gnomes  0A 19 32 64
      Orcs  05 0F 1E 50
   Archers  00 00 00 00
     Elves  05 0A 19 32
   Pikemen  00 00 00 00
    Nomads  04 08 0F 1E
   Dwarves  04 0A 14 32
    Ghosts  02 04 0A 14
   Knights  00 00 00 00
     Ogres  02 04 08 0F
Barbarians  02 04 0A 14
    Trolls  02 04 08 0F
   Cavalry  00 00 00 00
    Druids  01 03 06 0A
 Archmages  01 02 04 08
  Vampires  02 04 0A 19
    Giants  01 02 05 0A
    Demons  01 02 04 08
   Dragons  01 01 01 02

Repopulating castle

1. Each castle has it's own difficulty (see table in "Castle") from 0 to 3.
2. All 5 slots are populated.
3. First, dwelling type is picked (0-3).
4. Then, chance is rolled (1d100).
5. Following the chance table, while `chance` > value, increase index.
6. Pick troop type based on dwelling type and chosen index (see dwelling-to-troop table above).
7. Troop numbers are picked from the "troop numbers table" (see above).
    A. If picked number is 0x01, use rand(1, number) + rand(1, number) instead (always 2!).

Populating foe

1. Difficulty = continent this foe is on (0-3)
2. 3 slots are populated.
3. Dwelling = rand(0, 3)
4. Chance = rand(1, 100) // roll 1d100
5. Index = lowest row from the "chance table" with value <= Chance 
6. Pick troop type based on Dwelling type and Index (see "dwelling-to-troop" table above).
    A. If troop type was already picked in previous slots, re-run step 3.
7. Pick troop number from the "troop numbers table" (see above).
    A. If picked number is 0x01, use rand(1, number) + rand(1, number) instead (always 2!).

The Orb Bug

In both DOS versions (and probably all else, verify!), the orb for the first continent could never be found. This happens due to a bug in nav map salting, where the algorithm goes something like:

if (continent != 03)
{
    map[continent].x = x
}
    map[continent].y = y
//code probably lacked braces, that make this clear
//or indentation?

Instead of silently ignoring last continent (what should happen), the out-of-bound array write is performed, and next memory-adjacent array (the orbs!) gets overwritten.

Specifically, the Y value for Orb 0 becomes incorrect. Thus, Orb 0 could never be found.

Hard-coded costs

  • Archmage's training: 5000
  • Siege weapons: 3000
  • Boat Rental: 500/100

Army

A major portion of gameplay revolves around armies. Player has an army, foes have armies, castles have garrisons. Armies mostly come in three flavors - small (3 troops each), medium (4 troops each) and large (5 troops each). An army is a simple list of troop types and their counts.

Player is not allowed to have multiple stacks of the same troop type; neither empty slots - dismissing a troop, garrisoning, or losing a troop reorders the army. Foes, villains and monsters can have reoccurring troops however, and often abuse that to their favor.

Player always has some kind of army. Losing last troop sends player back to the home castle (to the tile just below the gate), where some default troops (20 peasants) are added for free. This event is known as "defeat".

Troops

Each troop type has the following values:

Skill Level (SL)
Movement Rate (MV)
Hit points (HP)
Melee Damage (minMelee, maxMelee)
Ranged Damage (minRanged, maxRanged)
Ammo (MaxAmmo)
Recruitment cost (RCost)
Weekly cost (WCost)
Maximum Population (MaxPop) -- in dwellings
Growth -- ammount to add to foes and unowned castles at the lucky week
Spoils Factor (Spoils) -- used to calculate spoils of war
Morale Group
Special Ability

Some values are not displayed in the game or the manual.

TROOP      SPOILS   GROWTH   MAXPOP

Peasants   1        6        250
Sprites    1        6        200
Militia    5        5        0
Wolfs      4        5        150
Skeletons  4        5        150
Zombies    5        5        100
Gnomes     6        5        250
Orcs       7        5        200
Archers    25       5        0
Elfs       20       4        100
Pikemen    30       4        0
Nomads     30       4        150
Dwarves    30       4        100
Ghosts     40       3        25
Knights    100      3        0
Ogres      75       3        200
Barbarians 75       3        100
Trolls     100      3        25
Cavalery   80       2        0
Druids     70       2        25
Archmages  120      2        25
Vampires   150      2        50
Giants     200      2        50
Demons     300      1        25
Dragons    500      1        25

Adventure

Each step on a grassy tile takes one turn. A step on a desert tile ends the day.

Every 40 turns, a day passes, and every 5 days, a week comes to an end. See 'End Of Week' for details.

When on a boat, travel between continents is possible. This also ends the week.

Score

Player's score can be calculated at any given moment by

score = 
    ((villains caught * 500) 
    + (artifacts found * 250)
    + (castles garrisoned * 100) 
    - (followers killed * 1))
        * difficulty_modifier

Where difficulty factors for Easy, Normal, Hard and Impossible are 0.5, 1, 2 and 4.

Treasure

Each continent has a number of 'random treasure' tiles, which are filled with random treasures during world "salting".

Artifact

Artifacts have hard-coded bonuses, described sketchily in the [Manual]. There are 2 artifacts per continent. Artifacts have their own tiles, and do not look like chests.

Ring of Heroism: absolutely no idea
Articles of Nobility: when picked up, player instantly gains +2000 commission
Shield of Protection: -25% base damage taken from enemy
Anchor of Admiralty: changes weekly cost of boat from 500 to 100 (and initial rental of boat as well)
Book of Necros: when picked up, spell capacity is multiplied x 2; when gaining max spells, points are multiplied x 2
Crown of Command: when picked up, base leadership is multiplied x 2, and leadership is reset; when gaining leadership, points are multiplied x 2
Amulet of Augmentation: when picked up, player instantly gains +5 spell power
Sword of Prowess: +50% base damage inflicted on enemy

Mystery of the Heroism Ring

Some manuals say "it gives more leadership". Well, it doesn't.

Some manuals say "it increases the odds" in fighting. As far as damage goes, nope.

Some manuals say "it increases luck". What luck?

A navigational map allows the player to travel to the next continent. Each continent (except the last one) has 1 map hidden within, placed there during world "salting". Map to the first continent is received for free upon game start, so players are always able to sail back home. Navigational Maps use the chest tile.

Orb

An orb allows you to view an entire mini-map. There is 1 orb per continent, placed on "salting". Orbs use the chest tile.

Due to a bug in "salting", player can never find orb on the first continent.

Random Event

A treasure chest containing a random bonus. The event is rolled when it is being picked up, so it is possible to cheat around it using save-scumming. The possible events are:

  • +X Gold "After scouring the area..."
  • +X Commission "After surveying the area..."
  • +1 Spell Power "Traversing the area, you stumble upon..."
  • +X Max Spell "A tribe of nomads..."
  • +X Spell Y "You have captured a mischievous imp..."

Randomization algorithm works as follows:

1. Get random value (0x01 - 0x64)           //roll 1d100
2. If randomvalue < gold_chance[continent]
    A. Points = rand(1, extra_gold_points[continent]) + base_gold_points[continent]
    B. Gold = Points * 100
    C. Leadership = Gold / 50
    D. If (player.has_crown) Leadership = Leadership * 2
    E. Player chooses Gold or Leadership
        Player.gold += Gold
       or
        Player.leadership += Leadership
3. Else If randomvalue < income_chance[continent]
    A. Points = rand(1, extra_weekly_points[continent]) + base_weekly_points[continent]
    B. Player.Comission += Points
4. Else If randomvalue < spell_power_chance[continent]
    A. Points = 1
    B. Player.Spellpower += Points
5. Else If randomvalue < number_of_spells_chance[continent] 
    A. Points = base_number_of_spells[continent]
    B. If (player.has_necros_book) Points *= 2
    C. Player.MaxNumberOfSpells += Points
6. Else If randomvalue < new_spell_chance[continent]
    A. Points = rand(1, (continent+1)) // continents are 0-based
    B. Spell Type = rand(0, 13) // there are 14 spells
    C. Player.spells[Spell Type] += Points 
7. Else 
    A. Play music
    B. Act as if a bonus was taken
    C. Show empty message box
    D. This should never happen!

And is bounded to those hard-coded tables:

      Event    GOLD   COMMISSION  SPELL_POWER  MAX_SPELLS  EXTRA_SPELLS
  Continent

          0    0x3d     0x51          0x00       0x56          0x65
          1    0x42     0x56          0x57       0x5c          0x65
          2    0x4c     0x56          0x58       0x5d          0x65
          3    0x47     0x51          0x56       0x5b          0x65

As you can see, step 7 never takes place, because EXTRA_SPELLS are always greater
than 0x64. However, the algorithm itself supports such behavior and can enter step 7,
if the tables are different.

 RND Values    BASE_GOLD EXTRA_GOLD BASE_INCOME EXTRA_INCOME MAX_SPELLS
  Continent

          0      0x00      0x05         0x09       0x0029       0x01
          1      0x04      0x10         0x31       0x0033       0x01
          2      0x09      0x15         0x63       0x0065       0x02
          3      0x13      0x1F         0xC7       0x012d       0x02

Note, that BASE_ and EXTRA_ should not be treated as MIN_ and MAX_, it's actually
" rand(1, EXTRA_) + BASE_ ", as per algorithm above.

Friendly Foe

Each continent has a number of 'friendly foes' that wish to join you instead of fighting.

When player encounters one, a troop type and number are generated, according to "Populating foe" algorithm described in "World Salting" above, and a yes/no prompt is presented. If player's army has no free slots (and non-free slots of same troop type do not count here), than friendly foe vanishes, without giving player a chance to accept it.

In any event the foe is erased from the map.

Towns

There are 26 towns, each mapped to a castle, so different towns provide different information regarding castle garrisons.

You can buy a boat in the town, at which point it spawns nearby on the water. Coordinates for such spawns are hard-coded.

TOWN    BOAT_X  BOAT_Y  GATE_X  GATE_Y
0x00     0x1e    0x0b    0x1d    0x0b 
0x01     0x3b    0x05    0x39    0x04
0x02     0x27    0x32    0x26    0x31
0x03     0x22    0x16    0x23    0x17
0x04     0x04    0x31    0x05    0x31
0x05     0x12    0x2c    0x10    0x2c
0x06     0x0e    0x3c    0x0c    0x3c
0x07     0x0a    0x26    0x09    0x26
0x08     0x0e    0x1a    0x0d    0x1b
0x09     0x3a    0x20    0x39    0x21
0x0A     0x33    0x1b    0x33    0x1d
0x0B     0x3a    0x38    0x39    0x38
0x0C     0x02    0x24    0x03    0x24
0x0D     0x12    0x15    0x10    0x15
0x0E     0x29    0x39    0x28    0x3a
0x0F     0x31    0x0c    0x32    0x0e
0x10     0x3b    0x3c    0x3a    0x3b
0x11     0x38    0x04    0x38    0x05
0x12     0x0a    0x3c    0x09    0x3b
0x13     0x0c    0x07    0x0d    0x08
0x14     0x08    0x03    0x06    0x03
0x15     0x0b    0x03    0x0c    0x04
0x16     0x2f    0x24    0x2f    0x23
0x17     0x32    0x09    0x32    0x08
0x18     0x02    0x09    0x03    0x09
0x19     0x3b    0x30    0x3a    0x2f

Dwellings

Castles

There are 26 castles (not counting the Home Castle).

Each castle has a hard-coded difficulty level, that determines what monsters spawn there (see "Castle Population" in "World Salting" above), during salting and at the end of week (if you leave a castle un-garrisoned).

CASTLE DIFFICULTY TOWN
Azram 00 0x03
Basefit 01 0x0E
Cancomar 00 0x07
Duvock 01 0x10
Endryx 02 0x0C
Faxis 00 0x16
Goobare 02 0x12
Hyppus 02 0x15
Irok 00 0x11
Jhan 01 0x13
Kookamunga 00 0x0D
Lorsche 02 0x05
Mooseweigh 01 0x09
Nilslag 00 0x0F
Ophiraund 00 0x0B
Portalis 00 0x02
Quinderwitch 01 0x08
Rythacon 00 0x00
Spockana 03 0x06
Tylitch 02 0x04
Uzare 03 0x01
Vutar 00 0x14
Wankelforte 00 0x18
Xelox 02 0x0A
Yeneverre 01 0x17
Zyzzarzaz 03 0x19

When you leave a garrison in the castle, you pay them off in gold one last time (= weekly pay).

Villain and monster castles grow numbers of their troops at the end of week.

Home Castle

Magic Alcove

End Of Week

At the end of each week a creature is picked at random. Every 4th week is always a week of peasant.

At the week of peasant, all your ghosts permanently turn into peasants.

Player's leadership is reset to base_leadership value.

All non-garrisoned player castles, are re-occupied by monsters, as per "Castle repopulation" in world salting (see above).

All dwellings for the weekly creature are re-populated, meaning their creature count is at maximum (MaxPop) again.

All castles not owned by player and all the foes grow their troop counts for the weekly creature according to the growth value (Growth). This happens after castle repopulation.

Combat

There are two types of combat: "field combat" and "castle siege".

During siege, the level layout is predetermined with castle tiles. Player army starts at the bottom of the screen, and garrison stands on the top.

#3124#
#.5..#
#....#
#534.#
##12##

For field combat, player army starts on the left and foe army stands to the right.
Some obstacles are randomly generated in between.

1....1
2....2
3....3
4....4
5....5

The algorithm for obstacle generation is unknown, but ANY approximation will look good.

Unit

A unit is an in-combat representation of a troop, spotting some additional properties:
* Initial Count (can never resurrect more than initial units)
* Damage counter (injury)
* Moves counter (move points spent/left)
* Ammo counter (ranged attacks left)
* Action counter (acted this turn)
* Retaliation flag (retaliated this turn)
* Retaliation Count (retaliate with full numbers even after kills have been made)
* X position on battlefield
* Y position on battlefield

Hit points.
Skill level.

Waiting.

Statuses

Out-of-control: troop moves on it's own. Can attack both sides.

Frozen: under the effect of the freeze spell. Can't move.

Damage types

Physical: Comes from Melee and Ranged attacks. Can not be blocked.

Arcane: Comes from magical creatures' Ranged attacks and spells. Immune creatures receive no damage.

Holy: Comes from Turn Undead spell. Non-demonic creatures receive no damage.

Special abilities

  • vampires will gain whatever damage they inflict as hit points, growing own stack (cannot exceed initial troop count).
  • ghosts will add units equal to the number of enemy units slain.
  • demons have a 10% chance of halving an enemy troop in addition to regular damage.
  • dragons are immune to magic (that includes ranged attacks from archmages and druids).
  • trolls regenerate hit points between turns.

Between turns

  1. Reset retaliation flags for attacking side.

End of turn

  1. Remove all injury from units with Regenerate ability (Trolls).
  2. Reset move and act flags.

Damage

assuming each unit has those values:
    turnC - number in stack, before damage was dealt (used in retaliation,etc)
    curC - current number in stack
    maxC - maximum number in stack (==army at the begining of battle)

damage could be dealt using:

function deal_damage(a_UID, t_UID, is_ranged, is_external, external_damage, retaliation)
    //a_UID is attacker UID (0-9)
    //t_UID is target UID (0-9)
    if (!retaliation)
        units[a_UID].turnC = units[a_UID].curC
        units[t_UID].turnC = units[t_UID].curC

    dont_retaliate = retaliation
    demon_kills = 0

    if (is_external)
        //magic-vs-unit
        final_damage = external_damage 
    else
        //unit-vs-unit
        if (attacking troop IS demon)
            if (rand(1,100) > 89) //10% chance
                demon_kills = ceil(units[t_UID].curC / 2)

        if (is_ranged)
            dont_retaliate = 1
            units[a_UID].ammo--
            if (attacking troop IS druid)
                if (defending troop IS dragon)
                    cancel attack
                dmg = 10
            if (attacking troop IS archmage)
                if (defending troop IS dragon)
                    cancel attack
                dmg = 25
            else
                dmg = rand(minRanged, maxRanged)
        else
            dmg = rand(minMelee, maxMelee)

        total = dmg * units[a_UID].turnC
        skill_diff = units[a_UID].skill + 5 - units[t_UID].skill
        final_damage = (total * skill_diff) / 10

        if (a_UID < 5)
            if ( under_control(a_UID) )
                final_damage *= morale_modifier(a_UID)  //1-norm,0.5-low,1.5-high

        if (a_UID < 5 && player.has_sword)
            final_damage *= 1.5f

        if (t_UID < 5 && player.has_shield)
            final_damage /= 4
            final_damage *= 3
            //almost same as multiplying 0.75, but more brutal, as div by 4 can yield 0

    final_damage += units[t_UID].injury
    final_damage += units[t_UID].hp_per_unit * demon_kills

    kills = units_killed(final_damage, units[t_UID].hp_per_unit)
    injury = damage_remainder(final_damage, units[t_UID].hp_per_unit)

    units[t_UID].injury = injury

    if (kills < units[t_UID].curC)
        //stack survives 
        units[t_UID].curC -= kills
        if (t_UID < 5)
            player_army_count[t_UID] = units[t_UID].curC
    else
        //stack dies
        units[t_UID].dead = 1
        units[t_UID].curC = 0
        final_damage = units[t_UID].turnC * units[t_UID].hp_per_unit
        if (t_UID < 5)
            player_army_troop[t_UID] = FF
            player_army_count[t_UID] = 0

    if (t_UID < 5)
        player.followers_killed += kills

    if (!is_external)
        //undead powers:
        if (attacking troop IS ghost)
            units[a_UID].curC += kills
        if (attacking troop IS vampire)
            units[a_UID].curC += units_killed(final_damage, units[a_UID].hp_per_unit)
            if (units[a_UID].curC > units[a_UID].maxC)
                units[a_UID].curC = units[a_UID].maxC
                units[a_UID].injury = 0

        if (!dont_retaliate)
            if (!units[t_UID].retaliated)
                dont_retaliate = 1
                units[t_UID].retaliated = 1
                deal_damage(t_UID, a_UID, 0, 0, 0, 1) //recursive
    else
        if (units[t_UID].dead)
            units[t_UID].coords = 0xFF

Spoils of war

Value is calculated before the battle. Resulting gold is the sum of all troops' (spoils factor, multiplied by 5, multiplied by troop count).

Villain escape

When player wins a battle against a villain, but lacks proper contract, villain escapes to the next random castle not owned by another villain. Castles owned by players and random monsters are fair game. Then, he gains control of whatever army is stationed in that castle.

Thus, it seems villains can get control of EMPTY armies, in case player's empty castle is chosen. TODO: verify this.

Combat AI

  1. If unit is blocked (has enemies surrounding it):
    1. Pick close target.
    2. Attack!
  2. If unit has ranged shots (and ammo):
    1. Pick distant target.
    2. Shoot!
  3. If unit can fly:
    1. Pick distant target.
    2. Resolve destination.
    3. If possible: Fly!
    4. If not possible: Wait!
  4. Unit can walk:
    1. Pick distant target.
    2. Resolve destination.
    3. If possible: Walk!
    4. If not possible: Wait!

After Walk and Fly actions take place, the algorithm is repeated.

After Attacking, Shooting or Waiting, the turn passes on as usual.

Target picking

For distant targets, shooting units are picked. If there are no shooting units, units with minimum troop hp are picked.

For close targets, units with minimum troop hp are picked.

Neither check involves troop stack count, i.e. Peasants are always picked first, because
they have 1 HP. Even if there are 200 in the stack.

Note: this is rather disappointing. I was hoping the AI would have more tricks up it's sleeve.

Move resolving

Units steadily move to their targets. AI never does stupid moves, and if there are no
unoccupied tiles (that would make the Pythagorean distance between it and it's target smaller) around it, it waits.

Similar rules apply to Flying units: closest (to origin), unoccupied, adjacent to target unit tile is picked, and if none are available, AI waits.

Spells

Combat spells

  • Clone (2000) = increase stack by a number of units, equal to 10 hit points * spell power + injury, accurately assigns new injury (clone remainder)
  • Teleport (500) = move any unit, friendly or foe, onto an open square
  • Fireball (1500) = deal 25 * spell power magic damage
  • Lightning (500) = deal 10 * spell power magic damage
  • Freeze (300) = cause one unit to not move (it can still attack adjacent)
  • Resurrect (5000) = causes N dead units in a stack to come back to life, where N is equal to spell power. If maximum initial count is reached, and is capped against, injury is healed.
  • Turn Undead (2000) = deal 50 * spell power holy damage

Questions:

  • Freeze spell duration?

Adventure spells

  • Bridge (100) = build 2 (or less) tiles of bridge over water tiles
  • Time stop (200) = stops time for 10 * spell power steps, resets to 0 if you move over desert tile
  • Find Villain (1000) = show the current contract's villain's location (castle)
  • Castle Gate (1000) = go to any castle you previously visited
  • Town Gate (500) = go to any town you have previously visited ("gate" coordinates are used)
  • Instant Army (1000) = as long as you have an open stack or have that unit, you get (spell_power + 1) * rank_multiplier of units without paying any gold
  • Raise Control (500) = increase Leadership by 100 * spell power till end of week

Instant Army table:

Rank Knight Paladin Sorceress Barbarian MULTIPLIER
0 Peasants Peasants Sprites Peasants 3
1 Militia Militia Gnomes Wolves 2
2 Archers Archers Elves Orcs 1
3 Knights Cavalry Druids Ogres 1

Mods

Real-time Adventure

In some versions of the game (MD, QFDBS), the overworld adventure happens in real-time. You and your foes move by pixels, and not by tiles; days pass by on their own.

Troop cast

In some version of the game (which?) spells are cast by troops and not heroes. TODO: Explore this.


Related

Wiki: Home
Wiki: Roadmap

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.