This is an extensive and detailed guide setting up or debugging AI of units in The Hand of Merlin, написано его игровым дизайнером ковриком.
Введение
В этом руководстве, я’d like to walk you through the creation of an AI, which can make an enemy unit use their skills on their own, against your warband.
How does AI work in The Hand of Merlin?
Our programmers chose to use the Utility AI paradigm. Это означает, простыми словами, that for every ability we let our AI consider, это’ll try to rank the “полезность” value of its casting in every single tile it can cast, and then compare all options, picking the one with the highest utility value. Это’s a great way to consider multiple options at once.
Specifically in our case, каждый “Unit Class” has its own “Мозг”, where we’ll describe options and the questions the AI makes to each target tile.
If that isn’t clear yet, дон’не волнуйся, позволять’s go step by step.
Unit Brains
Прежде всего, we have to create a Мозг. A great way to do it is via the Create Menu (Ctrl+n), а затем выбрав Generic -> (merlin) AI brain params.
Альтернативно, if you already have a Unit Class file, you can create a new Brain directly on that file, and then open it separately.
В любом случае, the result is a blank Brain file, как этот:
Be sure to save that puppy (we use the Content\Merlin\AI\UnitBrains folder).
Note that there’s not a lot going on here, as we still have to fill in the Ability Considerations, но там’s already something called a Unit Priority. я’ll take this chance to explain what Priority is.
Это, хорошо, наш “Утилита” value for each action. During an enemy turn, since our game uses Side Initiative, all possible actions from all possible units will be ranked in how high their priority is, и они’ll be played in that order, as long as there are available abilities. Как мы’ll see shortly, the Ability considerations are the heavy lifters here, but if you ever want a unit to consistently play first or last, you might want to play with the Unit Priority, as this will multiply the priority/utility of everything that that specific brain calculates.
For an example on how that works, Бегемот has a priority of 3, и Чернокнижник (Support bandit) имеет 0.5. This usually makes the Behemoth play first, and the warlock after all other units.
Consideration Sets
Сейчас, позволять’s look at the Ability Consideration Sets. Здесь, you should have at least one for every ability the unit has, but some abilities (like Run!) can have multiple entries.
Think of each Consideration Set as a question your AI can ask. В примере ниже, “If I am going to use Shoot, how should I use it, and is it more important than other abilities?”
Each consideration has 4 характеристики:
- А Этикетка is for internal use only. Helps you identify them from afar, and will come in handy when we talk about debugging. Это’s like a name for that set.
- The Способность is where you list the ability this is in relation to. If the ability is not enabled for any reason (the unit doesn’t have it, it’s on cooldown, or it takes more AP than the unit currently has), this set won’t be triggered.
- У вас есть Приоритет to associate with the ability, which is modulated by the Unit Priority and the …
- Decision Maker, which is the actual calculation the AI does with that ability to each possible tile. Note how it actually is a file type on its own, so it’s a modular piece.
Decision Makers and Scorers
Найден в Content/Merlin/AI/Behaviours папка, and always named with a `Behavior_` prefix, these are the building blocks of the AI. Технически, you can mix and match between those, but I recommend creating your own Decision Makers, especially if you have a specific behavioral pattern in mind.
Each Decision Maker is nothing more than a combination of Scorers, that take the priority of the ability and multiply it by some value. На картинке выше, you can see that the Behavior_OverwatchDefensive decision maker, associated with Mandrake’с Prepare Shot способность, имеет 3 scorers:
- Gate_NoOverwatchAlly, which sets the priority to 0 если там’s an ally of Mandrake’s that is already preparing a shot;
- Gate_CanHitRangedAnyone, which will set the priority to 0 if the unit cannot find a target to hit (то есть. это’ll never use overwatch if there is no one in range, likely preferring to just walk up)
- Score_DefensiveRating, which makes the priority lower if the current tile is a bit too in the open, making the Mandrake prefer to use Prepare Shot only if its behind cover (мы’ll talk more about Defensive rating in a sec, дон’не волнуйся).
Note how they have a specific naming convention. All of these scorers, найден в Content/Merlin/AI/Considerations, have one of three suffixes: Ворота can set a priority to 0 или 1, almost like a boolean. Счет tend to be more subtle, начиная от 0 к 1, и Бонус может иметь только 1+ ценности, making something MORE likely. This is just my personal conventions though, and you can feel free to name them whatever you prefer.
To dive a bit deeper, Позволять’s take a look at how Gate_NoOverwatch Ally работает:
Прежде всего, it’s of the type “Has status effect”, which is kind of the category of question. Мы’ll list all the questions and their base properties in a sec. Так, we have to qualify the question. “ВОЗ” имеет “который” эффект статуса. The “ВОЗ” here is the Units of Interest. I can set it up to search for all sorts of units, like those inside an area, those with a specific health ratio, those with specifics relations, и т. д..
В этом случае, мы’re searching for all allies, so we put All Units in the unit group, and we apply the relation filter, с Друг фильтр.
Затем, which status effect? We could use a category (positive/negative/marker/hidden), but for this case, I just wanted to know who has the `Overwatch.rsc` status effect. И вот ты идешь.
Так, тот Отвечать to this question will be a number of units that are my allies that also have the listed status effect. This will be plotted as the X value in the Graph entry.
To check out this graph in a more visual way, I suggest clicking on the the graph button, здесь
Which grants you this visual over here:
As we said, the X axis is the “отвечать” to the consideration’s question. The Y axis, однако, is whatever we decide should multiply the Приоритет given a X value. В примере выше, if the X is 0 (there are no allies with the Overwatch status effect), then we’ll multiply the priority by 1. Если, однако, есть 1 or more allies with the status effect, then we multiply the priority by 0, cancelling the entire operation – Mandrake will not use Prepare Shot.
Отсюда и название – это Ворота to see if there are allies with the Овервотч эффект!
All Scorers work in this same way, providing you with an X for you to decide what the Y should be. Здесь’s a quick rundown of all the types, so you know what to look for. Кстати, questions that are “Yes/no” result in 1 for yes, 0 for no, как и ожидалось.
Обратите внимание, что Offensive Rating и Defensive Rating are left for last, since they are a bit special.
Gate Types
- Units Count in Cast area at Target: “If I aim an ability at a specific tile, what units will the target area of this ability find there?” Great for checking the effectiveness of AoE.
- Number of Interesting Units: “How many units are there of this type?” A more generic way of searching for units. Maybe your behavior is different if your unit is the last one standing?
- Hit Chance: “how likely an ability is to hit a specific target?”. Most ranged units will avoid taking shots against targets in cover!
- AP cost to use this ability: “what does this ability cost if I target this tile?” Useful if your ability can scale off AP, like Run.
- Min Walk distance from target tile: “Starting from the target tile, что’s the minimum distance to a unit of interest?” This is useful for movement abilities, to keep other units at a reasonable distance. Cockatrices use this to get close to allies, например.
- Min Walk Distance to target tile: “From here I am standing, how far is my target tile?” This works well if your unit wants to minimize/maximize traveling distance. Redcaps love walking around units, and this is what you use for that.
- Air Distance: Works exactly like Walk Distance, но не’t consider covers and other movement blockers. It’s a straight line, and uses diagonals well. Better for “proximity” checks, like Mandrake’s preference to shoot nearby units.
- Single Target X Percent/Amount: “At this target tile, если там’s a unit, how much Armor/Health/Life does it have?” Здесь, Life stands for adding both Health and Armor. This is a good one if your enemies prefer wounded targets, or if they have armor-wrecking skills, they might prefer higher armored foes! Percent puts it in a 0-1 соотношение, and Amount gives you the flat value.
- Has Status Effect: “Does my units of interest have a status effect?” We talked about this one before, but it works well for more complex behaviors if you use hidden status effects!
- Status Effect Stack Count: “How many stacks of the status effect do they have?” Мы не’t use this one, but it would work well for some “ярость”-type effects, верно?
- Can Caster Activate Ability?: “Can I use this other ability?” Good for checking if your ability is out of cooldown before you do something. Our Rogue bandit checks if their Shiv ability is cleared before it Sprints close, в качестве примера.
- Turn Type of Caster: “What kind of turn is this?” Hopefully the X is self-explanatory here. This gives you a different result if this is the turn the unit was revealed, or if it is a reaction, like those granted by Redcap’s Watchful.
- Blackboard Query: “What information is out there regarding ability use?” this allows you to query which abilities have been used recently. Will help you sort out combos and similar actions!
- Caster Action Points: “how many Action Points I have?” If you want to prefer to do some actions at a specific action point count, Это вам!
- Defensive Rating: “How safe is the target tile?” This is an interesting one. The AI tries to estimate how defended a tile is considering all enemies and their ranges. Having this consideration associated with your movement ability makes enemies more careful, and favor covers, depending on how you set your graph. И да – the AI can even see what class each enemy is, and doesn’t care about getting cover against Warriors!
- Offensive Rating: “How good of a shot do I have at my foes from the target tile?” This allows the unit to rank how many enemies it can hit from the target tile. Higher X in tiles where multiple enemies can be hit without cover – add this to get better flanking behavior!
The combination of these last two can do wonders for the “личность” of your AI. Work a good graph to balance between “оборонительный” и “offensive play!
Обратите внимание: если твой movement ability determines that the current tile is the best possible tile, the unit will just stay put and pass a turn.
Отладка
Small parting note, to help your testing out. When you are messing with new enemies in your tests, есть Console Command that can give you some information about the end result of your queries.
Чтобы использовать его, when you are running a simulation, нажмите кнопку tilde key and type
hom_dbg_bEnableAIDebugging = 1
This will make it so that when the AI starts to consider their first turn, they actually print to the screen all actions with >0 end priority. Когда вы закончите, set the same variable to 0.
С этим, I can see that he could’ve used Ooze Run, взгляд, Corrupt, and Far Run, but Gaze wont out by a landslide, also noted by the red yellow line. Just right click to step through the process of every action, а ты’ll see how your configuration ended up working!
Вот и все! Go forth and have some fun creating new brains for your units!
Это все, чем мы делимся сегодня для этого. Рука Мерлина гид. Это руководство было первоначально создано и написано Мибс. На случай, если нам не удастся обновить это руководство, вы можете найти последнее обновление, следуя этому связь.