View Issue Details

IDProjectCategoryView StatusLast Update
0004435The Dark ModCodingpublic30.06.2018 09:10
Reporterduzenko Assigned Toduzenko  
PrioritynormalSeveritynormalReproducibilityhave not tried
Status closedResolutionnot fixable 
Product VersionTDM 2.06 
Target VersionSVNFixed in VersionTDM 2.06 
Summary0004435: Investigate fp-precision related issues
DescriptionI'm going to enable SSE optimization on all projects.
Let's post here any bugs that appear because of that.


related to 0003633 new Can't use doors when pressed up against them 
related to 0004550 resolvedstgatilov Cleanup of SIMD code 
related to 0000665 new Moveables stacked on top of eachother begin to levitate up 
related to 0001073 new Butcher Knife & Kitchen Knife Levitating 
related to 0004651 resolvedstgatilov Mantling does not trigger (in New Job) 
related to 0004853 resolvedstgatilov Player gets stuck on edge between two slanted polygons (Volta2) 




05.12.2016 02:49

developer   ~0008600

This causes the mantling bug to return.


1) Install mission "Swing"
2) Climp the ladder at the beginning of the mission
3) Before you reach the mantle distance for the first platform, keep trying to mantle
4) You will find that sometimes you are able to mantle before you should
5) When this happens you will be embeded into the platform and you wont be able to jump

It may take a few tries to replicate this.


05.12.2016 13:43

developer   ~0008602

Last edited: 05.12.2016 13:44

I can't identify the problem just yet.
I uploaded a video on youtube with my experience. It's working like that for both x87 and sse compiles.
How is working for you?



05.12.2016 14:38

developer   ~0008603

Last edited: 05.12.2016 14:40

The replication involves mantling from the ladder to the platform. You are mantling from a swing to the platform.

Climb the ladder, when you approach the top of it turn to face the platform. Keep trying to mantle early
(before you are over the threshold where you should be able to climb off the ladder onto the first platform.)



05.12.2016 15:42

developer   ~0008604

New video at
Still can't repeat.


05.12.2016 15:47

developer   ~0008605

After you mantle, are you able to jump?


05.12.2016 15:49

developer   ~0008606

Tried again - I can jump after mantle 5 times out of 5.


18.12.2016 09:19

developer   ~0008620

Possible issue: underground basin in Somewhere Above the City.
Not possible to pull up to the ground above it.


26.12.2016 22:31

developer   ~0008637

Perhaps do this in the game\physics classes:

#if defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(DEBUG)
// greebo: switch off function inlining for this file in VC++ 2013 release builds
// Function inlining seems to cause lighting bugs (triangles are drawn very dark or black)
#pragma optimize("t", off)


22.01.2017 09:41

developer   ~0008715

Additional info for the the example above:
Player can't mantle up from water when closely touching the basin wall.
After moving a little away from the wall it mantles as usual.


12.04.2017 00:57

developer   ~0008792

Same issue reproduced in the x64 build (32-bit binary). As expected.


17.04.2017 02:02

administrator   ~0008797

In this particular scenario, there is the ledge you mantle to is located at coordinates Y=7616, Z=3424.

Now there are two cases:
1. Mantling with hands involved. Then trace collision point is (* 7615.75 341?.?), and mantle endpoint is (* 7615.75 3424.?). In such case player does not get stuck.
2. Mantling without hands. Then trace collision point is (* 7616 3424), which is exactly on the ledge. Then the idClip::Translation is called (player vs world) in order to check if this point is suitable for ending mantle position. Since player with Z=3424 prefectly touches the platform, any result is acceptable, and collision manager returns "no collisions" verdict. So the point (* 7616 3424) is accepted as "end mantle" point. Now the bad part is: when mantling ends, player has position (* 7616 3423.97???), which is a bit lower than platform. This leads to player getting stuck, and he cannot jump.


17.04.2017 02:20

administrator   ~0008798

Last edited: 17.04.2017 02:20

Now the question is: why isn't player's position exactly equal to mantle end position when mantling is over?

As it turns out, mantling animation (method MantleMove) is called each frame during mantling. It checks fraction of move which is already complete (var timeRatio), and sets player position depending on this fraction.
The problem is: MantleMove is last called with fraction = 0.98, it is NOT called with fraction = 1.0, because UpdateMantleTimers changes phase before modelling last bit of animation. As a result, both position and viewangles are not set exactly to their final values when the mantle is over.

There is already a fix for viewangles in UpdateMantleTimers done by greebo. It sets roll precisely to zero. I have added a fix for endpoint here too: it sets player's position exactly to mantle endpoint. This change fixes the issue.



17.04.2017 02:37

administrator   ~0008799

Last edited: 17.04.2017 02:37

Now the question is: why is it so critical if mantle finishes a bit inside solid?

