View Issue Details

IDProjectCategoryView StatusLast Update
0005156The Dark ModAIpublic19.02.2020 03:05
Reporterduzenko Assigned Tograyman  
Status resolvedResolutionfixed 
PlatformPCOSWindowsOS Version10
Product VersionTDM 2.07 
Target VersionTDM 2.08Fixed in VersionTDM 2.08 
Summary0005156: Physics failures: Huge translation
DescriptionI'm getting a lot of these errors in current builds. I'm worried that they're likely to affect AI and gameplay negatively.
Steps To ReproduceStart PD3
Look in console for text like this

speaker_zone_ambient::init() called
Color read from main ambient light 'ambient_world': 0.06 0.06 0.06

Changed location from '' to 'streets_west'.
The ambient 'snd_streets_west' (Pad01) for location 'streets_west' is now playi
'atdm_ai_thief02_3' dealt 41280 landing damage at [9326.95 613.45 -679.84]
huge translation for clip model 0 on entity 3803 'atdm_moveable_crate01_10'
huge translation for clip model 0 on entity 3803 'atdm_moveable_crate01_10'
huge translation for clip model 0 on entity 3803 'atdm_moveable_crate01_10'
huge translation for clip model 0 on entity 3803 'atdm_moveable_crate01_10'
huge translation for clip model 0 on entity 3803 'atdm_moveable_crate01_10'
huge translation for clip model 0 on entity 3803 'atdm_moveable_crate01_10'
huge translation for clip model 0 on entity 3804 'atdm_moveable_crate01_11'
huge translation for clip model 0 on entity 3804 'atdm_moveable_crate01_11'
'atdm_ai_townsfolk_commoner_armed_4' dealt 73426 landing damage at [8343.84 947
.03 -679.75]
TagsNo tags attached.


related to 0004940 resolvedgrayman Various AI get dead/unconscious before you get to them 
related to 0003989 resolvedgrayman Examine returning to sitting position after interruption 




16.02.2020 06:05

administrator   ~0012191



16.02.2020 06:31

administrator   ~0012192

I looked at atdm_ai_thief02_3, who patrols the building and passes near 9326.95 613.45 -679.84 (where he sometimes dies according to logs).

It seems that sometimes he tries to sit down, but gets "teleported" to weird places due to it. Hence added 0004940 as related.


16.02.2020 06:38

administrator   ~0012193

Here is the footage of miserable death due to programmers' bugs =)


16.02.2020 06:47

administrator   ~0012194

Two more cases:

The exact effect is different, but all the time AI tries to sit down in a horribly wrong way.


16.02.2020 08:09

developer   ~0012195

I'm not able to repeat the events from the start log in the description at will. But two things that always happen are:
1. at spawn location, strife right until blocked by wall - always a huge translation for player console log
2. setviewpos 8800 2064 -583 and try walk forward - movement blocked by stairs with "huge translation" log

Suspecting that physics fails to process small movements happening in high coords due to fp32 precision loss?


16.02.2020 08:17

developer   ~0012196

Last edited: 16.02.2020 08:33

View 2 revisions

Curious: the huge translation happens in 64bit release but not in 32bit debug build
Apparently triggered by "Maximum Optimization (Favor Speed) (/O2)"



16.02.2020 08:37

developer   ~0012197

Unless debugger plays tricks this line is suspicious (physics_player.cpp:402):

                idVec3 fullForward = downTrace.endpos + maxStepHeight * velocityNorm;

+ downTrace.endpos {x=8839.75000 y=2064.00000 z=-629.874695 } idVec3
        maxStepHeight 16.0000000 float
+ velocityNorm {x=56.1372032 y=0.000000000 z=42.1064301 } idVec3
+ fullForward {x=613956.500 y=2064.00000 z=5954735.00 } idVec3


16.02.2020 08:46

developer   ~0012198

