And_re

Client Side Prediction with a Physics Engine

Recommended Posts

Hi,

I'm working on a game called HaxArena that is available here:
http://eu.haxarena.com/ | http://us.haxarena.com/ | http://eu2.haxarena.com/ | http://us2.haxarena.com/

and right now I'm trying to add Client Side Prediction based on the source code from http://www.gabrielgambetta.com/fpm_live.html. At the beginning I improved that demo by adding another dimension http://hax.droppages.com/ and now I'm trying to integrate that example with Matter.JS but I somehow can't make it work correctly e.g. I see some kind of rubber banding or the player starts moving faster and faster with every frame even though I don't press any buttons.

There are 2 functions available: 

Matter.Engine.update(engine, [delta=16.666], [correction=1]) - right now I'm using only this one on the server while I still don't have any Client Side Prediction; it's responsible for movement of all bodies and collisions

Matter.Body.update(body, deltaTime, timeScale, correction) - I'm trying to use it in the applyInput method of the Entity class

var Entity = function() {
  this.x = 0;
  this.speed = 2; // units/s
}

// Apply user's input to this entity.
Entity.prototype.applyInput = function(input) {
  this.x += input.press_time*this.speed;
}

I also tried changing some parts of this function:

Client.prototype.processServerMessages = function() {
  while (true) {
    var message = this.network.receive();
    if (!message) {
      break;
    }

    // World state is a list of entity states.
    for (var i = 0; i < message.length; i++) {
      var state = message[i];

      if (state.entity_id == this.entity_id) {
        // Got the position of this client's entity.

        if (!this.entity) {
          // If this is the first server update, create a local entity.
          this.entity = new Entity();
        }

        // Set the position sent by the server.
        this.entity.x = state.position;

        if (server_reconciliation) {
          // Server Reconciliation. Re-apply all the inputs not yet processed by
          // the server.
          var j = 0;
          while (j < this.pending_inputs.length) {
            var input = this.pending_inputs[j];
            if (input.input_sequence_number <= state.last_processed_input) {
              // Already processed. Its effect is already taken into account
              // into the world update we just got, so we can drop it.
              this.pending_inputs.splice(j, 1);
            } else {
              // Not processed by the server yet. Re-apply it.
              this.entity.applyInput(input);
              j++;
            }
          }
        } else {
          // Reconciliation is disabled, so drop all the saved inputs.
          this.pending_inputs = [];
        }
      } else {
        // TO DO: add support for rendering other entities.
      }
    }
  }

Something like:


var isSimulation = true

this.entity.applyInput(input, isSimulation);

and then using a fake / shadow body to apply an input and setting the final position of that fake body to the real body to avoid the rubber banding problem.

I will be really helpful if anyone gives me some advice or an idea of how to deal with these problems.

Share this post


Link to post
Share on other sites

Hi And_re

The scenario described by Gabriel Gambetta is for games where the movement is deterministic.  In other words, if the user was at position P(x,y,z), and the user pressed the right button 10 times (or for 10 iterations of the game clock) then the new position is exactly P(x+10,y,z).

This is quite common, for example in Real-Time Strategy games and First-Person Shooter games.

However in your game you have real physics, as you pointed out.  And Gabriel Gambetta's approach is not the one you need.  You can take a look instead at Gaffer-on-Games: http://gafferongames.com/networked-physics/the-physics-simulation/

And there is an open-source library (which I am a contributor to) called Lance.gg which does client-side prediction for multiplayer games.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.