Prototyping Fun – UE4 Multi-Tiered Tactical Search AI [Part 3]

Part 2

View post on

That is how I have the lower level (which I called “pleb” in this case) structured.  The service sends a request to the commander for a new destination.  A more optimal way to set this up would be to have it be a task instead of a service and have it add the lower level AI to an array on the commander’s end.  Whenever the commander discovers a new location to search, the commander would do a second EQS search using the array of waiting “plebs” as context for the search.  This would allow the closest pleb to be selected, and this would mean that the pleb wasn’t asking for a duty every 1 second or so.

View post on

This is the version of the commander tree that I discussed in earlier posts.  This one is OK for the most part, although the decision making for the data nodes could be improved slightly.  Perhaps pick a random data node that exists already, and check it for line of sight to any other data nodes would save the work load and allow for a much more robust scan.

To boost this further, you would need to track which nodes even have an eligible point somewhere in their pathing grid.  If they do not, remove them from the possible selections.

These are all untested hypotheticals, but if you wish to use this in a live project, I hope this helps in some way.

Prototyping Fun – UE4 Multi-Tiered Tactical Search AI [Part 2]

Shortcomings of Part 1’s system:

Part 1

#1: Over vast areas, this system begins to bog down.  Each EQS query is extremely expensive given the ever-increasing number of data nodes that are being used as context points.  If your EQS query favors close points, the system is able to generate many more points without struggling.  If it favors far away points, the system will begin lagging due to the massive quantity of nodes that the EQS queries are checking.

The difference in the results:

View post on

The above picture is what happens whenever you prefer short range locations.

View post on

The above picture is what happens whenever you prefer long range locations.  You get a much wider breadth of targets hit, but you also don’t search much of the town.

If you are willing to trade off some accuracy, I found that 1000 range with 250 distance between the points on the EQS’ pathing grid generator allows for many more data nodes to exist before the system starts bogging down.

I have not found an optimal solution to this problem at this stage.


#2: The trace on the EQS runs for infinity.  This can cause issues going between areas that are separated by large swaths of open land.


#3: It does not factor in distance from any AI agents.  If you are willing to factor in the distance from AI agents, you may be able to make it slightly more coordinated.

Part 3

Prototyping Fun – UE4 Multi-Tiered Tactical Search AI [Part 1]

Note: This system is a work in progress.  In part 2, I will discuss things that could be changed for a better result.

Goal: Create a multi-tiered AI that performs navmesh search operations distributed across many agents.

Description: For this system, I am trying to create an AI that would attempt to search every nook and cranny it could.  Once a location is checked, it should not be checked again.  This should create a systematic sweep of the entire area.

The AI should begin by using EQS to discover a location that  has not been searched yet, and then the AI should go to that location, search it, and repeat this process until nothing in range has not been searched.  The undiscovered point should be close to a discovered location.

The first step was to figure out the behavior I’m looking for.  In this case, I want…

  1. A location on the pathing grid
  2. A location that has not been seen yet
  3. A location that is close to the AI
  4. A pathable location.  That is to say that, while the roof of a house may be part of the pathing grid, it is not pathable because an agent cannot make it there.
  5. The areas to be searched are distributed among participating AI


This will be a 4 step EQS process.


#1: Set up a pathing grid generator in EQS.  I chose 1000 range with 100 distance between points.  There are some unfortunate situations where 1000 range with 100 distance between isn’t good enough.  Be careful when making this too large as we are going to be using the data nodes as context points, and you will have many of these in the world.

For the context, you will need to consider something if you choose to do this as well.  If you want this system to run in any situation with no prior setup, you will need to do a context check off of an existing actor.  If you are looking to do this without a preemptive Data Node, you will need to use the higher level controller (or one of the lower level soldiers) as the context to do the EQS check off of.

In my prototype, I placed a Data Node (mentioned in #2) where the higher level controller spawns at, and I set up a context that returns all BP_DataNodes in the level.


#2: I need to somehow keep track of all of the points the agents have visited.  For this, I created a Blueprint that I called BP_DataNode.  This Blueprint was originally supposed to contain data (hence the name), but it ironically stores no information now and is simply used as an indicator of the spots the AI has scouted.

For this step, I did a trace test.  I traced from the pathing grid node to the context (same context as last step), and I had bool match set to true, even though what I was checking was whether it was out of LoS or not.  This test is a simple “Filter Only” test.  Scoring does not matter, as I want to eliminate all of the visible nodes, not give +1 to the ones I can’t see.

#3: Now I did the distance check.  I used the same context as the previous two steps, and I measured the distance from the node to the context with a “filter and score”, although the filter portion was only set to a minimum of 0.0.  The scoring was set to an inverse linear system so that closer points were favored.

#4: Finally, I checked if a path existed.  If the node is unreachable, it should be discarded.  This is also a filter only result.  This test is optional depending on how the terrain is built.  In my case, there were rooftops that would appear on the pathing grid, but they were not reachable.

View post on

This is the EQS I used to scout for undiscovered locations.  The massive red downward arrow is pointing towards the initial data node (so that I could track where they spawned).  The querying mode isn’t that important for it, although I prefer 25% to create minor variance.

The next stage was to figure out how I was going to distribute the nodes to the lower level agents.  For this, I had the higher level AI perform the EQS, generate a node at the returned grid point, spawn a BP_DataNode, and add it to an array of nodes that have not yet been searched by an agent.  This particular decision was made so that they all have access to the same list, and the list is synchronized.

The low level AI is very simple.  It moves to its current target node.  When it arrives, it asks the higher level controller for the next node.  The low level AI has no decision making regarding which node it goes to.  All of that is handled through function requests sent by the lower level AI to the higher level AI.

Here is the end result:

View post on

The red arrows may seem clumped up, but the grey boxes are 4-room buildings to test functionality.  All of the red arrows point to data noes that are out of line of sight of all other data nodes, and the lower level agents are being sent to systematically check each of those points.

If there are any questions regarding this system, please don’t hesitate to ask in the comments.  While the comments do require approval, this is to prevent spam.

In the second post on this subject, I will detail the problems this setup has realizing the goal AI mentioned at the beginning of this post.

Part 2