frootloopsI think you're fundamentally missing where the prediction happens. For me, source prediction happens on the client, based on what was last given by the server.
There's a fundamental misunderstanding here. Source does not predict, it interpolates because it already knows what's going to happen. The client is always so far behind the latest packet it recieved (well, not if the interp is too low) that it does not have to predict the future. E.g. the client got packets from time t and t+1 and is rendering time t+0.5. It doesn't have to guess where everything will be, it can interpolate that it'll be halfway between the positions at 0 and 1. By the time the client gets around to rendering t+1 it should have recieved the packet from t+2. This would be interp_ratio 1, the bare minimum, usually it's even more packets so the guess can be better than "halfway" and account for changing movement speeds.
TwiggyWhy not? I believe most of the time when a client requests to spawn an projectile it is allowed to do so. If the client dies after predict spawning a projectile but before the projectile existence is confirmed by the server, then only that dead client will see some kind of visual artifact. And that client's dead anyway, no big deal.
Yes, it's much less of a problem in games without stuns but you still have to clean up the dead projectiles (more code), generate more salt because the player sees his own projectiles spawning and then disappearing and the teleporting problem still exists. It's not worth the trouble.
TwiggySure, my question now is, if it's the first case, can you mitigate how much the projectiles teleport by increasing what i believe is named interp, which is delay between what state is computed by server and what state is rendered by clients?
If everyone is living in the past and a projectile instantly spawns locally then it has spawned in the past exactly as far behind the present as the player is. Except no one but the player knows about it. Everyone else will see it after the usual delay that ping/transmission time and server processing time adds. If you want everyone to see the same thing then at that time it must appear where it has already traveled to on the shooters side, meaning it has to teleport.
TwiggyCould you elaborate on why this is a bad idea for hitscan things?
frootloops already answered the technical side but I think I should add something you're missing: These are completely different use cases.
Fighting games have predetermined animations that will always play out the same and fixed framerates.
TF2, or any fps for that matter, has neither. Any movement can be canceled or even reversed at will. That is a fundamental requirement for dodging. In a fighting game you get an input an know what will happen for the next 20 frames. Fps don't get that. Anything could happen in the next frame. Any attempt to predict when which input will happen is doomed to fail.
On top of that no one will have the same framerate. A delay of 3 frames is meaningless when someone could be dropping to 30 fps and someone else might still be at 300 fps. You're not even in sync with the server's fps. So instead you get another problem: You can't use the server's snapshots directly. Your 144 fps are not in sync with the server's 66.6667. You will not get a snapshot for every frame you render and even when you do get one it isn't necessarily from the exact same time that your current frame will be. So you need to guess for possible states between the servers snapshots. Prediction is useless so extrapolating from past snapshots towards the future is a fool's errand and should only be done when there's no other choice because guessing movement will continue as is is at least better than freezing everything. So what do you do? You don't render the latest snapshot, you put your personal time at least one snapshot behind the latest one recieved and interpolate between it and older snapshots.
The end result is that you have to interpolate and you can't predict others' inputs so you might as well use interpolation for that as well. (see first paragraph)
Also something I should've added when you asked about TF2 being deterministic, but thought it would be complicated and unnecessary in this case. Thankfully Taat (#9) reminded me that it is relevant in this case.
TF2 should be deterministic, but isn't in practice because the source engine's physic calculations are fps dependent. Now that isn't good, but it is unavoidable because when your fps fluctuate and aren't in sync with anything sometimes you have to calculate 0.0034782378623425 of the movement per second because that's just what fraction your framerate is and there's only some much precision you have and then the rounding errors add up. This isn't a problem in a server based game because the errors are tiny and the server can assert its authority and bring everyone back on the "right" track (the slightly wrong track it has chosen instead of the other slightly differently wrong tracks everyone else has chosen) by the next snapshot. In a peer-to-peer game that assumes every input has to same result from everyone's perspective however you are fucked. Everyone's game state would drift further and further apart. Even if you try to synchronize regularly there's no way to decide on a "correct" state. Everyone is wrong, just in different ways.
Fighting games and fps are fundamentally different use cases, using netcode made for one in the other would have terrible results.