1 decade ago
by Joncom
Here's a
video showing the problem I'm talking about. What you see in the video happens anytime two clients have significantly different FPS rates.
A quick note: my multi-player movement works by only sending an update if there is a change in movement for an entity. So, for example, if a non-local player is moving up, there will be no updates from that player until he stops, or changes directions. His entity will keep animating and moving until told to do otherwise.
With that out of the way...
A client that's getting 45 FPS will see that clients who are getting 60 FPS are teleporting
ahead of where their entity was before they changed directions or stopped.
And a client that's getting 60 FPS will see that clients who are getting 45 FPS are teleporting
back from where they appeared to be before they changed direction or stopped.
I'm curious what kind of options I have, because I consider "constant movement rates" across clients to be very important.
I've thought about using a bunch of Date().getTime() functions and moving entities based on "time since move started". I'm not sure though... is this is the best approach?
1 decade ago
by dominic
How do you move the entities? If you use the built in
.vel
or
.accel
properties, the speed should be constant, regardless of the frame rate. If you manipulate
.pos
directly, you need to factor in the
tick value.
1 decade ago
by Joncom
I use the built in .vel
property and let Impact handle the movement. However, I wish I could say the speed was constant across clients with differing FPS rates.
1 decade ago
by Nico
Have you thought about hardcoding in an FPS limit? For example limit all clients to 30FPS and disconnect them if they drop below a certain threshold?
Those could be totally ridiculous ideas but in my head it seems like it could work :P
I set mine for 20 fps for a board game style mmo it works pretty well
1 decade ago
by paulh
fps value is depreciated in 1.20.
1 decade ago
by dominic
Quote from Joncom
I use the built in .vel
property and let Impact handle the movement. However, I wish I could say the speed was constant across clients with differing FPS rates.
There&
039;s probably something else going on - show us the #update()
code of both entities.
Also, it may be a good idea to set
ig.Timer.maxStep to a "big" value (
1
second should do), for clients that can't render 20fps.
1 decade ago
by Joncom
local-player entity update function:
update: function() {
this.parent();
// action (like reading a sign or talking to npc)
if (ig.input.pressed('action') && !this.isMove) {
this.action(this);
}
// handle zoning
if (this.moveDoor && !this.moveWaiting && !this.isMove) {
// we just entered a door, so zone
this.moveDoor.trigger();
} else {
/////////////////////
// Handle Movement //
/////////////////////
if (this.moveWaiting) {
// about to move
console.debug("Waiting to move...");
this.moveWait();
} else if (this.isJump || this.isMove) {
// a move or jump has already been started
this.finishMove();
} else if (ig.input.state('left') && !ig.input.state('right')) {
// if player is trying to move left
this.facing = 'left';
this.movePressed();
} else if (ig.input.state('right') && !ig.input.state('left')) {
// if player is trying to move right
this.facing = 'right';
this.movePressed();
} else if (ig.input.state('up') && !ig.input.state('down')) {
// if player is trying to move up
this.facing = 'up';
this.movePressed();
} else if (ig.input.state('down') && !ig.input.state('up')) {
// if player is trying to move down
this.facing = 'down';
this.movePressed();
} else {
// if player not trying to move, set to idle
this.moveAnimStop();
// keep all slow-walk animations reset
this.anims.slowLeft.rewind();
this.anims.slowRight.rewind();
this.anims.slowUp.rewind();
this.anims.slowDown.rewind();
}
}
}
network-player entity update function:
update: function() {
this.parent();
// movement
if (this.isJump || this.isMove) {
this.finishMove();
} else {
// keep animation consistent with this.facing
this.moveAnimStop();
}
}
I wonder however if this might be the culprit (see
!!!
comment):
finishMove: function() {
if (this.destinationReached()) // check if reached destination
{
this.isJump = false; // no longer jumping (regardless if was)
// !!! THIS LINE RIGHT HERE !!!
this.alignToGrid(); // ensure player's at legal coordinates
this.vel.x = this.vel.y = 0; // stop player
this.goAgain(); // check if we should continue moving
if (this.isLocal) updateBorder(this); // change repeating border
} else this.move(); // continue to destination
},
alignToGrid()
sets players x and y to the tile he was facing when a move was initiated:
alignToGrid: function() {
switch (this.facing) {
case 'left':
case 'right':
this.pos.x = this.destination;
break;
case 'up':
case 'down':
this.pos.y = this.destination;
break;
}
},
In other words, regardless of whether Impact moves the player entity exactly to his destination or slightly past it, player is
snapped to
this.destination
every 16 pixels (game tilesize) before possibly performing another move.
But why might this cause players to appear to teleport/jump around the screen when two clients have different FPS rates?
1 decade ago
by dominic
Kind of solved. Joncom didn't change the actual frame rate, but the
timeScale - which slowed done the game (which is the intended effect).
There's still some "teleporting" visible, but my guess is, that it's network overhead.
You could send your action to the server and then let the server run the timer and return something to allow the next action putting everyone on the server's timer.
Page 1 of 1
« first
« previous
next ›
last »