Projectile prediction, how is it done in other engines?
by Stefan Lundmark · in Torque Game Engine · 02/07/2007 (8:52 am) · 16 replies
Projectile prediction, how is it done in other engines?
Other engines handle projectile prediction differently than Torque, which sends the transform, vector, speed and the source object ID as a ~80 bit packet to the client, per projectile.
Does anyone know how other engines handle this? Especially so, how do they handle the random vector of each projectile, which is not predictable? Do they update the value per shot, or do they keep a sequence (perhaps exchanged during the mount of that weapon?) which the client and server uses to simulate random paths?
If anyone has some outside information or just some random brain fart, I would be happy to hear it. :)
Cheers!
Other engines handle projectile prediction differently than Torque, which sends the transform, vector, speed and the source object ID as a ~80 bit packet to the client, per projectile.
Does anyone know how other engines handle this? Especially so, how do they handle the random vector of each projectile, which is not predictable? Do they update the value per shot, or do they keep a sequence (perhaps exchanged during the mount of that weapon?) which the client and server uses to simulate random paths?
If anyone has some outside information or just some random brain fart, I would be happy to hear it. :)
Cheers!
About the author
#2
I dont think there would be any use of keeping a sequence to generate random paths, it's probably more like this.
Client sends the signal that a bullet is fired
server decides the random vector, and tells the client (as well as any other clients) everything it needs to know.
What i mean to say is that the client that fired the shot probably has nothing to do with the random vector. If it did, you would run into the same cheating problems that plagued the original counterstrike.
02/07/2007 (10:14 am)
I think he's refering to the random nature of say, the spread of fire that a machine gun put's out. (most games have a gun like that spreading fire in a small cone of fire)I dont think there would be any use of keeping a sequence to generate random paths, it's probably more like this.
Client sends the signal that a bullet is fired
server decides the random vector, and tells the client (as well as any other clients) everything it needs to know.
What i mean to say is that the client that fired the shot probably has nothing to do with the random vector. If it did, you would run into the same cheating problems that plagued the original counterstrike.
#3
02/07/2007 (10:16 am)
Rule of thumb for stopping cheaters. The more the server takes care of, the less the client can fudge.
#4
Yes I am talking about the random direction which a projectile travels at.
The client does not "take care of it" - it just knows what the next vector will be. I know it is prone to aimbotting, but I am interested in this from a performance perspective. :)
I guess they probably stuff the vector into the packet somewhere. Anyway, the packets which Source sends are very small, and that is what caught my interest! They probably do not send the actual ghost of the projectile, position or speed, which is what I am going to try.
02/07/2007 (10:33 am)
Thanks guys.Yes I am talking about the random direction which a projectile travels at.
Quote:
Rule of thumb for stopping cheaters. The more the server takes care of, the less the client can fudge.
The client does not "take care of it" - it just knows what the next vector will be. I know it is prone to aimbotting, but I am interested in this from a performance perspective. :)
I guess they probably stuff the vector into the packet somewhere. Anyway, the packets which Source sends are very small, and that is what caught my interest! They probably do not send the actual ghost of the projectile, position or speed, which is what I am going to try.
#5
Regarding the packet size, maybe you could remove the speed of the projectile and substitute it with a "projectile type".
Let's say that you have, for example, 8 or less different projectile types, then you just need 3 bits. Both the server and client will know what is the speed for each of them.
Even the projectile starting point could be removed and desumed from the position of the firing object, but only if you are absolutely sure that server and client are perfectly aligned...
Hope this helps (remember, I'm no expert... :-) )
Bye,
Jacopo
02/07/2007 (11:12 am)
If you do not care about cheating, then you could just send the final vector (that is, the vector of the projectile modified by the random factor).Regarding the packet size, maybe you could remove the speed of the projectile and substitute it with a "projectile type".
Let's say that you have, for example, 8 or less different projectile types, then you just need 3 bits. Both the server and client will know what is the speed for each of them.
Even the projectile starting point could be removed and desumed from the position of the firing object, but only if you are absolutely sure that server and client are perfectly aligned...
Hope this helps (remember, I'm no expert... :-) )
Bye,
Jacopo
#6
02/07/2007 (11:37 am)
The problem is not speed or the vector, the problem is that when the projectile is created on the server, it is ghosted to the client.. that's alot of data to send right there.
#7
Can't quite remember what they do for something that sends a lot of "bullets" at the same time (like a shotgun), it's possible the only thing sent over the net is one "bullet" and a "spread" variable and then the server just makes an educated guess as to what was and wasn't hit.
02/07/2007 (12:50 pm)
As far as I know half-life (as in source), does not use "projectiles" for things like bullets. Bullets in half-life are basically just a ray trace, the bullets arrive at it's target instantly. No need to send continuous packets or create objects/ghosts, it sends one packet and that's it. Can't quite remember what they do for something that sends a lot of "bullets" at the same time (like a shotgun), it's possible the only thing sent over the net is one "bullet" and a "spread" variable and then the server just makes an educated guess as to what was and wasn't hit.
#8
02/07/2007 (12:58 pm)
They use hitscan for machineguns/shotguns, yeah. Basically a raycast and an explosion at the end of it. What I'm interested in is the network mechanics behind it :) You know, the client still needs to know the vector of the ray before rendering it.
#9
02/07/2007 (1:01 pm)
Well, sending two positions (start position, and where it hits) back and forth between the server and all clients doesn't sound like it would take much networking resources...
#10
32 clients in scope shooting 15 shots (each) per second gives a load of 249 kB per second.
Pretty exagurated example, but I would like to get that number down nevertheless.
Edit: Disregard the numbers above. I was assuming that BitStream::getStreamSize () was returning the length of the BitStream for that particular projectile, not for other streams as well.
02/07/2007 (1:36 pm)
All you really have to do is send the random number used to project the vector. The position can be gotten from the clients version of the muzzlePoint, assuming that client/server are in sync. Even if they are not, that is not a big deal since the simulation depends on the server and not the client.32 clients in scope shooting 15 shots (each) per second gives a load of 249 kB per second.
Pretty exagurated example, but I would like to get that number down nevertheless.
Edit: Disregard the numbers above. I was assuming that BitStream::getStreamSize () was returning the length of the BitStream for that particular projectile, not for other streams as well.
#11
02/07/2007 (3:40 pm)
How about not ghosting the projectiles? You could create them on the client rather than ghosting from the server. This would reduce response time on them showing up and reduce some bandwidth. Depending on the type and use of projectile, the player probably wouldn't notice that the client and server versions are slightly out of synch.
#12
I am down to 12 bits per projectile now, from 81 bits. And the client predicts the random vector properly (8 bits). The only problem left is getting the source ID across and that is going to take a few bits.
02/07/2007 (4:03 pm)
That is what I am doing right now! Pretty cool idea Brian. Thanks.I am down to 12 bits per projectile now, from 81 bits. And the client predicts the random vector properly (8 bits). The only problem left is getting the source ID across and that is going to take a few bits.
#13
So, with this idea, you create the projectile on the server and client. The server still determines collisions (damage/points) and the client determines the explosion when its version of the projectile hits something?
Stefan, can you elaborate on what you are sending (e.g. the 12 bits)?
Thanks
Todd
02/07/2007 (4:29 pm)
This is interesting.So, with this idea, you create the projectile on the server and client. The server still determines collisions (damage/points) and the client determines the explosion when its version of the projectile hits something?
Stefan, can you elaborate on what you are sending (e.g. the 12 bits)?
Thanks
Todd
#14
In my case, the first 4 bits are the move/fire states, and the next 8 bits is the number used to randomize the projectiles direction of travel.
The only problem I have left is to get the projectiles to render. Since they are created on the client, some mechanic somewhere thinks they are server objects and will not call the render methods.
02/07/2007 (4:54 pm)
Yes, that is the idea. If the simulations are different, the projectile might explode earlier on the client than the server or vice versa. That is hardly a big deal with high ROF guns, which is what I am using it for.In my case, the first 4 bits are the move/fire states, and the next 8 bits is the number used to randomize the projectiles direction of travel.
The only problem I have left is to get the projectiles to render. Since they are created on the client, some mechanic somewhere thinks they are server objects and will not call the render methods.
#15
Couldn't you have a static data member for this new projectile class that is the seed for its randomization calls. You only send the projectile seed over the network once at the beginning of the mission. Then, as long as you have the same number of "create projectile" calls on the client as on the server, you wont need to send the 8 bits for every burst of fire.
Todd
02/07/2007 (6:05 pm)
Just a thought....Couldn't you have a static data member for this new projectile class that is the seed for its randomization calls. You only send the projectile seed over the network once at the beginning of the mission. Then, as long as you have the same number of "create projectile" calls on the client as on the server, you wont need to send the 8 bits for every burst of fire.
Todd
#16
02/08/2007 (3:14 am)
That is what I was trying to describe as a sequence in my topmost post. I am pretty sure that is sacrificing too much to the cheaters, though. However, you could use 4 bits instead and still get away with a pretty good spread or perhaps a combination of the two techniques, with a seed and a smaller number.
Torque 3D Owner Jacopo De Luca
Default Studio Name
What do you mean by "random vector"?
Are you talking about a single projectile that randomly changes direction, or are you talking about the spread of, for example, a machine gun where each projectile fired will have a slightly different direction form the others?
Bye,
Jacopo