Totally confused and clueless
Adding the logging code makes the error go away

                idVec3 fullForward = downTrace.endpos + maxStepHeight * velocityNorm;
                gameLocal.clip.Translation( stepTrace, downTrace.endpos, fullForward, clipModel, clipModel->GetAxis(), clipMask, self );
                if ( fullForward.z > 9999 ) {
                    common->Warning( "%s\n", fullForward.ToString() );
                    common->Warning( "%s\n", ( downTrace.endpos + maxStepHeight * velocityNorm ).ToString() );
                    common->Warning( "%s\n", ( maxStepHeight * velocityNorm ).ToString() );
                    common->Warning( "%s\n", velocityNorm.ToString() );

Commenting it out and the error comes back


16.02.2020 09:29

developer   ~0012199

Last edited: 16.02.2020 09:32

View 2 revisions

The attached save game always generates huge translation for crater entity when AI walks by



16.02.2020 10:23

developer   ~0012200

I start wondering if it's VS2019 optimizer bug. I test this with the notools project that uses 2019 build tools.


16.02.2020 10:34

developer   ~0012201

Fixed by updating MSVC 2019 to 16.4.5
Thank you MS for wasting a day of my life


16.02.2020 10:38

administrator   ~0012202

I cannot reproduce anything you are saying.
But AIs are dying, and it is an unrelated problem.


16.02.2020 12:15

administrator   ~0012203

Sorry, but I still see AIs on this map self-killing and teleporting to nowhere. Regardless of which MSVC I'm using.
Basically, the Chair-Killer has returned! =)

So I'll keep this task open.


16.02.2020 12:21

administrator   ~0012204

Speaking about atdm_ai_thief02_3, who happens to teleport to many various places when he tries to sit down.

In one of the cases he teleports outdoors =)
Looking at what caused the movement, I see that ai_darkmod_base::Legs_Sit_Down script is calling setOrigin here:

    vector vec2Ideal = getVectorToIdealOrigin(); // vector from where the AI stopped walking to the ideal location for sitting
    vector startLocation = getOrigin() + vec2Ideal; // base movement toward ideal location
    float vec2IdealLength = sys.vecLength(vec2Ideal);

    if (vec2IdealLength > 0)
        float time2Slide = 0.5; // Slide to ideal position in 0.5s.
        float slideIncrements = 10; // Do it in 10 increments
        vector incSlide; // Incremental slide
        incSlide_x = vec2Ideal_x/slideIncrements;
        incSlide_y = vec2Ideal_y/slideIncrements;
        incSlide_z = 0; // assume AI is on the floor, so ignore any z component
        float incTime = time2Slide/slideIncrements;
        float i;
        for (i = 0 ; i < slideIncrements ; i++)
            setOrigin(getOrigin() + incSlide);

When inspecting the vec2Ideal value, I see that:
  (9288 80 -688) --- location of path_sit2
  (9338 118 -703) --- approximate origin when AI starting sitting down
  (9248 712 -448) --- owner->GetMemory().startSitLocation --- i.e. the destination of the movement caused by script code
So the "ideal" location is very far. In fact, it is exactly where path_corner_307 is located, which is several path-entities away.


16.02.2020 12:47

administrator   ~0012205

As far as I guess, the idea was to "snap" AI into the mapper-specified location at the moment of sitting.
I don't understand why path_sit entity itself could not be used for it --- that would be quite logical. Supposedly because position of path_sit never influenced anything, so mappers put it into random places.
That's why we try to get the last visited path_corner entity and snap AI into its location. This is logical if everything went normal, then the AI should have started sitting down from that location (since task changed to "sit" immediately after that).

I looked where startSitLocation is updated. There are two places, and I guess this is the main one:
                // grayman 0003989 - Save the ideal sitting location, which is the path_corner origin.
                // This is useful when sitting down and lying down, to make sure I sit
                // or lay down in the correct place.
                owner->GetMemory().startSitLocation = path->GetPhysics()->GetOrigin();

So I started the game afresh and recorded which "path" entities happened here:
  Entity "path_corner_301": num=5979 def=77
  Entity "path_corner_314": num=5993 def=77
  Entity "path_corner_307": num=5985 def=77
  Entity "path_corner_318": num=5998 def=77
Somewhere here the guy tried to sit down, and was pulled back apporoximately to where path_corner_318 is.
Then he continued patrolling:
  Entity "path_corner_314": num=5993 def=77