You might remember that in the old versions of TDM, there was a very funny bug: player started to float up after a mantle, sometimes going through a wall (see e.g. 0000652). This behavior was caused by the special code supposed to fix any collisions present at the end of mantling. It is located in method CorrectAllSolid, and it was written by SophisticatedZombie in the very beginning. It checks if the player clips into something, and if yes, then it lifts player up by delta = 0.2.

Since this hack was applied continually, it sometimes made player levitate through wall. In order to fix this issue, Ishtvan committed a change in revision 2970 (back in 2008):
  possible fix for infamous 'rising issue' : levitation code in CorrectAllSolid is only executed if we clip something after a mantle
However, that fix was buggy. It sets a special phase fixClipping_DarkModMantlePhase after mantling, but then changes it to notMantling_DarkModMantlePhase immediately, without even getting out of UpdateMantleTimers.

I have fixed that: allowed to get out of the loop in UpdateMantleTimers if phase is fixClipping_DarkModMantlePhase. Then the "push-player-up" starts working (called only once after mantle), and the issue is resolved.



17.04.2017 02:56

administrator   ~0008800

Now I have two working fixes for the issue, each alone is enough to fix this particular scenario. A good question is: how is it related with FPU/SSE switch?

It is hard to answer. I looked through the code which checks for collision, and it is very tight in its handling of floats. Note that in this case all important coordinates are integers, i.e. they are perfectly representible as float32 numbers. Also, player's collision model is checked against the platform he perfectly touches. The internal code (TestTrmInPolygon) seems to not apply any tolerance (i.e. epsilon) when checking for collision. All of this means that the outcome of touching collision query is very unstable and depends on the arithmetic used. A more consistent arithmetic (SSE) is more likely to have various quantities equal, which may lead to verdict "no collision".

The only potential issue with precision I see is that collision code uses Pluecker coordinates for lines passing through edges (FromLine, FromRay, InnerProduct). They are similar to cross product, i.e. they have components like x1*y2-x2*y1. Since we have coordinates of magnitude about 10^4 here, these products can lose precision when evaluated in 32-bit floats (product is 10^8, so error can be around 10). Maybe converting something to double precision values here may help. But it feels like gambling.


30.06.2018 06:10

administrator   ~0010617

How about closing this issue, since it covers a vast set of issues and no single issue in particular?
We can create a "precision" tag to mark all issues related to this.


30.06.2018 06:19

developer   ~0010618



30.06.2018 06:54

administrator   ~0010619

I mark it as "not fixable" because there is no particular issue to be fixed here. The true reason would be "too broad" =)

Issue History

Date Modified Username Field Change
04.12.2016 08:49 duzenko New Issue
04.12.2016 08:49 duzenko Status new => assigned
04.12.2016 08:49 duzenko Assigned To => duzenko
05.12.2016 02:49 nbohr1more Note Added: 0008600
05.12.2016 13:43 duzenko Note Added: 0008602
05.12.2016 13:44 duzenko Note Edited: 0008602
05.12.2016 14:38 nbohr1more Note Added: 0008603
05.12.2016 14:40 nbohr1more Note Edited: 0008603
05.12.2016 14:40 nbohr1more Note Edited: 0008603
05.12.2016 15:42 duzenko Note Added: 0008604
05.12.2016 15:47 nbohr1more Note Added: 0008605
05.12.2016 15:49 duzenko Note Added: 0008606
18.12.2016 09:19 duzenko Note Added: 0008620
26.12.2016 22:31 nbohr1more Note Added: 0008637
22.01.2017 09:41 duzenko Note Added: 0008715
05.03.2017 07:27 duzenko Relationship added related to 0003633
12.04.2017 00:57 nbohr1more Note Added: 0008792
17.04.2017 02:02 stgatilov Note Added: 0008797
17.04.2017 02:20 stgatilov Note Added: 0008798
17.04.2017 02:20 stgatilov Note Edited: 0008798
17.04.2017 02:37 stgatilov Note Added: 0008799
17.04.2017 02:37 stgatilov Note Edited: 0008799
17.04.2017 02:37 stgatilov Note Edited: 0008799
17.04.2017 02:56 stgatilov Note Added: 0008800
30.08.2017 17:02 nbohr1more Relationship added related to 0004550
09.10.2017 14:06 nbohr1more Relationship added related to 0000665
09.10.2017 14:06 nbohr1more Relationship added related to 0001073
05.11.2017 04:34 stgatilov Relationship added related to 0004651
27.06.2018 17:38 stgatilov Relationship added related to 0004853
30.06.2018 06:10 stgatilov Note Added: 0010617
30.06.2018 06:19 duzenko Note Added: 0010618
30.06.2018 06:54 stgatilov Note Added: 0010619
30.06.2018 06:54 stgatilov Status assigned => closed
30.06.2018 06:54 stgatilov Resolution open => not fixable
30.06.2018 06:54 stgatilov Fixed in Version => TDM 2.06
30.06.2018 09:10 stgatilov Tag Attached: precision