2
\$\begingroup\$

I am building a simple multi-player fly-around-a-3D-world game in Javascript/webGL/websocket (Chrome, Firefox mostly).

How should I handle and process user input?

My preliminary design (untested) is to first just track which keys are down in the event handler:

var keys = [];

document.onkeydown = document.onkeyup = function(evt) {
   keys[evt.charCode] = evt.type == "keydown";
   keys[CTRL] = evt.ctrlKey;
   keys[SHIFT] = evt.shiftKey;
   websock.send(JSON({time: (new Date()).gettime(),
      down: evt.type == "keydown",
      key: evt.charCode,
      shift: evt.shiftKey, ctrl: evt.ctrlKey }));
};

and then, in my requestAnimationFrame callback, compute how many time-slices (say 20 per second?) have elapsed since the last render callback, and then compute that many time-steps using the booleans in the keys array to determine if to apply a left bank, right bank, up down and accelerate and so that time-step for each player.

How effective / responsive is this? Is there a better way? And is there a neater way to deal with latency than just backdating changes for other user's ships?

\$\endgroup\$
2
  • \$\begingroup\$ @Bane I don't think you even answered the actual question. Then again, most of my questions here don't get answers I'm happy with :( \$\endgroup\$
    – Will
    Commented Aug 14, 2012 at 11:23
  • \$\begingroup\$ Would you be satisfied with "Depends"? I just gave you an idea of what I think would be more effective and logical... I can't vouche for myself, but the rest of the site is pretty darn effective in answering questions, and if the questions don't get answered, maybe it's the asker's problem. \$\endgroup\$
    – jcora
    Commented Aug 14, 2012 at 11:41

1 Answer 1

1
\$\begingroup\$

Edit: there's a bug in your code.

At the new Date().getTime() part (you can write it like that, no need for extra parenthesis).

  1. Not all your clients are going to have the same time.
  2. One could easily change the date values being sent to your server.

So, that value isn't very reliable (in case you plan to use it for something important), you better calculate it on the server side.

Never, ever trust the client with anything other than their current state of input.

I strongly suggest that your movement has nothing to do with rendering.

I usually have one function called logic, and that function basically calls all the objects' update methods, and gives them the time passed. The player class, then, has an input listener, and in its function it checks which keys pressed, and depending on the time, reacts accordingly.

if (player.input.right)
{
    velocity.x = const;
}

//Do some physics.

position.x += velocity.x * dt

I call this logic function ~30 times per second, so it's responsive enough. As for the netcode, it's best to record input and only send that to the server. The server only sends back the difference in the game state since the last message (see: Backbone.js diff).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I agree with your sentiment, it was misleading to call my game loop callback 'render' and I've changed that. Regards your use of delta time, gafferongames.com/game-physics/fix-your-timestep is always a good link for anyone googling this later. \$\endgroup\$
    – Will
    Commented Aug 14, 2012 at 7:58
  • \$\begingroup\$ As a side note.. if timestamp is not coming from the client, then the server would favor players with better connections automatically, so overall I think that it would need some sort of time sync to determine average connection speeds for different clients so that i.e. modem and dsl -connections could compete against each other and game would implement requirement of "fairness" better. \$\endgroup\$ Commented Oct 23, 2013 at 18:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .