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

Fixes some player's origin displacements for fire events, impulses commands… #442

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

XutaxKamay
Copy link

@XutaxKamay XutaxKamay commented Dec 20, 2017

Idk when, soz.

... Previously some years ago ...

This fixes shooting problems and others things while pressing a button while moving etc.

https://www.youtube.com/watch?v=VPT0-CKODNc

Another example (the radar describes perfectly the problem):
https://www.youtube.com/watch?v=pr4EZ06mrpQ

Why is this happening?

Well, this is happening mainly because of interpolation, and how the function RunCommand works finally. Let me explain.
In fact, the taken shooting position is the new one computed from the game's movement, and not the current one.
You can see this happening by using timescale, and getting some speed.

The game is computing the new interpolated localplayer's data from the prediction data (BaseInterpolate1 from C_BaseEntity) by getting the final predicted time (so the final predicted command) and removes a tick interval to actually take the previous final predicted time , for having data to interpolate with! , and adds a tick interval where it's mulitplied by interpolation_amount (this is computed per frames, and it goes to 0.0 to 1.0) to go on the final predicted time, wich finally goes to what you should see.

If you try to interpolate directly from the final predicted time, there wouldn't be any data to interpolate with, so that's why Valve is removing a tick interval on the final predicted time to interpolate the localplayer.

But it makes issues on player's gameplay we must remember that since the commands are ran per ticks, the changes are instantaneous, so when you're actually firing, you're still on the previous predicted time, and not the final one.

You see the world and shoot as it was previously 1 tick before and not when it was when firing when you move.

The solution of what you would think of would be of course to disable interpolation on a player side,

but that would not make a smooth gameplay (so makes still a game unplayable) and the player wouldn't even predict his next position to actually shoot at the head of the player correctly anyway (or he must be a real machine to do that) ,
but why?

Since the game is running the commands per ticks (this is not really true on client-side prediction or even server-side due to dropping packets but to make it easier to explain) you'll suddently "teleport" to the other side and see your bullet at that position, instead of seeing your shot behind, as expected and predicted by the player.

So the solution is just to call PostThink (wich handles mainly fire events, impulse stuffs etc), before applying the final data to the player, so interpolation is not a problem anymore, the weapons take the right origin to shoot the bullet with, and much others stuffs! Like collision bounds, or when you're actually landing with high velocities, it stops the falling velocity at where it should and not 1 tick before. (bunny hopping purposes)

https://steamuserimages-a.akamaihd.net/ugc/909030263364841206/048560EB944800B68FF1F52920763D5B66231AE7/

Here is a view example of what is happening, blue = what the game actually see, red = what the player saw in the game.

The more lower the tickrate is, the more it is shifted and maybe unplayable.
Imagine servers with 33 ticks, the shift might be too much even for 100 velocity units, it's like 3 units of displacement or more

I hope valve and people will understand what I explained and hopefully this gets fixed on all valve games so we get a proper gameplay for everyone! (Yes since I guess valve is using this code for every games, it needs to be fixed on every games)

Also not to mention that every hacks will break since they're using the gamemovement's to predict their current commands since it's not truely a prediction problem anyway.

Good day and thanks for atleast reading!

PS: Sorry for my english if it's not correct, but if I get understood, it's the more important.

@TotallyMehis
Copy link

Here's a test I did:
https://youtu.be/VYs0-lUwWas

Seems to hold up.

…sed before the player's thinkings, fixed it by moving the processed impacts before thinking functions.
@XutaxKamay
Copy link
Author

XutaxKamay commented Dec 22, 2017

Exactly there is no point running client side lag compensation, but prediction does. I didnt mean something else, sorry again if you understood something else. And yes I've read that.

" You also have to remember that because the server beholds a random seed that’s purposely different to the clients to stop the client predicting the seed, the shot you fire doesn’t appear where you see it on your screen because the seeds are different and not given to the player to prevent calculation of the spread thus nospread "

