I reached another big checkpoint yesterday for my artificial intelligence framework: now my units know how they want to position themselves considering the resulting influence maps that they party blackboard holds. See that Iâm expressing a desire, not the pathfinding to that position or the steering behavior used. It was a long month of development again, because this was a long study again, until I found a middle ground that was simple enough for me to implement after some trial and error.
My starting point was an article called âRecognizing Strategic Dispositions: Engaging the Enemyâ, from Steven Woodcock and Wyrd Wyrks and was published on AI Game Programming Wisdow. This is a staple for anyone who is trying to do any squad behavior using influence maps. He presents a simple algorithm that can be used to identify some strategic dispositions in a map, (the front, the flanks and the rear), using the center of mass from the team. Its a good article, if you know what he is talking about, I wasnât very versed on the military so even the basic definitions like âWhat is actually a front?â appeared in my mind. It also focus on a two team scenario, which isnât exactly what my game is. Right now Iâm trying to emulate something similar to Majesty 2 and I notice playing the stage called âPretenders to the Throneâ that not only the game can have multiple teams, that even the monsters in the nature can attack each other! It was fun to watch a skeleton that came from the city graveyard to start to fight another skeleton that came from the North.
Both problems where somehow quickly solved after some research, and preparing on the code over the influence maps, but when I returned to implement the actual algorithm I couldnât understand exactly what they meant in some lines.
âAlgorithmically we might use something along the lines of the following to make these formation identifications:
1- Determine the center of mass of our units (i.e., the approximate location with the highest value as determined by the influence map).
2 - For every enemy unity we can see:
a. Select the unit that has the greatest "gradient" of influences betwheen the center of mass or our units and his. We arbritarily call that the front. There can only be one front.
b. If a given unit is within two squares of a unit belonging to the designated front, add it the front as well.
c. If a given unit is further than two squares from the front and has a gradient of influences less than that leading from the center of mass of our unit to the front, it is designeted as a flank unit. There can be several flanks.
d. If a given unit is within two squares of unit belonging to a designated flank, add it to the flank as well.
e. If the shortest path to a given unit from our center of mass runs through a square belonging or adjacent to a unit delegated to the front, that unit is designed as part of the enemyâs rear. There can be more than one rear.
f. If a given unit is within two squares of unit belonging to an area designated as the rear, add it to the rear as well.
3- Any unit that isnât allocated to one of the preceding groups (front, flank or rear) is treated independently and can be considered an individual unit. There can be any number of individualsNote that anytime we classify a given unit, we should move on to th next unit. Typically, one doesnât assign a unit to both flank and rear, for example.â
- Steven Woodcock, Wyrd Wyrks in âRecognizing Strategic Dispositions: Engaging the Enemyâ
The word gradient didnât meant anything to me after a week staring at the article. I know influence maps can be processed as images, since they are matrixes, yet that didnât rung any bell on my mind. I just stole the concept for center of mass and using that I built my own strategy and Utility AI using it. Its far from perfect, but at least is a starting point, is well isolated on the code if in the future I need to alter
First I will explain some basic concepts on my influence maps:
- Each agent âpowerâ is 1. The threat level is given by the agent memory. Every agent has an threat level depending on their power and events in the prior turns and shared story among agents. The healers and tanks will pull more aggro than a dps normally, but if an agent see someones she really HATES, he will focus on that as a target.
- The resulting influence in a cell is the team influence less all acumulated influence from all the other enemy teams. I prefer to have a fearful tank than a suicidal dps.
- My influence maps only considers agents that can fight back. For now we are not considering the possibility of towers or other kind of buildings targeting the units.
- The influence can spread for a range of 9 tiles, which is the maximum range of any skill inside the game
- The influence map will shrink or enlarge as the combat area expands, that is defined by the Combat Cluster size which is defined by how far/close the units are (the minimum size is 20 cells by 20, unless the window is placed near a corner of the map).
- The calculus for the influence map is not make every frame, so the agents will have the latest information, for now this is calculate every 2 seconds, for all 10 teams. I didnât do any stress test to determine how much this weights in cycles.
- The resulting influence map is only calculated if the team is active (meaning, thereâs active units actively in combat)
For the following board, the âAâ is an swordman, while the subscribed âAâ is a poring:

The influence map calculated is for the team with the swordman:

And the poring team:

The resulting influence map for the team with the swordman is:

When the combat brain tick for the swordmand agent starts it decides that he wants to engage with the poring. After that he will try to decide where is the best position for him to position in the map depending on the skill he selected to use. Thereâs some rules that will determine how much a cell âpullsâ an agent depending on the roles certain agent can perform:
- An agent will act more like a tank (wTank) if he sees that his team is being cornered, meaning that their team have less control over cells than the enemy team
- An agent will act more like a support (wSupp) if he sees that his team has lost a consideratable amount of health (and here we are considering even civilians!!! So even units that are outside combat oficially will be accounted for)
- An agent will prioritize to act as an ranged dps (wRDPS) if they arenât tanking or giving sup. (wRDPS = 1 - wTank - wSupp)
- An agent will be a meele dps (wMDPS) as the last resort:
- if a unit can be meele DPS and ranged DPS:
- wRDPS = (1 - wTank - wSupp) * 2/3
- wMDPS = (1 - wTank - wSupp) * 1/3
- else:
- wMDPS = wRDPS = 1 - wTank - wSupp
- if a unit can be meele DPS and ranged DPS:
Those values are literally weights, that will be multiplied if a cell is a valid choice.
After the weights are defined, select the highest value among all cells for:
- if a cell is occupied by a building, ignore it
- if the cell is out of the range of the selected skill the value will be inverse number of enemies multiplied the amount of roles of this unit (a negative number that is bigger than the max amount that a cell can have)
- For Tanks considers the following:
- Tanks desire to be near their aggro
- Tanks desires to position themselves between the major threat and their allies
- Tanks donât want to walk too much to position themselves Tanks desire to be at the border of the influence map (closer to zero on the influence map)(they normally are slower than other classes)
- For Supports consider:
- Supports desire to be near the center of mass of the team
- Supports desires to be close to the other members
- Supports desires to be away from their targets as much as they can
- Ranged DPS follows the same rules as the supports, so I just use the same value
- Melee DPS considers:
- Melee dps desires to be near their aggro
- Melee dps also desires to be at the border of the influence map, but they prefer to not be that exposed than tanks
- At the end we add and adjust by the weight of the role:
(tUtility = wTank* tankUtility+ wMDPS* meleeUtility+ wSupp* supUtility +wRDPS* rangedUtility)
The resulting map for the unit will look like the following:

Another example with agents (a support and another poring) almost aligned on the board:




At this end of this month, Iâm tired of seeing a black screen, with small numbers. I know I should proceed to start to modulate the actual threat of each enemy, the path finding, and I could actually modulate all the combat without the visuals, but Iâm tired. I just added OpenGL into the project and will do something minimal for visual debugging on the next stages. I got the famous black screen, and called it the day.
In other news, Iâm doing some textures while doing some meetings for OpenGameArt that are being well received by the community and I also plan to use on this project as soon as we start to have something more defined than a blocks:




