Page MenuHomeFeedback Tracker

AI make LoS detection check on sound source before target is inside FoV (Aka, eyes in back of head)
Closed, ResolvedPublic

Description

Many players feel that the AI detects them with robotic radar senses. Although the AI rely on hearing gunfire or footsteps and then turning to acquire targets visually, this process has a problem.

The following is my longstanding observation on how the AI works. It is visualized in the repro mission with a script that denotes the perceived position of the AI's target with circles of red smoke. Confirmed targets are discreet balls of white and red smoke.

AI listen to gunshots and make a guess of where the source (target) is. This guess has a high degree of error. They then turn towards the target or scan the horizon.

Expected: When the source of the sound is within their field of vision, they perform a Line of Sight check. If it is positive and not diluted by range or fog, they acquire the target.

Observed: Alarmed AI turn towards the source of gunfire. Before the target actually enters the unit's field of view, a Line of Sight check is performed. The AI knows exactly where the target is before actually being able to lay eyes on it. This enables them to open fire on a target instantly, with maximum accuracy. They do not actually have to spend any time looking for the target.

Expected: The AI should not perform a target-acquiring LoS check until the target is actually within their normal FoV.

Further suggestions: If the target is at long range, wearing ghillie or prone in terrain with high camouflage value (talls grass, woodland areas of the map), the LoS check should be delayed. If the target is well concealed but LoS exists, the AI should fire on an area target of several meters, gradually zeroing in on the point target.

Details

Legacy ID
3175887749
Severity
None
Resolution
Fixed
Reproducibility
Always
Category
AI Issues
Steps To Reproduce

I recommend setting timeacc to around 0.1 to observe this mission.

Repro:

  1. Step out from behind the concrete barrier. Walk, so as not to give away your position audibly. (This close range best displays the FOV glitch)
  2. Fire a single round into the concrete barrier.
  3. Wait several seconds for the AI to become alarmed. KnowsAbout will increase, red circles of perceived position will appear on the runway around the player. Note the high degree of inaccuracy of the AI's position guess.
  4. When the AI has begun to swivel, KnowsAbout will suddenly increase to 4. Red and white smoke will burst from the player. This indicates that he has been spotted. At this point observe that the AI should only be able to see the player's position through peripheral vision, at best. He may even be looking through his own helmet.
Additional Information

WTF? The brilliant bugtracker isn't accepting PBO or SQM! Here is the text version of repro mission:

version=12;
class Mission
{
addOns[]=
{

		"A3_Characters_F_BLUFOR",
		"A3_Characters_F_OPFOR",
		"a3_map_stratis",
		"A3_Structures_F_Walls"

};
addOnsAuto[]=
{

		"A3_Characters_F_BLUFOR",
		"A3_Characters_F_OPFOR",
		"A3_Structures_F_Walls",
		"a3_map_stratis"

};
randomSeed=1762223;
class Intel
{

		resistanceWest=0;
		startWeather=0.1;
		startWind=0.099999994;
		startWaves=0.099999994;
		forecastWeather=0.1;
		forecastWind=0.099999994;
		forecastWaves=0.099999994;
		forecastLightnings=0.099999994;
		year=2035;
		month=7;
		day=6;
		hour=14;
		minute=15;
		startFogBase=0.001;
		forecastFogBase=0.001;
		startFogDecay=0.0049999999;
		forecastFogDecay=0.0049999999;

};
class Groups
{

		items=2;
		class Item0
		{
			side="WEST";
			class Vehicles
			{
				items=1;
				class Item0
				{
					position[]={1679.1724,5.5,5524.8608};
					azimut=183.14183;
					id=0;
					side="WEST";
					vehicle="B_soldier_M_F";
					player="PLAYER COMMANDER";
					leader=1;
					skill=0.60000002;
					init="shots = 0; this  addeventhandler [""fired"", {shots = shots +1;}]; this allowdammage false; 0 = this spawn {while {true} do {hintsilent format [""knowsabout: %1 \nshots fired: %2"", ai knowsAbout player, shots]; sleep 0.1}};";
				};
			};
		};
		class Item1
		{
			side="EAST";
			class Vehicles
			{
				items=1;
				class Item0
				{
					position[]={1677.4756,5.5,5503.3018};
					azimut=173.72935;
					id=1;
					side="EAST";
					vehicle="O_Soldier_F";
					leader=1;
					skill=0.60000002;
					text="ai";
				};
			};
		};

};
class Vehicles
{

		items=1;
		class Item0
		{
			position[]={1679.1486,5.5,5522.5693};
			azimut=173.72935;
			id=2;
			side="EMPTY";
			vehicle="Land_CncWall1_F";
			leader=1;
			skill=0.60000002;
		};

};
};
class Intro
{
addOns[]=
{

		"a3_map_stratis"

};
addOnsAuto[]=
{

		"a3_map_stratis"

};
randomSeed=13170605;
class Intel
{

