(hopefully) improved reconciliation

This commit is contained in:
ari melody 2024-08-30 12:30:53 +01:00
parent c35c18bbbc
commit 5c936df3f6
Signed by: ari
GPG key ID: CF99829C92678188
2 changed files with 95 additions and 36 deletions

View file

@ -109,23 +109,32 @@ function start() {
break;
case "update": {
server_tick = data.tick;
Object.keys(data.players).forEach(id => {
const player = players[id];
const update = data.players[id];
// this should never be true, but just in case
if (!player) return;
if (id == client_id) {
// clear all predictions prior to this tick
var prediction = predictions[data.tick];
if (prediction) {
Object.keys(predictions).forEach(tick => {
if (tick < data.tick) delete predictions[tick];
});
var prediction = predictions[data.tick];
if (!prediction) return;
server_ping = new Date() - prediction.time;
if (Math.abs(prediction.x - update.x) > 1)
players[client_id].x = update.x;
if (Math.abs(prediction.y - update.y) > 1)
players[client_id].y = update.y;
}
Object.keys(data.players).forEach(id => {
const player = players[id];
const update = data.players[id];
if (id == client_id) {
if (!prediction) return;
const predicted = prediction.player;
// clear all predictions prior to this tick
if (predicted != update) {
var diff_x = predicted.x - update.x;
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];
} else {
player.x = update.x;
@ -135,9 +144,33 @@ function start() {
Object.keys(data.props).forEach(id => {
const prop = 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;
}
const predicted = prediction.props[id];
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;
}
@ -211,6 +244,10 @@ function start() {
canvas.addEventListener("keypress", event => {
switch (event.key.toLowerCase()) {
case 'i':
enable_interpolation.update(val => !val);
interpolationToggle.checked = enable_interpolation.get();
break;
case 'p':
console.log(predictions);
break;
@ -288,16 +325,22 @@ function sendChat(msg) {
}
function update(delta) {
const prediction = {
time: new Date(),
player: {},
props: {},
};
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);
// insert prediction for the next server tick
predictions[ticks] = {
time: new Date(),
prediction.player = {
x: clientPlayer.x,
y: clientPlayer.y,
};
@ -312,7 +355,19 @@ function update(delta) {
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,
};
});
predictions[ticks] = prediction;
ticks++;
}
@ -337,8 +392,8 @@ function draw() {
const server_state = Object.values(predictions)[0];
ctx.fillStyle = "#208020";
ctx.beginPath();
ctx.rect(server_state.x - Player.SIZE / 2,
server_state.y - Player.SIZE / 2,
ctx.rect(server_state.player.x - Player.SIZE / 2,
server_state.player.y - Player.SIZE / 2,
Player.SIZE, Player.SIZE);
ctx.stroke();
}

View file

@ -88,6 +88,8 @@ export function init(http_server) {
name: prop.name,
x: prop.x,
y: prop.y,
xv: prop.xv,
yv: prop.yv,
col: prop.colour,
sprite: prop.sprite,
}
@ -193,6 +195,8 @@ function update() {
frame_props[id] = {
x: prop.x,
y: prop.y,
xv: prop.xv,
yv: prop.yv,
}
});