Friday, August 13, 2010

Avoiding Latency (Investigation) in Faye

‹prev | My Chain | next›

Today, I begin investigating a my (fab) game problem I noticed when I first switch to faye for message communication—some messages are not quite as instantaneous as they might be:


Specifically, the collision detection / bounce effect does not occur at quite the same time in my screen as it does in other players' screens. When viewed from another room, my player travels quite a bit through the other player before snapping back (via a nice raphaël.js animation). On my screen, the bounce takes place almost immediately after the two players have overlapped.

Back in the comet days of my (fab) game, the bounce was much faster. So I am left with two possibilities: (1) faye is not quite as fast at broadcasting messages or (2) when I factored comet out, I left out some pieces. I will investigate (2) today—mostly because I am lazy (benchmarking is relatively easy, but would require a bit of setup).

Looking through the collision code, the collision is first detected in raphaël.js:
    if (!self.initial_walk &&
!self.mid_bounce &&
c_el != self.avatar.node &&
c_el != self.avatar.paper.bottom.node) {
Lotta conditionals there. If this is not the initial movement in the game, and the player is not already in the middle of a bounce / collision, and the colliding element is not itself(!) or the raphaël canvas, then the player starts a bounce. That's a bit complicated, but it worked in comet and no changes have been made since. So let's check out bounce_away():
Player.prototype.bounce_away = function() {
var x = this.x - 2*Player.radius*this.direction.x,
y = this.y - 2*Player.radius*this.direction.y;

this.faye.publish('/players/bounce', {id:, x: x, y: y});
this.bounce_to(x, y);
Here, I calculate the x-y coordinates to which the player should bounce to after colliding, then publish to all interested clients the need to bounce, then perform the bounce_to() locally. The "bounce" message published to all players in the room will inform them that my player needs to bounce_to() a new location in the room.

I do not believe that the order of calls have changed here as I switched from comet to faye, so it seems likely that there is some latency in faye itself. Before giving up on fixing my code and investigating latency in faye, I would like to see if there is anything that I can do to shift evaluation order.

So I take the stop() call that had been done in the initial collision detection and move that to a broadcast-able stop call in bounce_away():
Player.prototype._stop = function () {

Player.prototype._bounce_away = function() {

var x = this.x - 2*Player.radius*this.direction.x,
y = this.y - 2*Player.radius*this.direction.y;

this.faye.publish('/players/bounce', {id:, x: x, y: y});
The hope here is that, by broadcasting the stop message to all attached clients as early as possible in the collision evaluation, that I will simulate the collision more accurately. After teaching the room how to tell players to stop, I give the code a whirl:


Dang. That really did not seem to have had any effect at all. The stop/bounce of my player (fred) does not start in bob's room until well after it does in my room. Guess I need to investigate faye latency a bit (and ways to mitigate them). Tomorrow.

Day #194

No comments:

Post a Comment