January 9, 2018 at 22:29 #22620
In my game, AI units have access to several different skills and weapons. Its obvious that each weapon/skill should have its own scorer/targeting function (e.g. dagger attacks nearest enemy, heal will heal nearest ally, etc.), but I am at a loss as to how exactly I should implement this using Utility AI, considering these weapon/skill combinations can change in real-time. This seems like it should be a trivial task, it is a common use-case, but nonetheless the solution eludes me.
What seems easiest to do is to check the agent’s inventory for equipped weapons and skills, and then generate the AI tree in realtime from a library of weapon/skill AI scorers, however it is not very clear given the documentation available how I might accomplish this. Also, this solution might hinder performance, since (I assume) single instance AI’s would no longer shared amongst agents.
Alternatively, I could have a giant tree which evaluates every single weapon and skill scorer in the game, but first checks each weapon/skill scorer to see if the agent is actually wielding it. This option carries a bit of ‘code smell’, and could potentially become very unwieldy even with the editor provided, especially if a single weapon is capable of performing multiple different actions depending on different circumstances (e.g. “Reload Gun” and “Fire Gun” in the SurvivalShooter example).
I would probably be fine with the above solution if I could ‘wrap’ multiple qualifier/action pairs (i.e. a Selector) into a single qualifier. For example, wrap “Reload Gun” and “Fire Gun” into a single qualifier “Use Gun”. “Use Gun” would evaluate its child qualifiers, and return the score of the highest child qualifier. If that score is chosen by the parent selector, then the “UseGun” qualifier would execute the action of the proper child. It isn’t clear given the documentation provided how I might implement this. I see you can set the ‘action’ property of the QualifierBase class, but I am unsure how to use the editor to hook up this ‘SelectorQualifier’ class. All this being said, I can’t shake the feeling that I’m just trying to do things in the wrong manner.
Any help would be appreciated. Thanks!January 10, 2018 at 10:41 #22622
Thanks for your post.
First, I need to state that there are usually numerous ways to solve such a situation. The exact right solution sometimes take experimentation and actual in-game tests.
That being said, it sounds to me like you are overcomplicating the situation. As you start by stating, each weapon or skill should have its own scorer(s), leading to an action. Scorers can be reusable (e.g. HasHealth above or below X), and you can combine multiple scorers easily in the editor.
You probably do not need to write your own qualifiers at all. Most likely, you will just need to write scorers (IContextualScorer and IOptionScorer). The provided qualifiers usually suffice, e.g. “Sum of Children” and “All or Nothing” are the ones that I most commonly use.
If you find that certain weapons have more complex behaviours, e.g. Reload and Fire for a gun, you can – as you state – wrap this up in its own action. E.g. the “Use Gun” action checks for ammo, if none, then reloads first, otherwise just fires. Alternatively, you can visualize this in the AI as well. I recommend using “Sub AIs” (with AI Links) to hide the complexity and to facilitate having small, easily maintainable AI assets that form a more sophisticated network together.
Doing this would however require you to implement the needed scorers and set up AI nodes for each weapon/skill (or at least the ‘type’ of weapon/skill, if some can be treated equally). I do think this is preferable though, since everything is visual and easily tweakable through the editor. Breaking the AI up into smaller sub AIs will avoid having a huge, confusing AI tree.
Actually doing dynamic instantiation of AI nodes within an AI asset is not recommend. Dynamically adding or removing AI assets to an AI agent is fine though, if that helps your use-case.March 19, 2018 at 13:18 #22916
Ok, here’s the problem, but a bit more straightforward:
Lets say you have a game that has 400 unique guns. Each gun requires a unique scorer based on things like how effective it is at a given range. You can equip each of your troops with up to three different guns.
How do you design the AI to decide which of the three equipped guns to choose using the Apex Editor?
It seems quite unwieldy to have the associated scorer for all 400 guns in a single AI object, especially considering the fact that on each iteration, all 400 scorers will be evaluated even though only 3 are equipped and usable.
It would be much clearer, maintainable, and run-time efficient if one were able to build an AI selector out of equipped guns during run-time. I recognize that this would incur a memory cost (instead of having just one AI object for all actors, it would require a unique AI object instance for each actor), but for a closed source asset as expensive as this one, I would expect the tool to allow for that functionality if desired.
Again, I’m at a loss at how to proceed with this tool, and it is frustrating as this feels like a trivial problem.March 19, 2018 at 14:03 #22920
Thanks for posting again.
I hope I understand your situation correctly.
Your game has 400 guns in total. Each AI agent carries 3 guns. Each AI agent must at any time decide which of the 3 guns it wants to have equipped currently.
Assuming I understood correctly, I can see several solutions to this situation using Apex Utility AI.
The easiest and in my opinion most efficient solution would be to utilize the ActionWithOptions. This assumes that you can represent all guns using a common type (e.g. a common base class or interface). Then, you write an ActionWithOptions that takes the common gun type, along with a number of Option Scorers (IOptionScorer) that scores the common gun type based on what parameter is relevant, e.g. distance to target compared to range capability of the gun, etc.
Then, your AI asset is very simple. You just have the ActionWithOptions, e.g. ‘ChooseGun’ on a node in the AI and then tweak the OptionScorer setup until you get the result you want.
A simple but powerful solution for a trivial problem.March 27, 2018 at 07:00 #22993
That helps a bit. I think I’ll be able to abstract out the different types of abilities so that I can have an AI choose one depending on the circumstances, then add an ability-specific AI dynamically to handle runtime tactical decisions.
However, I’m running into another problem: Is there a clean way to combine AI Scorers like is suggested in this video at the 23 minute mark?
In Apex Utility AI Editor, if I have a Selector composed of Attack, Reload, Heal, and TakeCover qualifiers, is there a clean way to make the TakeCover qualifier receive and modify the scores of the Reload and Heal qualifiers to provide is own unique value (like in the video)?
I know I could accomplish it by having the reload and heal qualifiers write their scores to the context’s memory, but this solution ends up being quite cumbersome and difficult to enforce validation.March 27, 2018 at 10:15 #22996
My suggestion would be to either precompute the scores to the context as you suggest, if not from the qualifiers then from an action in a CompositeAction which computes and writes the relevant scores (e.g. ReloadScore, HealScore, ThreatScore) to the context – ContextualScorers can then simply return that score, possibly together with a multiplication factor.
Another option is to possibly compute the values more than once. Each qualifier can hold any number of contextual scorers, so your TakeCover qualifier can be composed of both the Reload and Heal ContextualScorers – this means more computations but may be simpler to manage.March 29, 2018 at 00:27 #23009
Alright, one last question (more of a request)
I’m going to be using more than one IAIContext in my game. It would be very nice if I could define for each AI which kinds of IAIContext it expects, so that the editor can narrow down possible actions/scorers to only those which implement the chosen IAIContext. As it stands, it is all too easy for for a designer who only works with the AIEditor to add actions to an AI which are expecting a different kind of context.April 3, 2018 at 10:19 #23027
Thanks for the suggestion. I wholeheartedly agree that what you are describing is a desirable feature. Unfortunately, it has proven non-trivial to implement such a feature and thus I cannot say when or even if it will get implemented.
What I do in those situations is typically to prefix actions and scorers with a few letters to tell me/the AI designer what is usable. E.g. “NZ1_Shoot”, “NZ1_Heal” and “GM2_Shoot” and “GM2_Reload”.
You must be logged in to reply to this topic.