Digging into and improving BVR AI
-
I’ve been researching realistic BVR tactics these years.
My research is summarized below:
https://docs.google.com/document/d/1DKxkrI7vi0W4fuXPRrMhvBxJDxbBSI0SbWlbohdqjrY/editI found BMS AI tactics might be too aggressive that they are risking their lives too much to kill the target.
It’s not following USAF AFTTP standards that much and its ALR(Acceptable Level of Risk) sounds always “EXTREME”I was digging around the Sim folder of the theater and found several tweaks we can make…
I’ll explain here what I found, but also needs someone’s help.The first one I found is
Sim\Acdata\BRAIN\mnvrdata.dat
This file has comments at the beginning.
A# # # enum ACMnverClass { # MnvrClassF4, // Combat Class 0 in ACD DATA File # MnvrClassF5, // Combat Class 1 in ACD DATA File # MnvrClassBomber, // Combat Class 2 in ACD DATA File # MnvrClassF15, // Combat Class 3 in ACD DATA File # MnvrClassF16, // Combat Class 4 in ACD DATA File # MnvrClassMig25, // Combat Class 5 in ACD DATA File # MnvrClassMig27, // Combat Class 6 in ACD DATA File # MnvrClassIgnored, // Combat Class 7 in ACD DATA File. Ignored by AI # MnvrClassUnused, // Combat Class 8 in ACD DATA File. Ignored by AI # NumMnvrClasses // Means there are 9 combat classes # }; # # enum ACMnverClassFlags # { # CanLevelTurn = 0x1, # CanSlice = 0x2, # CanUseVertical = 0x4, # CanOneCircle = 0x10, # CanTwoCircle = 0x20, # CanJinkSnake = 0x100, # CanJinkLoaded = 0x200, # CanJinkUnloaded = 0x400 # }; # # enum BVRInterceptType { # BvrSingleSideOffset, // 1 in this file # BvrPince, // 2 in this file # BvrPursuit, // 3 in this file # BvrNoIntercept, // 4 in this file # NumInterceptTypes # }; # # enum WVRMergeManeuverType { # WvrMergeHitAndRun, // 1 in this file # WvrMergeLimited, // 2 in this file # WvrMergeUnlimited, // 3 in this file # NumWVRMergeMnverTypes # }; # # enum SpikeReactionType { # SpikeReactNone, // 1 in this file # SpikeReactECM, // 2 in this file # SpikeReactBeam, // 3 in this file # SpikeReactDrag, // 4 in this file # NumSpikeReactionTypes # }; # # /*------------*/ # /* AC Element */ # /*------------*/ # typedef struct # { # BVRInterceptType* intercept; # WVRMergeManeuverType* merge; # SpikeReactionType* spikeReact; # char numIntercepts; # char numMerges; # char numReacts; # } ManeuverChoiceTable; # #
Variable definitions follow like:
# F16 Manuever Class Flags 0x737
F16 v F16
Num intercepts
2
Num Merges
2
Num Spike React
2
Intercept Types
1 2
Merges
2 3
Spike Reacts
2 3
Let me explain in detail: **The maneuver class flag** This is 3 digits number in Hex(I believe) defines how aircraft can maneuver. Seems by editing the first digits you can prevent F-16 from the vertical/slice turn. Second digits allow which or both tactics to be chosen in WVR Third might be the last time ditching maneuver options for missile evade.
CanLevelTurn = 0x1,
CanSlice = 0x2,
CanUseVertical = 0x4,
Let's say you want F16 to level turn and slice turn but don't want to do vertical turn, (Usually, there would be an Altitude block to prevent air collision and blue on blue in a large package, you don't want to split S to evade missile) then 1+2=3
CanOneCircle = 0x10,
CanTwoCircle = 0x20,
F-16 can be good at both one circle and two circle fight: 10+20=30
CanJinkSnake = 0x100,
CanJinkLoaded = 0x200,
CanJinkUnloaded = 0x400
This one I could not understand what is JinkLoaded or JinkUnLoaded Anyway, If you like to only allow Jink Snake, just leave 100 So you can edit like: 100 + 30 + 3 = 133 Overall you can write:
F16 Manuever Class Flags
0x133
This is an example but this time I'd like to prevent F-16 even from slice turn. Doing Slice turn is okay according to AFTTP, but BMS AI tends to lower altitude too much risking their fuel consumption and MANPADS threat.
F16 Manuever Class Flags
0x131
However, even if I set the first digits to 1 which only allows level turn, F-16 still does slice turn in BVR. I'd also like to prevent all Jink maneuvers from F-16. But I'm uncertain should I write **0x31** or **0x031** here. Still, it looks effective enough that now F-16 will not split S to evade missiles. I'll also continue to intercepts/merge/spike section. This area seems to define BVR decision. BMS AI tries to BEAM against enemy ARH to reduce their energy. Sounds expert but basic BVR tactics are usually Launch&Leave (Skate/Short Skate) which should evade missile by mainly drag. Beaming against enemy radar will opening distances between elements and might lose mutual supports (AI flights often do that). The comment says:
enum SpikeReactionType {
SpikeReactNone, // 1 in this file
SpikeReactECM, // 2 in this file
SpikeReactBeam, // 3 in this file
SpikeReactDrag, // 4 in this file
NumSpikeReactionTypes
};
So "Spike Reacts" value should be 4 only (I tested but it seems even if you don't set 2 here, AI can still use ECM)
F16 v F16
Num intercepts
4
Num Merges
3
Num Spike React
1
Intercept Types
1 2 3 4
Merges
1 2 3
Spike Reacts
4
What other intercept options and merge options mean are uncertain. Yeah, I know whats single side offset, pince, pursuit are but I'm really not sure how will these options work in BMS. I just set all options enables so that AIs might perform all possible tactics they have. I also guess WVR limited/unlimited option has some kind of idea from "War call, Restricted/Unrestricted war" but just guessing… This "Spike Reacts" option is really effective that now AI evades missiles mainly by drag. There are other 3 files in the same folder: **GENERIC.BRN, BRAINDAT.brn** and **BRAINDAT.FIL** These files I really can't understand what their values inside mean. One section that might be related to AI BVR tactics is the following part.
WVREngageMode
1
3.0 50000.0 180.0BVREngageMode
1
3.0 250000.0 180.0I tested AI vs AI BVR several times and found they don't shoot AMRAAM inside 10 or fewer nautical miles. I guessed "50000.0" of # WVREngageMode indicates that inside this range (in feet) AI goes to WVR mode and doesn't shoot MRM. Therefore I reduced the value as follows.
WVREngageMode
1
3.0 24000.0 180.0I feel like F-16s now shoot AMRAAM within 10nm but I'm not sure if this change made it or not. OK, let's then go to Acdata files. BMS AIs shoot missile bit too close I felt, yeah that should have high PK but unless ALR is extreme you should not risk your life as a fighter pilot and expensive fighter jet. I'd like AIs to execute more safe Launch & Leave until they really need to go Launch & Decide. I found several variables in each aircraft FM data that might affect AI BVR tactics. **Sim\Acdata\f16bk50.dat**
MinTGTMAR 4
MaxMARIdedStart 20
AddMARIded5k 0
AddMARIded18k 2
AddMARIded28k 4
AddMARIdedSpike 1
MaxWEZtaStart 5
IsShortBurnThreat 0
IsLongBurnThreat 1MAR/WEZta is described in stock BMS Manuals. MaxMARIdedStart should be possible maximum MAR at 0ft. AddMARIded5k / AddMARIded18k / AddMARIded28k sounds AI will add MaxMARIdedStart + each additional values at their current altitudes. However, even I twice all of the aircraft FMs MAR/WEZ values, AI shoot range nor drag starting range doesn't seem to change.
-
Oh and I forgot to write.
“F-16” in the mnvrdata.dat means any “F-16 class” aircraft defined in the DB.
So any other aircraft that is counted as “F-16 class” will use the same option. -
Most of those variables are not used anymore in BVR
Bms BVr code is 100% different than any previous falcon versions
Iirc there are now 10 or 12 tactics each of them including sub tactics
Moreover the BVR tactics chosen by AI are depending on many parameters with random included. That is to say you can’t conclude anything reliably unless because you never know in which tactic the AI brain has been engagedBe aware that 2 ships tactics are different than 4 ships tactics
The only way to have a reliable known tactic is to use DGF module and specify the tactic
Be aware that it is also highly dépendant on skill level
-
Most of those variables are not used anymore in BVR
Bms BVr code is 100% different than any previous falcon versions
Oh wow, I just looked into the GOG Falcon4.0 folder and found this code is coming from the original Falcon4.0
A# enum ACMnverClass { # MnvrClassF4, # MnvrClassF5, # MnvrClassF15, # MnvrClassF16, # MnvrClassMig25, # MnvrClassMig27, # MnvrClassA10, # MnvrClassBomber, # NumMnvrClasses # }; # # enum ACMnverClassFlags # { # CanLevelTurn = 0x1, # CanSlice = 0x2, # CanUseVertical = 0x4, # CanOneCircle = 0x10, # CanTwoCircle = 0x20, # CanJinkSnake = 0x100, # CanJinkLoaded = 0x200, # CanJinkUnloaded = 0x400 # }; # # /*------------*/ # /* AC Element */ # /*------------*/ # typedef struct # { # BVRInterceptType* intercept; # WVRMergeManeuverType* merge; # SpikeReactionType* spikeReact; # char numIntercepts; # char numMerges; # char numReacts; # } ManeuverChoiceTable; # # # F4 Manuever Class Flags
BVRInterceptType, WVRMergeManeuverType and SpikeReactionType seems to be a new variable.
I’m not sure it’s a BMS variable or older OF era one.
At least SpikeReactionType seems working for BMS4.35
I wish 4.36/4.37 also allows a similar type of option.
I’d like enemy AI to execute drag maneuvers mainly in my theater.If possible I’d also like to edit MAR/WEZta variables for each aircraft.
Just my wishlist.
The only way to have a reliable known tactic is to use DGF module and specify the tactic
Be aware that it is also highly dépendant on skill level
I tested in the DGF module and as long as I choose the same tactics, same plane same numbers, and the same condition.
The first commit always goes the same game (will change after the next commit though,). -
Sorry that you spent time on this but
CanLevelTurn = 0x1, => not working - active only in Merge Mode which only runs a few frames so this is useless (i might think about debugging this )
CanSlice = 0x2, => not working active only in Merge Mode which only runs a few frames so this is useless (i might think about debugging this )
CanUseVertical = 0x4, => not working active only in Merge Mode which only runs a few frames so this is useless (i might think about debugging this )
CanOneCircle = 0x10, => not used at all,
CanTwoCircle = 0x20, => not used at all,
SpikeReactNone => not used at all
SpikeReactECM => not used at all,
SpikeReactBeam => not used at all
SpikeReactDrag => not used at all,
MaxWEZtaStart => not used at all,
MinTGTMAR => Yes, in use
MaxMARIdedStart = >not used at all
AddMARIded5k = >not used at all
AddMARIded18k = >not used at all
AddMARIded28k = >not used at all
AddMARIdedSpike = >not used at allIsShortBurnThreat => in use
IsLongBurnThreat => in useas i said : most of those are relics of the past that
- were never used or
- were totally poorly implemented.