Hi Nicholas,

So you send key presses reliably, and then wait for the server to respond back 
with a new state? What happens if a player fires their weapon, for instance, is 
this sent reliably? I guess my main confusion is what should and what should 
not be reliable traffic. It would make sense to me that gunshots were reliable, 
where as individual movement steps could be sent unreliably as you say. Now 
let's say that the client takes a step, do you then render the movement 
animation immediately before you get the response back from the server and then 
correct it if the server refuses, or do you wait for the server to accept the 
move? If the former, what happens if the client moves but he's not allowed to, 
do you just silently bounce him back? If the latter, wouldn't there be a 
noticeable delay between the key press and the actual movement since we need at 
least one roundtrip for that?

Kind regards,

Philip Bennefall
----- Original Message ----- 
  From: Nicholas J Ingrassellino 
  To: Discussion of the ENet library 
  Sent: Wednesday, November 24, 2010 6:23 PM
  Subject: Re: [ENet-discuss] Best practises for synchronizing states


  I question if the lag is as bad as you are expecting it to be. Some 
connections and/or rural areas are worst than others but I am not sure it will 
be as bad as you think. For example, if you look back at the last few e-mails I 
sent to this list you will see my current project treats the client as a dumb 
terminal-- only key presses are send and object information is back unreliably 
20 times a second. There is some dead reckoning (the object speed and direction 
are sent to the client and the client does that work while waiting for the next 
update) and I do not have an issue even on my mobile phone.

  My point is you should run a number of tests to see what you get. Make sure 
to play with the rate the "server" (or in your case client to client) sends 
data vs bandwidth usage. Make sure you do not flood the line with too many tiny 
packets and that you process all packets in a while loop (vs an if) to make 
sure you processes everything as fast as possible. Another note on my project 
is that I do not wait on an timers to process network events (as opposed to my 
log and display code that only happens 60 times a second).

  I think you may surprised yourself with what you can pull off in terms of 
latency.



------------------------------------------------------------------------------

  Nicholas J Ingrassellino
  LifebloodNetworks.com || [email protected]

  "The idea that I can be presented with a problem, set out to logically solve 
it with the tools at hand, and wind up with a program that could not be legally 
used because someone else followed the same logical steps some years ago and 
filed for a patent on it is horrifying."
  - John Carmack on software patents


  On 11/23/2010 10:00 PM, Philip Bennefall wrote: 
    Hi all,

    This is a fairly lengthy email, so I apologize in advance.

    I am relatively new to ENet. I have integrated it in my game engine and 
have successfully written a game which is working perfectly. It is one of those 
finger twitching action games where speed is of the utmost importance and delay 
is the most evil thing in the world. The way I do it is to keep sending the 
entire state for a player to the other party unreliably. The other client then 
works out the events that "must" have occured by looking at the differences 
between the last known state and the new one. This is far from a perfect 
solution as it neither scales well nor provides for very readable code. Here's 
a summary of how I'm handling things:

    The game is a shooter where you run a round on a 1d grid firing rocks at 
your oponent's palace. When a rock hits a square on the other side it'll 
quickly begin piercing its way through until that section of the wall crumbles. 
During that time, the other player may use their hammer to defend the section.

    I wrote an internal layout description for myself before I started coding, 
which I then followed to ensure proper handling of all possible situations.

    ---Start of Internal Description---
    The way in which this game communicates over the network is fairly simple. 
The two players have a direct connection established between one another, and 
they send out their player state roughly 30 times a second. This player state 
contains the current x position, the current throwing position which is -1 if 
nothing is being thrown, and then a list of all the squares on that player's 
side. For each square, two values are stored. The first is the current 
resistance which is 20 on max, and 0 if the square is destroyed. The second one 
is crumbling speed which is 0 if the square is not currently crumbling, and a 
value in milliseconds otherwise. This value is used to measure if two or more 
rocks have been thrown on the same square.

    When a new state is received from the remote player, we have to analyse 
this information in order to determine what changes that have occured and if we 
need to take any action.

    If a new x position is received, we simply move the player's local variable 
to this square and play a footstep sound.

    If the new throwing position is different from our old one, we can take a 
few actions depending on its value:

    1. If the new one is greater than -1 and the old one is -1, the remote 
player threw a rock at us. we play the throwing sound in the appropriate 
location, but take no other action.

    2. If the new one is -1 and the old one is greater than -1, we can assume 
that the remote player hit us and start the crumbling sequence for that square 
on our end. Naturally if our square is already crumbled, the remote player will 
not get any hit notifications from us. 

    3. If they both are greater than -1, we can assume that the remote player 
hit us and so we activate that sequence as above. We can also assume that the 
remote player made a new throwing attempt in another location and that we 
didn't see the -1 state that came prior to it probably because of lag, and so 
we play another throwing sound in the new location.

    After this, we go on to scan the game board and do the following for each 
square:

    If the new resistance is greater than the old one, the remote player 
hammered and so we play that sound.

    If the new resistance is lower than the old one, we can take four actions.


    1. If the new resistance is 0 and the old resistance is greater than 0, the 
square just broke so we play the appropriate sound and forget about it.

    2. If the old crumbling speed is the same as the new one, this was a normal 
crumbling step and so we play the appropriate sound.

    3. If the old crumbling speed is 0 and the new one is greater than 0, this 
was a new hit so we react accordingly.

    4. If the old one is greater than the new one and the new one is greater 
than 0, this was a new hit on the same square.
    ---End of Internal Description---

    I realize that this is a lot of very game specific information, and that's 
exactly my point. This all seems like a very dirty hack to me, and I was 
wondering if any of you can suggest a better and more scalable way of doing 
this while still keeping latency to an absolute minimum?

    Thanks in advance for any help!

    Kind regards,

    Philip Bennefall
    P.S. I should perhaps mention that this is a game for the blind; entirely 
based on sound, which is why sounds are mentioned all over the place rather 
than graphics.

_______________________________________________
ENet-discuss mailing list
[email protected]
http://lists.cubik.org/mailman/listinfo/enet-discuss
_______________________________________________
ENet-discuss mailing list
[email protected]
http://lists.cubik.org/mailman/listinfo/enet-discuss

Reply via email to