Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

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

1 decade ago by ShawnSwander

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'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.

1 decade ago by ShawnSwander

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 »