Jump to content

Client Side Prediction with a Physics Engine


And_re
 Share

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.

Link to comment
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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...