		timeOfChanges=1800.0002;
		startWeather=0.30000001;
		startWind=0.1;
		startWaves=0.1;
		forecastWeather=0.30000001;
		forecastWind=0.1;
		forecastWaves=0.1;
		forecastLightnings=0.1;
		year=2035;
		month=7;
		day=6;
		hour=14;
		minute=15;
		startFogBase=0.001;
		forecastFogBase=0.001;
		startFogDecay=0.0049999999;
		forecastFogDecay=0.0049999999;

};
};
class OutroWin
{
addOns[]=
{

		"a3_map_stratis"

};
addOnsAuto[]=
{

		"a3_map_stratis"

};
randomSeed=14678934;
class Intel
{

		timeOfChanges=1800.0002;
		startWeather=0.30000001;
		startWind=0.1;
		startWaves=0.1;
		forecastWeather=0.30000001;
		forecastWind=0.1;
		forecastWaves=0.1;
		forecastLightnings=0.1;
		year=2035;
		month=7;
		day=6;
		hour=14;
		minute=15;
		startFogBase=0.001;
		forecastFogBase=0.001;
		startFogDecay=0.0049999999;
		forecastFogDecay=0.0049999999;

};
};
class OutroLoose
{
addOns[]=
{

		"a3_map_stratis"

};
addOnsAuto[]=
{

		"a3_map_stratis"

};
randomSeed=11739500;
class Intel
{

		timeOfChanges=1800.0002;
		startWeather=0.30000001;
		startWind=0.1;
		startWaves=0.1;
		forecastWeather=0.30000001;
		forecastWind=0.1;
		forecastWaves=0.1;
		forecastLightnings=0.1;
		year=2035;
		month=7;
		day=6;
		hour=14;
		minute=15;
		startFogBase=0.001;
		forecastFogBase=0.001;
		startFogDecay=0.0049999999;
		forecastFogDecay=0.0049999999;

};
};

Now you'll have to make your own init.sqf with the following language in order to repro:

  • spawn {

for [{_i=1}, {_i>=1}, {_i=1}] do
{
while {true} do {

		sleep(0.1);
		_nt = ai nearTargets 1000;
		if (count(_nt)>0) then
		{
			for [{_j=0}, {_j<count(_nt)}, {_j=_j+1}] do
			{
				//scopeName "checkplayer";
				_ct = _nt select _j;
				//if ((_ct select 4) == targetr || (_ct select 4) == targetg) then {
					_loc = _ct select 0;
					_rad = _ct select 5;
					// hintSilent format["%1", [_loc distance player, _rad]];
					//[ShapeName, AnimationName, Type, TimerPeriod, LifeTime, Position, MoveVelocity, RotationVelocity, Weight, Volume, Rubbing, Size, Color, AnimationPhase, RandomDirectionPeriod, RandomDirectionIntensity, OnTimer, BeforeDestroy, Object]
					drop ["\A3\data_f\cl_basic", "", "Billboard", 1, 1, _loc, [0, 0, 0], 0.05, 0.005, 0.0042, 1, [0.5,0.5], [[1,1,1,1],[1,1,1,0]], [0,1,0,1,0,1], 0.2, 0.2, "", "", ""];
					if (_rad > 0) then
					{
						_bdiv = 20 / (_rad * 3);
						if (_bdiv<1) then {_bdiv = 1;};
						for [{_k=0},{_k<360},{_k=_k+_bdiv}] do
						{
							_pos = [(_loc select 0) + (sin(_k)*_rad), (_loc select 1) + (cos(_k)*_rad), _loc select 2];
							drop ["\A3\data_f\cl_basic", "", "Billboard", 1, 1, _pos, [0, 0, 0], 0.01, 0.005, 0.0042, 0, [0.25,0.25], [[1,0,0,1],[1,0,0,0]], [0,1,0,1,0,1], 0.2, 0.2, "", "", ""];
						};
					};
					//breakOut "checkplayer";
				//};
			};
		};

};
};

Further tickets are pending to inquire why, in this case, the AI requires so unnaturally long to respond to a nearby gunshot.

Event Timeline

maturin edited Steps To Reproduce. (Show Details)Aug 27 2013, 8:03 PM
maturin edited Additional Information. (Show Details)
maturin set Category to AI Issues.
maturin set Reproducibility to Always.
maturin set Severity to None.
maturin set Resolution to Fixed.
maturin set Legacy ID to 3175887749.May 7 2016, 4:17 PM
maturin added a subscriber: maturin.

I apologize for the duplicates. This useless piece of software was rejecting my repro mission attachments and I was unaware that it was actually creating tickets. Please refer to the most recently-created ticket and delete this one.