After that he tried to sit down again, and was thrown into path_corner_314 location, and killed by the stairs obstacle.


16.02.2020 13:14

administrator   ~0012206

Ok, the reason was that there is another was out of PathCornerTask:
        else if (_usePathPrediction)
            // Move not done yet. Try to perform a prediction whether we will hit the path corner
            // next round. This is valid, as no accuracy is set on the current path.
I added the same assignment in this code path, and now the guy does not die.

However, he sits straight on the stairs instead of the bench.
The last location when is assigned to startSitLocation is "path_corner_316".
I have no idea why "path_corner_300 is ignored: it is in-between "path_corner_316" and "path_sit_2" on the patrol path.


16.02.2020 23:37

administrator   ~0012214

Working on the problem, with notes being attached to issue 3989. When the problem is fixed, I'll note that in the related issues.


19.02.2020 02:22

administrator   ~0012227

The missing line stgatilov pointed out in the path prediction code was the root cause of these huge translation problems.

With the line added, the PD3 AI properly navigated his patrol w/o huge translations or damage.

The problem of his sitting in the wrong places is a problem with the map: the monsterclip around the bench he's supposed to sit on is misapplied, making it impossible for him to get to the path_corner in front of the bench, at which he sits down. Since he can't get to the path_corner, he sits wherever he is at the moment. I've seen him sit both at the bottom of the stairs and in front of a nearby door. The path_corners in those locations are trying to get to the bench path_corner, but find that they're unable to.

Fixed in rev. 8595:



19.02.2020 03:05

administrator   ~0012229

Committed a corrected copy of (PD3) if anyone wants to dmap it and observe the behavior of the afflicted AI.


Issue History

Date Modified Username Field Change
15.02.2020 20:57 duzenko New Issue
15.02.2020 20:57 duzenko Status new => assigned
15.02.2020 20:57 duzenko Assigned To => stgatilov
16.02.2020 06:05 stgatilov Note Added: 0012191
16.02.2020 06:30 stgatilov Relationship added related to 0004940
16.02.2020 06:31 stgatilov Note Added: 0012192
16.02.2020 06:38 stgatilov Note Added: 0012193
16.02.2020 06:47 stgatilov Note Added: 0012194
16.02.2020 06:47 stgatilov Severity normal => major
16.02.2020 06:47 stgatilov Category Physics => AI
16.02.2020 08:09 duzenko Note Added: 0012195
16.02.2020 08:17 duzenko Note Added: 0012196
16.02.2020 08:33 duzenko Note Edited: 0012196 View Revisions
16.02.2020 08:37 duzenko Note Added: 0012197
16.02.2020 08:46 duzenko Note Added: 0012198
16.02.2020 09:29 duzenko Note Added: 0012199
16.02.2020 09:32 duzenko Note Edited: 0012199 View Revisions
16.02.2020 10:23 duzenko Note Added: 0012200
16.02.2020 10:34 duzenko Status assigned => resolved
16.02.2020 10:34 duzenko Resolution open => fixed
16.02.2020 10:34 duzenko Fixed in Version => TDM 2.08
16.02.2020 10:34 duzenko Note Added: 0012201
16.02.2020 10:38 stgatilov Note Added: 0012202
16.02.2020 12:15 stgatilov Status resolved => assigned
16.02.2020 12:15 stgatilov Note Added: 0012203
16.02.2020 12:21 stgatilov Note Added: 0012204
16.02.2020 12:47 stgatilov Note Added: 0012205
16.02.2020 12:48 stgatilov Relationship added related to 0003989
16.02.2020 13:14 stgatilov Note Added: 0012206
16.02.2020 23:37 grayman Note Added: 0012214
19.02.2020 02:22 grayman Note Added: 0012227
19.02.2020 02:23 grayman Assigned To stgatilov => grayman
19.02.2020 02:23 grayman Status assigned => resolved
19.02.2020 02:23 grayman Product Version TDM 2.08 => TDM 2.07
19.02.2020 03:05 grayman Note Added: 0012229