(CS:GO has servers with a custom random seed wich makes the prediction a bit useless for local bullets/shooting stuffs, but that's another story, it was meant to stop cheaters abusing the prediction for their aimbots and etc..)

I know.
Though I don't know if people are reading correctly sometimes..

@geotavros
Copy link

Are you sure this issue is not related to the slow motion you enable to test it? I mean, did anyone test it while not in slow motion? For example, recording a 300 fps video while the game is in real-time and then checking this video out.

@XutaxKamay
Copy link
Author

XutaxKamay commented Dec 27, 2017

Though this pullrequest break with physics props (thanks gocnak) still, so I'm going probably to commit another fix for it. The simple solution would be to take the old origin of the player before calling the game movement and set this origin for shooting position , but it won't fix others things.

@XutaxKamay
Copy link
Author

2 years later.. I really need to re-work on it properly.. That'll come.

@Kefta
Copy link

Kefta commented Oct 28, 2019

We are eagerly awaiting

@Everlastingbulletlag

This comment has been minimized.

@XutaxKamay
Copy link
Author

XutaxKamay commented May 8, 2020

Pls no hate, love.
I'm sure they're aware of it but probably busy with some others stuffs we don't know yet? (Source2 or VR) I know your frustration though I wish I could at least make signed Valve Client Plugins so I can load custom stuff inside game's client to fix some bugs or add functionalities, I've even tried to email them about it but I did not get any replies yet.
Anyway yes you made me remind that I need to re-work on it haha, I've so much to do that I end up doing nothing sometimes. Need a todolist

PS:
maybe they're just waiting me to finish this properly without breaking changes so they can copy it safely, who knows <.<

@Kefta
Copy link

Kefta commented May 9, 2020

We'll be here when you finish it king.

@KillaBoi
Copy link

KillaBoi commented Feb 3, 2021

thanks for approving this KillaBoi

I did this like a year ago, Valve doesn't care about it :(

@XutaxKamay
Copy link
Author

Hey it's been 2 years again, I said I should have worked on it, but guess what...
I did nothing. ( ͡° ͜ʖ ͡°)

Time passes, and now I realize it's been already 4 years I did that pullrequest and it has been 10 years since I've been starting to code on that engine.

No really, I think this should be on top of my priorities so it can be even considered to be implemented in valve's code, like I said they probably waiting for me in secret to finish it... I must tell that they're not very communicative sometimes, probably busy I don't know.

I saw that there was a CS:GO update about making custom client plugins that could be used to fix the game, I think I tried to email them about it so mine could get signed by them, but I don't even know if they saw it.
I mean I could be even ready to share it publicly with source code available with some quality fixes/changes.

@KillaBoi
Copy link

KillaBoi commented Feb 5, 2021

Hey it's been 2 years again, I said I should have worked on it, but guess what...
I did nothing. ( ͡° ͜ʖ ͡°)

Time passes, and now I realize it's been already 4 years I did that pullrequest and it has been 10 years since I've been starting to code on that engine.

No really, I think this should be on top of my priorities so it can be even considered to be implemented in valve's code, like I said they probably waiting for me in secret to finish it... I must tell that they're not very communicative sometimes, probably busy I don't know.

I saw that there was a CS:GO update about making custom client plugins that could be used to fix the game, I think I tried to email them about it so mine could get signed by them, but I don't even know if they saw it.
I mean I could be even ready to share it publicly with source code available with some quality fixes/changes.

sharklaser tried to fix desync/antiaim back in 2018 and even released source code to fix it and emailed them about it but they didn't even bother with fixing that so i doubt they'll implement any of this tbh, it sucks but theres only so much u can do... you can release it if u think it'll help modders using the sdk in the future or smth but ye :/

@XutaxKamay
Copy link
Author

XutaxKamay commented Feb 5, 2021

Well, if its purpose is to be used on CS:GO it is quite useless because matchmaking servers are hosted by Valve. So I doubt to see it any of it soon.
But the community servers can already have that fix for their shooting position I've made one for sourcemod for almost all games.
The problem with it is that it breaks prediction for bullets, it would need a fix also on client-side, but that can't be done at the moment I guess. Although it is more a problem of a cosmetic effect.

@osiris-plus

This comment has been minimized.

@micwoj92

This comment has been minimized.

@KillaBoi

This comment has been minimized.

@micwoj92

This comment has been minimized.

@Kxnrl
Copy link

Kxnrl commented Apr 10, 2022

Replying to #442 (comment)

I can not find that pr or src from github/google, can you share the link?

@7kazan
Copy link

7kazan commented Sep 16, 2023

How can I apply this fix to no more room in hell ? I tried here it doesn't work

@XutaxKamay
Copy link
Author

XutaxKamay commented Oct 19, 2023

I repeat it but, the pull request is not ready to be merged into any source engine mods/games.

Due to recents events with "sub-ticks" hype with a lot of confusion about what it is doing and since some people wanted my input on this,
I think it is a good idea to start discussing about it now here to get more into details of what we would need to do to solve this problem, because this is not an
image issue at the contrary that some people would think.

I'm glad Valve finally addresses solutions to this problem, but there's a lot of issues around it still and I'm not even talking about exploits possible with it. (rapid fire, the fact that you can technically gain more acceleration than in "normal" ticks, etc.)

Now, let's talk about again of the core issue, interpolation between ticks and what is shown to the player:

One thing is true, what is shown to your screen is an interpolated position, and does not reflect in any ways your real position except in one case, when cl_interpolate is 0.

Remember that if you fire here without interpolation, the position is being 1 tick off when you fire, and it is not due to interpolation, but just mostly how RunCommand works as explained above.
So the "sub-tick" doesn't solve that problem entirely, except if that delay is taken into account, though since the logic for RunCommand didn't change I believe, the issue should be still there technically. (EDIT; I just checked they actually send the whole eye position + angles it seems, which solves that problem but unintentionally, the core of the problem is still somewhat here, even in prediction)

Now the real problem that Valve is talking about here is that there's a delay between when a tick has fired and what is shown to your screen,
and that delay needs to be taken into account too, it is not a problem to know when someone pressed a button since we know already that information,
the commands are already created in CreateMove per ticks and not per frame basis,
so there's no delays here in the first place, the prediction and interpolation does its job already here and commands being processed correctly in ProcessMovement.

The delay that truly exists is the moment where you click on your mouse and the tick which creates the commands, which is why sub-tick seem to exist, but then, this is not only the whole server logic which needs to be re-thought about, but the whole client aswell including prediction, which means that every tick is a frame, and a frame is also a tick. It isn't a game based on ticks then, but on frames.

This is really expensive and it just ignores why in the first place constant tickrate exists, for consistency and performance. You could claim it would be better this way since it has less delays to your inputs and could be more accurate, but there's always delays in your computer in order to synchronize, even electricity is delayed by the speed of light.

Now, we could always make buttons/angles based on frames still for when a specific event like shooting happens and leave alone movements on ticks, but this is a totally different logic here, since the movement and "event" logic would need to be seperated and we would need to define what is an "event" exactly, since buttons are also used for movements. (And I don't even talk about the cheaters problem getting worse)

The only thing that seems to be really calculated per frame basis and is legitimate are angles, which of course aren't predicted or interpolated in any ways, but to me it is a minor problem: (a lot of useless blah blah here)

The angle change is only visible during frames, but not on the tick itself, so where you're aiming at, after CreateMove is called, you won't be aiming anymore where you'd want it to aim at due the fact that in few microseconds, the function is modifying viewangles. And unfortunately could be resulting in missing opponent's head in some cases.

Sure, instead, we could make sure that viewangles should be not modified in CreateMove atleast only after the command is being created if you wanted accuracy for the player, they should be taken as inputs during the frames, but there's a problem here:
viewangles are important for moving which isn't desirable for bhoppers/surfers, so we can't simply say "let's avoid modifying viewangles in CreateMove" to have better accuracy,

it might be even not a good idea for most players too, since during that tick they can adjust the angles to where they'd want it to go and resulting into a headshot, so perhaps this is maybe actually a desirable effect.

Though if you wanted really a solution, what I can think of right now if it's really needed: there's maybe a need for two viewangles variables here in the CUserCmd structure: one for movement and one for event based stuffs like firing, pressing a button, etc.
But it could be negligible anyway, this is not the really the important point for me.

I'm pretty sure Valve thought about what I said above already; but I'm afraid that sub-tick introduction is making more problems than it should be doing.

Now, the second problem that sems more important to me: position, or eye's position of the player to be exact; I would think more of doing something like this:

Instead of having a full sub-tick, consider this: since it is an interpolation problem, it may aswell considered as a latency problem.
If it's a latency problem, then it is a lag compensation problem.
I think you get the idea now.

We could just send in CUserCmd the delay:

  1. between the last frame is fired and the new tick incoming, if for example the local player is still being interpolated but the shooting event is fired and being animated before the next tick, but I'm not sure anymore if that's what really happens, I think it does wait for the tick to fire before shooting and events, so second case.

  2. between last tick and first frame, in that case, we need to delay a bit when the engine sends commands to server to accumulate that interpolation information, sending for example interpolation_amount would do the job to lag compensate the local player to that specific frame when someone does a specific event like shooting. It is possible to interpolate because the server will be able to know the next position with ProcessMovement.
    If my memories are correct, that interpolation is linear only, so there's no issues here doing that with accuracy, no extrapolation.

EDIT: there's a case when fps is equal to tickrate or is below, in that case interpolation amount should be zero if I'm correct and the command should be sent directly.

Perhaps this is maybe what Valve is doing, if yes, then great (not that great though, it will be still a room being exploited by hackers in the future). If not, I'm afraid it will take some time before implementing this and prooving it works.

Anyway, I may be not correct on some things but I do believe that sub-tick isn't that necessary in my opinion, it's only a room exploitable for hackers.

I just wanted to be clear that these two problems are very related, but they are technically very different to the core.

@XutaxKamay
Copy link
Author

XutaxKamay commented Oct 19, 2023

I just tried out a bit CS2 today, and my feelings seems to be what I thought it is.
I'm very sad to see that cl_pdump is not working anymore in CS2, which is used to show prediction errors, but I can clearly see that there is a lot of prediction errors going on here.

https://files.catbox.moe/qsmyr5.mp4

This is with noclip, and nospread. What we see is that it does indeed take the shot where I clicked, but I would expect it to wait for the firing animation (so the tick) for the blue bullet to appear right in front of me instead of being where I clicked.

Sub-tick is breaking prediction and you can see that by the way I'm lagging after the next tick, and this must be normal since CS2 doesn't seem predict the sub-ticks at all.

I'm also getting some acceleration I shouldn't have; and I don't think that is the right behavior here of course.
This problem occurs because a fraction/interpolation_amount needs to be applied in every game movement code carefully placed.
I'd like to take one comment from reddit: https://www.reddit.com/r/GlobalOffensive/comments/17aot1c/subtick_movement_fixed/k5gwad8/

To me the whole sub-tick system seems to be conceptually wrong, even if they fix prediction.

Anyway what you see here is not CS anymore, it's another game based on frames.

One way to conceptually fix it is to do like I said above, the whole logic for "events" like shooting needs to run on a entirely different logic than movement if you want to do it per frame basis.

That way even during timescale being very low, it is still possible to shoot any time we'd want to and not waiting forcely for a tick to happen before seeing the fire animation and the bullet. We could also easily interpolate the position based on X "event" (reloading, shooting, openning a door, anything that interacts with something) which is sent with a fraction (could be interpolation_amount) to the player.
This would need to be done asynchronously instead of being inside tickrate logic at all. To do that, quite a big part of the source engine needs to be modified in order to not break anything, which is a lot of work, but possible.

But I'm not sure how well that will scale, especially for cheaters and performance:

  1. A cheater could possibly teleport back himself in the line of his previous movements, including other stuffs if not done properly. (like rapid fire)
  2. Since it will be async, more CPU usage, though that doesn't mean necessary that it will affect badly server side performance, but generally, when more cores are used the CPU clock tends to drop down due to TDP etc. Though actually I might correct a bit what I said earlier, it may affect the performance in a good way since the logics are seperated since the tickrate one will be lightened.
  3. Triggers will need also proper care for those that are based on shooting or other "events".

By the way if prediction breaks, I wonder where they can take the interpolated shooting position, since position and networked variables (punchangles) are mostly (smoothing) uninterpolated during predictions errors, shouldn't be a problem though if they send directly angles and eye position.
Prediction failures and sub tick doing wrong stuff on movement/punchangles is probably why some people have hard times spraying or doing anything in that game after pressing some keys.

@XutaxKamay
Copy link
Author

XutaxKamay commented Nov 9, 2023

Fun fact; if you do cl_predict 0, it still demonstrates perfectly the problem described in the pull request.

Like I said, this isn't a problem with interpolation much in the first place. (I haven't reverse engineered the game yet, I just know they take the eye position from here, that command prooves it, which is an issue)

It also seems they fixed prediction for their sub-ticks too, which is a good thing, it was really an issue before.

It's gonna take a while for them too to implement it properly by applying a fraction (gpGlobals->interpolation_amount or something else) everywhere in the game movement and physics, Think functions, etc.
Sadly even with those fixes it will stay mostly with the same inconsitencies simply because the game isn't based anymore on constant tickrates.
Performance wise, it's not really great either since it's doomed to run equal or more ticks than a constant tickrate.

I won't bash at Valve I think they expected us to be happy with it but to be honest I would be happier with them removing it for now and thinking of another solution to fix interpolation problems that doesn't affect tickrate.

@Nairdaa
Copy link

Nairdaa commented Nov 17, 2023

I'm so glad Kamay showed up again and is back with great input. I honestly hope Valve does take a deeper look into what they have done (and in my opinion, broke) and fix the game.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet