FAForever / fa

Lua code for FAF
228 stars 234 forks source link

AI - Mass raid platoon rework #4452

Open relent0r opened 1 year ago

relent0r commented 1 year ago

Describe the feature The default AI leverages a platoon function called GuardMarker for mass hunting. This request is for making the platoon function a little smarter when it comes to not running directly into enemy units.

After some previous discussion with Jip we thought that being able to have the platoons behavior be slightly different depending on the AI difficulty would be beneficial.

My first thought at an approach is to have a dedicated movement function that will avoid stronger enemy unit groups and focus on attacking enemy mass points over anything. I'll aim to keep as much of the existing logic as possible and focus on a smarter way to move to positions.

The main point of insertion will be this logic here.

                if not usedTransports then
                    local pathLength = table.getn(path)
                    for i=1, pathLength-1 do
                        if bAggroMove then
                            self:AggressiveMoveToLocation(path[i])
                        else
                            self:MoveToLocation(path[i], false)
                        end
                    end
                end

Rather than just queuing up the movement commands the platoon will manage itself while moving so that it can detect and avoid enemy units. How I've previously approached this.

The platoon will start a loop after each movement command which will run on a defined timer (this could be modified depending on difficulty or a minimum set for performance requirements). If enemy units are detected within a certain radius (again difficult or performance requirements) the platoon will compare its threat to the enemy units and make a decision on if it should avoid the enemy or attack them. There are a few ways we can do the attacking depending on the performance requirements. There are also different methods of performing the enemy unit query. IMAP vs GetNumUnitsAroundPoint.

The other part of the logic is what the units will do once they arrive at the location.

Because this is a multipurpose function rather than purely mass raiding some logic will need to be based on platoon data properties.

Additional context I've done this as an issue so that I can get feedback from others prior to setting to work on this feature. Though I'm also happy to just go for it and do the PR to see how it is received.

Garanas commented 1 year ago

It would be interesting to use a state-based AI for this, instead of having a complicated thread running on a loop. As a small example:

Which is a platoon of interceptors that by default patrol the base, unless the 'target' (that they will go out for to defend) is damaged by an air unit. They then linger around that unit before returning to base.

Long story short, the platoon function would then work via states. And those states can then be visualized for you (as a developer) to understand and test the situation. It would also create clear triggers as how the platoon can end up in a certain state. And we can make diagrams to visualize the state machine, to make it easier to understand.

It is what this video talks about:

Which is a bit lengthy, but alas 😄

Garanas commented 1 year ago

And another interesting feature of using a state machine: you can easily create new 'mechanics' that re-use the old logic, by creating a new class that only overrides one particular state. That way you can easily re-use logic, but have platoons act different upon certain triggers.

relent0r commented 1 year ago

Jip what sort of trigger do you think we would use for units that are moving towards a destination to make them avoid an enemy?

I think I get the concept of what this does. I don't totally understand how it remains in the PatrolBase state I'm assuming that its not actually staying in any code block its just because the IssuePatrol function is a forever thing so it doesn't need to do anything else until a state change happens.

For mass point raiding I think this would work well, at least we could implement for the simple land only cases. I'll definitely need your help on it. Things I'd want to identify. Minimum number of units in a platoon to trigger the platoon former? Currently its 3, but could/should be 1.

States. BuildingChain - Finding the best masspoint chain to attack. So a mass point group, or single etc. OnRoute - Moving to a masspoint Transporting - If a transport it needed for this location we'll need Loitering - At the maspoint location, look around and shoot any other extractors that are present Avoiding - enemy units are close to us, take evasion action or shoot them

Questioned to be answered. Would various units require other states. e.g scouts, mobile aa, arty, mml. Or we could limit it to just tanks/scouts to keep it simple. I'm not sure how to approach the transporting stuff. The default mechanics are designed for normal platoons.