(hopefully) improved reconciliation
This commit is contained in:
parent
c35c18bbbc
commit
5c936df3f6
|
@ -109,23 +109,32 @@ function start() {
|
||||||
break;
|
break;
|
||||||
case "update": {
|
case "update": {
|
||||||
server_tick = data.tick;
|
server_tick = data.tick;
|
||||||
|
var prediction = predictions[data.tick];
|
||||||
|
if (prediction) {
|
||||||
|
Object.keys(predictions).forEach(tick => {
|
||||||
|
if (tick < data.tick) delete predictions[tick];
|
||||||
|
});
|
||||||
|
server_ping = new Date() - prediction.time;
|
||||||
|
}
|
||||||
Object.keys(data.players).forEach(id => {
|
Object.keys(data.players).forEach(id => {
|
||||||
const player = players[id];
|
const player = players[id];
|
||||||
const update = data.players[id];
|
const update = data.players[id];
|
||||||
// this should never be true, but just in case
|
|
||||||
if (!player) return;
|
|
||||||
if (id == client_id) {
|
if (id == client_id) {
|
||||||
// clear all predictions prior to this tick
|
|
||||||
Object.keys(predictions).forEach(tick => {
|
|
||||||
if (tick < data.tick) delete predictions[tick];
|
|
||||||
});
|
|
||||||
var prediction = predictions[data.tick];
|
|
||||||
if (!prediction) return;
|
if (!prediction) return;
|
||||||
server_ping = new Date() - prediction.time;
|
const predicted = prediction.player;
|
||||||
if (Math.abs(prediction.x - update.x) > 1)
|
// clear all predictions prior to this tick
|
||||||
players[client_id].x = update.x;
|
if (predicted != update) {
|
||||||
if (Math.abs(prediction.y - update.y) > 1)
|
var diff_x = predicted.x - update.x;
|
||||||
players[client_id].y = update.y;
|
var diff_y = predicted.y - update.y;
|
||||||
|
// apply difference to all predictions
|
||||||
|
Object.values(predictions).forEach(p => {
|
||||||
|
p.x -= diff_x;
|
||||||
|
p.y -= diff_y;
|
||||||
|
});
|
||||||
|
// update client state to reflect
|
||||||
|
player.x -= diff_x;
|
||||||
|
player.y -= diff_y;
|
||||||
|
}
|
||||||
delete predictions[data.tick];
|
delete predictions[data.tick];
|
||||||
} else {
|
} else {
|
||||||
player.x = update.x;
|
player.x = update.x;
|
||||||
|
@ -135,9 +144,33 @@ function start() {
|
||||||
Object.keys(data.props).forEach(id => {
|
Object.keys(data.props).forEach(id => {
|
||||||
const prop = props[id];
|
const prop = props[id];
|
||||||
const update = data.props[id];
|
const update = data.props[id];
|
||||||
|
if (!prediction) {
|
||||||
|
prop.x = update.x;
|
||||||
|
prop.y = update.y;
|
||||||
|
prop.xv = update.xv;
|
||||||
|
prop.yv = update.yv;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
prop.x = update.x;
|
const predicted = prediction.props[id];
|
||||||
prop.y = update.y;
|
if (predicted != update) {
|
||||||
|
var diff_x = predicted.x - update.x;
|
||||||
|
var diff_y = predicted.y - update.y;
|
||||||
|
var diff_xv = predicted.xv - update.xv;
|
||||||
|
var diff_yv = predicted.yv - update.yv;
|
||||||
|
// apply difference to all predictions
|
||||||
|
Object.values(predictions).forEach(p => {
|
||||||
|
p.x -= diff_x;
|
||||||
|
p.y -= diff_y;
|
||||||
|
p.xv -= diff_xv;
|
||||||
|
p.yv -= diff_yv;
|
||||||
|
});
|
||||||
|
// update client state to reflect
|
||||||
|
prop.x -= diff_x;
|
||||||
|
prop.y -= diff_y;
|
||||||
|
prop.xv -= diff_xv;
|
||||||
|
prop.yv -= diff_yv;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +244,10 @@ function start() {
|
||||||
|
|
||||||
canvas.addEventListener("keypress", event => {
|
canvas.addEventListener("keypress", event => {
|
||||||
switch (event.key.toLowerCase()) {
|
switch (event.key.toLowerCase()) {
|
||||||
|
case 'i':
|
||||||
|
enable_interpolation.update(val => !val);
|
||||||
|
interpolationToggle.checked = enable_interpolation.get();
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
console.log(predictions);
|
console.log(predictions);
|
||||||
break;
|
break;
|
||||||
|
@ -288,31 +325,49 @@ function sendChat(msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(delta) {
|
function update(delta) {
|
||||||
|
const prediction = {
|
||||||
|
time: new Date(),
|
||||||
|
player: {},
|
||||||
|
props: {},
|
||||||
|
};
|
||||||
|
|
||||||
const clientPlayer = players[client_id];
|
const clientPlayer = players[client_id];
|
||||||
if (clientPlayer) {
|
if (!clientPlayer) return;
|
||||||
clientPlayer.in_x = input.move_right - input.move_left;
|
|
||||||
clientPlayer.in_y = input.move_down - input.move_up;
|
|
||||||
|
|
||||||
clientPlayer.update(delta);
|
clientPlayer.in_x = input.move_right - input.move_left;
|
||||||
|
clientPlayer.in_y = input.move_down - input.move_up;
|
||||||
|
|
||||||
// insert prediction for the next server tick
|
clientPlayer.update(delta);
|
||||||
predictions[ticks] = {
|
|
||||||
time: new Date(),
|
// insert prediction for the next server tick
|
||||||
x: clientPlayer.x,
|
prediction.player = {
|
||||||
y: clientPlayer.y,
|
x: clientPlayer.x,
|
||||||
|
y: clientPlayer.y,
|
||||||
|
};
|
||||||
|
|
||||||
|
var t = ticks;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!ws) return;
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
type: "update",
|
||||||
|
tick: t,
|
||||||
|
x: input.move_right - input.move_left,
|
||||||
|
y: input.move_down - input.move_up,
|
||||||
|
}));
|
||||||
|
}, fake_ping.get() / 2);
|
||||||
|
|
||||||
|
Object.keys(props).forEach(id => {
|
||||||
|
const prop = props[id];
|
||||||
|
prop.update(delta, Object.values(players));
|
||||||
|
prediction.props[id] = {
|
||||||
|
x: prop.x,
|
||||||
|
y: prop.y,
|
||||||
|
xv: prop.xv,
|
||||||
|
yv: prop.yv,
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
var t = ticks;
|
predictions[ticks] = prediction;
|
||||||
setTimeout(() => {
|
|
||||||
if (!ws) return;
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: "update",
|
|
||||||
tick: t,
|
|
||||||
x: input.move_right - input.move_left,
|
|
||||||
y: input.move_down - input.move_up,
|
|
||||||
}));
|
|
||||||
}, fake_ping.get() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
ticks++;
|
ticks++;
|
||||||
}
|
}
|
||||||
|
@ -337,8 +392,8 @@ function draw() {
|
||||||
const server_state = Object.values(predictions)[0];
|
const server_state = Object.values(predictions)[0];
|
||||||
ctx.fillStyle = "#208020";
|
ctx.fillStyle = "#208020";
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.rect(server_state.x - Player.SIZE / 2,
|
ctx.rect(server_state.player.x - Player.SIZE / 2,
|
||||||
server_state.y - Player.SIZE / 2,
|
server_state.player.y - Player.SIZE / 2,
|
||||||
Player.SIZE, Player.SIZE);
|
Player.SIZE, Player.SIZE);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,8 @@ export function init(http_server) {
|
||||||
name: prop.name,
|
name: prop.name,
|
||||||
x: prop.x,
|
x: prop.x,
|
||||||
y: prop.y,
|
y: prop.y,
|
||||||
|
xv: prop.xv,
|
||||||
|
yv: prop.yv,
|
||||||
col: prop.colour,
|
col: prop.colour,
|
||||||
sprite: prop.sprite,
|
sprite: prop.sprite,
|
||||||
}
|
}
|
||||||
|
@ -193,6 +195,8 @@ function update() {
|
||||||
frame_props[id] = {
|
frame_props[id] = {
|
||||||
x: prop.x,
|
x: prop.x,
|
||||||
y: prop.y,
|
y: prop.y,
|
||||||
|
xv: prop.xv,
|
||||||
|
yv: prop.yv,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue