Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pawn position is outside of buy-zone during freeze time #37

Closed
1 task done
in0finite opened this issue Jan 28, 2024 · 8 comments · Fixed by #56
Closed
1 task done

Pawn position is outside of buy-zone during freeze time #37

in0finite opened this issue Jan 28, 2024 · 8 comments · Fixed by #56
Labels
resolution/fixed type/bug Something isn't working

Comments

@in0finite
Copy link

in0finite commented Jan 28, 2024

Research

  • I've already searched and I could not find an existing issue or discussion about this issue.

Description

Sometimes, during freeze time pawn is placed outside of buy-zone.

To reproduce:

Go to: https://csunity-5172f.web.app/
Click Open -> Ok -> Select navi-javelins-vs-9-pandas-fearless-m1-mirage.dem -> Click Pause

Observe player "victoria" on the middle of screen. If you look around, you'll see his teammates are too far away from him.

Once the round starts, his position will be correct.

His position coordinates are again 1024. You can see that in Inspector (but converted to meters, it will be 32).

Code to reproduce

No response

Affected demos

navi-javelins-vs-9-pandas-fearless-m1-mirage.dem

@saul saul added type/bug Something isn't working help wanted Extra attention is needed labels Feb 11, 2024
@saul
Copy link
Owner

saul commented Feb 21, 2024

Does this issue reproduce on other CS2 online demo viewers? I'm interested to know if this is an issue with this parser specifically, or with the data that is in the demo/how it was recorded.

I'm also interested to know if you've seen this in any other demos, or just this one? It's possible that the issue has been fixed in the various demo recording/playback bugfixes that Valve have made over the past month or so.

@saul
Copy link
Owner

saul commented Feb 21, 2024

I can't seem to reproduce victoria's coordinates ever matching 1024. This yields nothing:

        demo.EntityEvents.CCSPlayerPawn.AddChangeCallback(
            pawn => pawn.Origin,
            (pawn, _, origin) =>
            {
                if (pawn.Controller?.PlayerName == "victoria" && (Math.Abs(origin.X) == 1024 || Math.Abs(origin.Y) == 1024 || Math.Abs(origin.Z) == 1024))
                {
                    Console.WriteLine($"{pawn.Controller} - {origin}");
                }
            });

@in0finite
Copy link
Author

in0finite commented Feb 21, 2024

var demo = new DemoParser();

await demo.StartReadingAsync(File.OpenRead("test.dem"), default);

while (demo.CurrentDemoTick.Value < 1305)
{
    await demo.MoveNextAsync(default);

    var player = demo.Players.SingleOrDefault(p => p.PlayerName == "victoria");
    if (player != null)
    {
        Console.WriteLine($"[{demo.CurrentDemoTick.Value}] Victoria position: {player.Pawn?.Origin}");
    }
}

Console.WriteLine("\nFinished!");

Until tick 1240, his position is { X = 1024, Y = -1024, Z = -1024 }.
This is when the round starts.
Then, until tick 1301, his Z coordinate stays at -1024.
And then, his position is correct.

This is all visible in demo viewer.

@in0finite
Copy link
Author

in0finite commented Feb 21, 2024

Does this issue reproduce on other CS2 online demo viewers? I'm interested to know if this is an issue with this parser specifically, or with the data that is in the demo/how it was recorded.

I'm also interested to know if you've seen this in any other demos, or just this one? It's possible that the issue has been fixed in the various demo recording/playback bugfixes that Valve have made over the past month or so.

I didn't test it with other online viewers.

I've seen this in many demos. And not just in the 1st round. It seems random.

Also, there is still a bug with pawn's position jittering. It just happens more rarely than before. I think it's connected to this bug.

@in0finite
Copy link
Author

I just opened #45 . I suspect it's the same issue.

In the same demo, you can see pawns outside of buy-zones : pause & demo_seek_tick 86464. kyxsan is outside.

Another example: same match, but on Nuke. Beginning of 2nd round (1-0 score). zont1x is outside.

@in0finite
Copy link
Author

@saul I tested Golang library using the same demo. It gives different results :

tick 0 - 1240 (round starts at 1240): position is (1296.000000000000000000000000, -64.000000000000000000000000, -167.968750000000000000000000)

tick 1240 - 1300 : X and Y coordinates are changing, Z stays the same (-167.968750000000000000000000)

tick 1300 - ... : all coordinates are changing

========================================
In comparison, here are the results of this library :

tick 0 - 1240 (round starts at 1240): position is (X = 1024, Y = -1024, Z = -1024)

tick 1240 - 1300 : X and Y coordinates are changing, Z stays the same (-1024) , note that XY are identical to Golang library so they are correct

tick 1300 - ... : all coordinates are changing, identically to Golang library

===========================================

This makes me think that in some occasions, some entity properties are not updated at all (they are skipped).
So, at tick 0, XYZ offset is not updated, that's why it remains the same until tick 1240.
Also, at tick 1240, Z offset is not updated, so he remains the same until next time pawn changes position Z.

I can post the Golang code used for testing, if you need it.

@in0finite
Copy link
Author

in0finite commented Apr 12, 2024

After digging through code of both libraries for entire day, I finally nailed it.

Both libraries read the position from exact same location in bit buffer, but the difference is that BitBuffer.ReadUBits(32) will return 0 if bits available is 32, because 1 << 32 gives 1, so the mask ((1 << numBits) - 1) becomes 0.

Phiiuu 😓

This means that everything that uses BitBuffer.ReadUBits(32), BitBuffer.ReadFloat(), BitBuffer.ReadAngle(), FieldDecode.DecodeFloatNoscale(), is potentially broken and is subject to jittering from 0 to real value.

Maybe use pre-calculated masks, it's a hot path afterall.

@saul
Copy link
Owner

saul commented Apr 12, 2024

Amazing work - many thanks for this! Great catch :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
resolution/fixed type/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants