sentrywiz
S
sentrywiz
How to make an AI for your map
NOTE
This tutorial assumes that you have an adept knowledge in the GUI part of the World Editor.You do not have to know JASS or any other code to read through this tutorial.
Everything here will be triggers, with very little script structure.
This tutorial will NOT be addressing common concepts and mechanics,
such as triggering loops, removing leaks or explaining in minor detail
where you can find the conditions and actions of the triggers.
This tutorial assumes you have this knowledge. If you do not, then this
tutorial may seem confusing to you. I suggest you obtain some knowledge
before reading, either via other tutorials or practice. Thank you
My Thoughts On AI
AI or Artificial Intelligence is something that in my opinion (IMO) should be present in every map.However each map is unique to itself and no AI would work the same for all maps.
I can understand that map devs usually just want to get their project alive,
get done with triggers or code and have a working map.
Unfortunately, to many devs the idea of an AI is great,
but many think of AI making as maybe a waste of effort, time and resources.
I think people believe AI is hard to make and requires complex coding or lots of huge triggers.
While some AI really has complex code structures behind it,
a basic functional AI is nothing complex and adds BIG BONUS to your map.
For one it will ensure that no matter what, your map can be played solo.
The experience will definately not be the same like you are playing with a real player.
I for one, am not a battle.net or a garena player and any map
that allows me to play alone with bots and doesn't take away from the
fun because its not a real player, is a lot of points in my book.
The best AI I have ever seen is the one in DOTA. No wonder I still play
dota with bots. They make the experience so fulfilling. But there are
many other maps like that. Castle Fight, Pudge Wars... all have a great
and exceptionally well made AI. And you can have that kind of AI, it will
take some resources and effort but it is really easy once your read
through this tutorial and understand how fun and easy can it be
for you to design your own AI for your maps.
AI Structure and Game States
This is the MEAT of the tutorial. It will
teach you the basic method and the template
that you use to shape the triggers.
Game States is a method of making your triggers.
With game states the AI making is simplified and you can easily adopt old and new
concepts into a slick and easy triggers or JASS code. What game states is about:
- Creating a 'state' for every action you want your AI to do
- Managing all 'states' via a control state, called the MAIN STATE
- Planning to avoid leaks and conflicts in your main state
- Realization of your main state conditions
All this means that when creating an AI for your map, you want to start your
template of the AI by first defining what your AI is supposed to be doing.
You can brainstorm this process with the actions you want your AI to do.
Basic actions can involve:
- Move, Attack, Patrol, Jungle, Gank, Buy Items, Cast Spells, Level Up, Assist Allies etc...
When you have your basic actions defined, you want to scour and see what you don't
want your AI to do. This is the opposite of the first brainstorming, and it can give you
a basic preparation for the problems your AI might face. It involves actions like:
- Not Waste Mana, Not Jungle, Not Buy Random Items, Not Initiate Fights First etc...
This adds to your process of creation. The basic actions give you a primary blueprint
to work with. The actions you don't want your AI to be doing add to the details of
your blueprint. It causes you to focus on great details that usually leads to a great AI.
Don't skip your don't actions process.
Now when you have your do's and dont's about your AI, its time to figure out your
control state or MAIN STATE. This is a state which will constantly monitor your AI and
give him commands regarding all decisions the AI is supposed to be doing. This will
be your bread and butter, because without it, your AI is as good as not working.
Usually this will be your main trigger or triggers which will compare all inputs for the
AI and cause them to react and decide in a great manner.
Your MAIN STATE should be composed of:
- Constant monitoring and comparrison (Every X Seconds)
- An array of conditions and actions (Multiple IF/ELSE)
The actions you brainstormed will be filling every nook and cranny of the IF/ELSE
conditions. This will lead the AI to have a valid response to most situations you
can think of. It will be able to do most things players do with great accuracy.
The MAIN STATE conditions have to be planned out carefully. Because if you
add many confusing conditions, the MAIN STATE will have no option but to
enforce the AI to make dumb decisions. So the more UNIQUE the condition is
the better your AI will be. If you make similar conditions between multiple
IF/ELSE's your AI will be confused and will often be stuck in infinite loops,
attempting to do both actions at the same time.
You will spend most of your time testing your MAIN STATE conditions.
As I said, this is your bread and butter and a key to an amazing AI.
Its up to you how much tweaking you will do and how UNIQUE and
clear your conditions will be.
The rest of this tutorial will be focused on examples and triggers.
I will attempt to do AI for different maps over time, so check
back on this tutorial to see if I have made it or leave questions.
I am more than happy to help you with ideas about your AI.
Example #1: Single Lane AoS (AI)
The map will be a short lane in which the AI will have to
go through lines of defences, level his skills, use them,
buy items when enough gold is acquired and will have
the option to go back to a base to heal when wounded.
This is how the map looks like:
The AI will take control over the Mountain King hero
which has the default spells: Storm Bolt, Thunder Clap,
Bash and Avatar.
The AI will have to retreat to this base when on low
health in order to replenish health, mana and possibly
buy items if it has enough gold.
The AI will move the Hero along the map and have a
progression scale, allowing the Hero to get level 6
before engaging into the final battle:
The AI will move up to this point at which the final
battle it will use all of its skills, use an item and win
the game by killing all neutral hostile units.
The AI Itself
This is the model the AI will be based upon:- MAIN STATE (Controls the other states and the survival of the AI)
- Move Attack (When the AI is at full health, it will move and attack)
- Back to Heal (When the AI is wounded, it will return to base)
- Use Spells Items (When the AI engages in combat, use spells and items)
- Level Up (When the AI levels up, decide which skills it will level)
- Buy Items (When the AI retreats to base, buy items)
With this in mind, we now have our model for triggering.
First is the main state, the heart of the AI operations.
-
MAIN STATE
-
Events
- Time - Every 1.00 seconds of game time
- Conditions
-
Actions
- Set AI_Group = (Units owned by Player 1 (Red) matching ((((Matching unit) is alive) Equal to True) and ((Unit-type of (Matching unit)) Equal to Mountain King)))
-
Unit Group - Pick every unit in AI_Group and do (Actions)
-
Loop - Actions
- -------- If Hero has less than 25% Health and is not Healing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Less than or equal to 25.00
- Healing Not equal to True
-
Then - Actions
- Trigger - Run Back to Heal <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
- -------- If Hero has 100% Health and is Healing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Equal to 100.00
- Healing Equal to True
-
Then - Actions
- Trigger - Run Move Attack <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
- -------- If Hero has more than 25% health and isn't healing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Greater than 25.00
- Healing Not equal to True
-
Then - Actions
- Trigger - Run Move Attack <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
-
Loop - Actions
- Custom script: call DestroyGroup ( udg_AI_Group )
-
Events
of triggers, but this is what our control state looks like.
- Time - Every 1.00 seconds of game time
- Set AI_Group = (Units owned by Player 1 (Red) matching ((((Matching unit) is alive) Equal to True) and ((Unit-type of (Matching unit)) Equal to Mountain King)))
-
Unit Group - Pick every unit in AI_Group and do (Actions)
-
Loop - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Less than or equal to 25.00
- Healing Not equal to True
-
Then - Actions
- Trigger - Run Back to Heal <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Loop - Actions
depict a condition that the AI is healing in base. We then make our
IF/ELSE by saying that if the Hero isn't healing, which means he is
not in base AND his total health is less than 25%, initiate state
BACK TO HEAL.
-
Back to Heal
- Events
- Conditions
-
Actions
- Set Healing = True
- Set AI_Loc = (Position of Fountain of Health 0000 <gen>)
- Unit - Order (Picked unit) to Move To AI_Loc
- Custom script: call RemoveLocation ( udg_AI_Loc )
var to true, set the location of the fountain, move the Hero
back to base and remove the location to avoid leaks. As you
can see, there are no events and conditions, so this state can
only be called from the main state. It will not run on its own
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Equal to 100.00
- Healing Equal to True
-
Then - Actions
- Trigger - Run Move Attack <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
If the Hero's total health is at 100% and the Healing var is true,
then we run the MOVE ATTACK state.
-
Move Attack
- Events
- Conditions
-
Actions
- Set Healing = False
- Set AI_Loc = (Center of Attack Region <gen>)
- Unit - Order (Picked unit) to Attack-Move To AI_Loc
- Custom script: call RemoveLocation ( udg_AI_Loc )
sets the location of the region where our Hero needs to go,
issues a move-attack order and removes the location.
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Greater than 25.00
- Healing Not equal to True
-
Then - Actions
- Trigger - Run Move Attack <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
when the health of the Hero is more than 25% and the
Healing var is set to false. If both are true, then we call our
MOVE ATTACK state again.
- Custom script: call DestroyGroup ( udg_AI_Group )
Now let's explain all we have read so far. The MAIN STATE
has 3 IF/ELSE conditions. One checks if the Hero is at
25% or less health and isn't healing. If yes, it sends it back
to base to heal. The second IF/ELSE checks if the Hero is
at base healing and if its health is 100% and sends it back
fighting if true.
The third IF/ELSE is ment if the AI has finished
killing a wave of defences but it still has more than 25% health.
In which case the AI will be stuck there, doing nothing until it can
regenerate back to full health and the second IF/ELSE can be run
again. The third IF/ELSE pushes the AI to fight until it has 25%
or less health, in which case it sends it back to base to heal.
-
Level Up
-
Events
- Unit - A unit Gains a level
-
Conditions
- (Unit-type of (Leveling Hero)) Equal to Mountain King
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
Or - Any (Conditions) are true
-
Conditions
- (Level of (Leveling Hero)) Equal to 3
- (Level of (Leveling Hero)) Equal to 5
-
Conditions
-
Or - Any (Conditions) are true
-
Then - Actions
- Hero - Learn skill for (Leveling Hero): Storm Bolt (Hero)
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
Or - Any (Conditions) are true
-
Conditions
- (Level of (Leveling Hero)) Equal to 2
- (Level of (Leveling Hero)) Equal to 8
- (Level of (Leveling Hero)) Equal to 10
-
Conditions
-
Or - Any (Conditions) are true
-
Then - Actions
- Hero - Learn skill for (Leveling Hero): Thunder Clap
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
Or - Any (Conditions) are true
-
Conditions
- (Level of (Leveling Hero)) Equal to 4
- (Level of (Leveling Hero)) Equal to 7
- (Level of (Leveling Hero)) Equal to 9
-
Conditions
-
Or - Any (Conditions) are true
-
Then - Actions
- Hero - Learn skill for (Leveling Hero): Bash
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of (Leveling Hero)) Equal to 6
-
Then - Actions
- Hero - Learn skill for (Leveling Hero): Avatar
- Else - Actions
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Events
Because we have the freedom and we know what skills
the Hero has, we can therefor set at which level does the AI
take a specific skill.
-
Use Spells Items
-
Events
- Unit - A unit Is attacked
-
Conditions
- (Unit-type of (Attacking unit)) Equal to Mountain King
- (Percentage life of (Attacking unit)) Greater than 25.00
-
Actions
- Set Hero_Loc = (Position of (Attacking unit))
- Set Enemies_Around = (Units within 250.00 of Hero_Loc matching ((((Matching unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True) and (((Matching unit) is alive) Equal to True)))
- -------- If Hero has Scroll, use it at the start of the fight --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- ((Attacking unit) has an item of type Scroll of Protection) Equal to True
-
Then - Actions
- Hero - Order (Attacking unit) to use (Item carried by (Attacking unit) of type Scroll of Protection)
- Else - Actions
-
If - Conditions
- -------- We use Storm Bolt as a finisher, when the enemy has 100 * Level health remaining --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of Storm Bolt (Hero) for (Attacking unit)) Greater than 0
- (Mana of (Attacking unit)) Greater than or equal to 75.00
- (Life of (Attacked unit)) Less than or equal to (Real(((Level of Storm Bolt (Hero) for (Attacking unit)) x 100)))
-
Then - Actions
- Unit - Order (Attacking unit) to Human Mountain King - Storm Bolt (Attacked unit)
- Else - Actions
-
If - Conditions
- -------- We use Thunder Clap only when there are more than 1 enemy at 250 range around the Hero --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of Thunder Clap for (Attacking unit)) Greater than 0
- (Percentage mana of (Attacking unit)) Greater than or equal to 50.00
- (Number of units in Enemies_Around) Greater than 1
-
Then - Actions
- Unit - Order (Attacking unit) to Human Mountain King - Thunder Clap
- Else - Actions
-
If - Conditions
- -------- We use Avatar when the hero's health is less than 50% --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of Avatar for (Attacking unit)) Greater than 0
- (Mana of (Attacking unit)) Greater than or equal to 150.00
- (Percentage life of (Attacking unit)) Less than or equal to 50.00
-
Then - Actions
- Unit - Order (Attacking unit) to Human Mountain King - Activate Avatar
- Else - Actions
-
If - Conditions
- Custom script: call DestroyGroup ( udg_Enemies_Around )
- Custom script: call RemoveLocation ( udg_Hero_Loc )
-
Events
and use spells with very specific conditions. We will look at this
bit by bit. Let's start with the basics:
-
Use Spells Items
-
Events
- Unit - A unit Is attacked
-
Conditions
- (Unit-type of (Attacking unit)) Equal to Mountain King
- (Percentage life of (Attacking unit)) Greater than 25.00
-
Events
Since the Hero will encounter enemies that will attack it, this
is when it will decide on the use of spells. Also since this state
isn't controlled via the MAIN STATE, it will run on its own so we
have to define that if the Hero's health is lower than 25%, the
entire state is skipped even if the Hero is attacked.
-
Use Spells Items
-
Actions
- Set Hero_Loc = (Position of (Attacking unit))
- Set Enemies_Around = (Units within 250.00 of Hero_Loc matching ((((Matching unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True) and (((Matching unit) is alive) Equal to True)))
-
Actions
And a Enemies_Around unit group that will see if there are
units at 250 range around the position of the Hero. This is necessary
for our Thunder Clap spell and will be explained shortly.
-
Use Spells Items
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- ((Attacking unit) has an item of type Scroll of Protection) Equal to True
-
Then - Actions
- Hero - Order (Attacking unit) to use (Item carried by (Attacking unit) of type Scroll of Protection)
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Scroll of Protection. If it does, it uses it.
-
Use Spells Items
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of Storm Bolt (Hero) for (Attacking unit)) Greater than 0
- (Mana of (Attacking unit)) Greater than or equal to 75.00
- (Life of (Attacked unit)) Less than or equal to (Real(((Level of Storm Bolt (Hero) for (Attacking unit)) x 100)))
-
Then - Actions
- Unit - Order (Attacking unit) to Human Mountain King - Storm Bolt (Attacked unit)
- Else - Actions
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
damage. Let's say that we want the AI to preserve mana and use
the Storm Bolt as a finisher, to kill off the wounded enemy. This means
it has to know when to cast it.
The IF/ELSE checks if the Hero's mana is 75 or greater, sees if the level
of Storm Bolt is at least one and checks if the unit attacking
our Hero has health less or equal to 100 * Level of Storm Bolt. If yes, a Storm Bolt is cast
-
Use Spells Items
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of Thunder Clap for (Attacking unit)) Greater than 0
- (Percentage mana of (Attacking unit)) Greater than or equal to 50.00
- (Number of units in Enemies_Around) Greater than 1
-
Then - Actions
- Unit - Order (Attacking unit) to Human Mountain King - Thunder Clap
- Else - Actions
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Let's say we want our AI to only cast Thunder Clap when it has
at least 2 enemies at 250 range around it. This will ensure our
spell gets a good value from being used. And let's also say that
since we want our AI to cast as many Storm Bolts as possible
without spending too much mana on Thunder Clap.
Since our Thunder Clap deals less damage and costs 90 mana
this means we need the AI to make a good decision of when
to use it and when not to. This is where our variables come into
play.
Our Enemies_Around group checks for all enemy units at 250
range around our Hero_Loc position. So we check if the number
of units is 2 or more and we check if the mana of the Hero is
atleast 50% or more. This saves mana for our Storm Bolts and
only uses Thunder Clap in good situations and when the Hero
has excess mana.
-
Use Spells Items
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Level of Avatar for (Attacking unit)) Greater than 0
- (Mana of (Attacking unit)) Greater than or equal to 150.00
- (Percentage life of (Attacking unit)) Less than or equal to 50.00
-
Then - Actions
- Unit - Order (Attacking unit) to Human Mountain King - Activate Avatar
- Else - Actions
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Since Avatar gives bonus hitpoints, armor and damage and
spell immunity, we can use it as a weird heal our hero can have.
For this example, I set Avatar to be cast when the Hero has
150 mana or more and when it is at 50% or less health. This
makes Avatar be used more as a heal and less as a buff.
-
Use Spells Items
- Custom script: call DestroyGroup ( udg_Enemies_Around )
- Custom script: call RemoveLocation ( udg_Hero_Loc )
checking, avoiding leaks.
-
Init
-
Events
- Map initialization
- Conditions
-
Actions
- Trigger - Turn off (This trigger)
- Hero - Learn skill for Mountain King 0017 <gen>: Storm Bolt (Hero)
- Set Healing = False
- Set AI_Loc = (Center of Attack Region <gen>)
- Unit - Order Mountain King 0017 <gen> to Attack-Move To AI_Loc
- Custom script: call RemoveLocation ( udg_AI_Loc )
-
Events
skill for our Hero to be Storm Bolt. And since the states become
active once the Hero starts fighting and going back to base, the
INIT trigger launches the Hero into battle. This trigger only runs
once, at the start of the game. Its just for testing purposes
Also, if you are interested in a MUI Solution to these triggers
because there were made for a single unit in mind, here is an
actual solution. Basically its just changing the Healing var to
an Array and changing the main AI_Group so it can pick
multiple heroes instead of one. Do bare in mind that the
only hero in the triggers is Mountain King, if you want more
heroes you will have to do the spells and level up triggers for
them as well.
-
MAIN STATE MUI
-
Events
- Time - Every 1.00 seconds of game time
- Conditions
-
Actions
- Set AI_Group = (Units in (Playable map area) matching ((((Matching unit) is A Hero) Equal to True) and ((((Matching player) controller) Equal to Computer) and ((Owner of (Matching unit)) Not equal to Neutral Hostile))))
-
Unit Group - Pick every unit in AI_Group and do (Actions)
-
Loop - Actions
- -------- If Hero has less than 25% Health and is not Healing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Less than or equal to 25.00
- Healing_MUI[(Player number of (Owner of (Picked unit)))] Not equal to True
-
Then - Actions
- Trigger - Run Back to Heal <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
- -------- If Hero has 100% Health and is Healing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Equal to 100.00
- Healing_MUI[(Player number of (Owner of (Picked unit)))] Equal to True
-
Then - Actions
- Trigger - Run Move Attack <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
- -------- If Hero has more than 25% health and isn't healing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Percentage life of (Picked unit)) Greater than 25.00
- Healing_MUI[(Player number of (Owner of (Picked unit)))] Not equal to True
-
Then - Actions
- Trigger - Run Move Attack <gen> (ignoring conditions)
- Else - Actions
-
If - Conditions
-
Loop - Actions
- Custom script: call DestroyGroup ( udg_AI_Group )
-
Events
-
Move Attack MUI
- Events
- Conditions
-
Actions
- Set Healing_MUI[(Player number of (Owner of (Picked unit)))] = False
- Set AI_Loc = (Center of Attack Region <gen>)
- Unit - Order (Picked unit) to Attack-Move To AI_Loc
- Custom script: call RemoveLocation ( udg_AI_Loc )
-
Back to Heal MUI
- Events
- Conditions
-
Actions
- Set Healing_MUI[(Player number of (Owner of (Picked unit)))] = True
- Set AI_Loc = (Position of Fountain of Health 0000 <gen>)
- Unit - Order (Picked unit) to Move To AI_Loc
- Custom script: call RemoveLocation ( udg_AI_Loc )
Summary -- Last Words
I conclude this tutorial with the hope that you sawthat making an AI can be a fun process.
Its a matter of you thinking about the states you
want your AI to do. The above provides you with a
template that you can base your own ideas on.
Its important to understand that every action
that you think the AI can do can be upgraded as
a state and used by a control state. You don't need
lots of huge triggers, just smart IF/ELSE and all the
game states you want.
View attachment AI Tutorial sentry.w3x
Last edited by a moderator: