refactor: predictor next to client, smoothing

This commit is contained in:
cha0s 2024-09-08 17:19:59 -05:00
parent 336ec04f66
commit 04a0230248
4 changed files with 38 additions and 28 deletions

View File

@ -17,7 +17,13 @@ export default class LocalClient extends Client {
{type: 'module'},
);
this.interpolator.addEventListener('message', (event) => {
this.accept(event.data);
const packet = event.data;
if (CLIENT_PREDICTION) {
this.predictor.postMessage([1, packet]);
}
else {
this.accept(packet);
}
});
}
if (CLIENT_PREDICTION) {
@ -35,12 +41,7 @@ export default class LocalClient extends Client {
break;
}
case 1: {
if (CLIENT_INTERPOLATION) {
this.interpolator.postMessage(packet);
}
else {
this.accept(packet);
}
this.accept(packet);
break;
}
}
@ -54,12 +55,12 @@ export default class LocalClient extends Client {
}
this.throughput.$$down += event.data.byteLength;
const packet = decode(event.data);
if (CLIENT_PREDICTION) {
this.predictor.postMessage([1, packet]);
}
else if (CLIENT_INTERPOLATION) {
if (CLIENT_INTERPOLATION) {
this.interpolator.postMessage(packet);
}
else if (CLIENT_PREDICTION) {
this.predictor.postMessage([1, packet]);
}
else {
this.accept(packet);
}

View File

@ -27,17 +27,8 @@ const Flow = {
DOWN: 1,
};
const Stage = {
UNACK: 0,
ACK: 1,
FINISHING: 2,
FINISHED: 3,
};
const actions = new Map();
let ecs = new PredictionEcs({Components, Systems});
let mainEntityId = 0;
function applyClientActions(elapsed) {
@ -46,7 +37,7 @@ function applyClientActions(elapsed) {
const {Controlled} = main;
const finished = [];
for (const [id, action] of actions) {
if (Stage.UNACK === action.stage) {
if (0 === action.finished && !action.ack) {
if (!Controlled.locked) {
switch (action.action.type) {
case 'moveUp':
@ -60,7 +51,7 @@ function applyClientActions(elapsed) {
}
action.steps.push(elapsed);
}
if (Stage.FINISHING === action.stage) {
if (1 === action.finished) {
if (!Controlled.locked) {
switch (action.action.type) {
case 'moveUp':
@ -72,9 +63,9 @@ function applyClientActions(elapsed) {
}
}
}
action.stage = Stage.FINISHED;
action.finished = 2;
}
if (Stage.FINISHED === action.stage) {
if (action.ack && 2 === action.finished) {
action.steps.shift();
if (0 === action.steps.length) {
finished.push(id);
@ -113,13 +104,13 @@ onmessage = async (event) => {
if (0 === packet.payload.value) {
const ack = pending.get(packet.payload.type);
const action = actions.get(ack);
action.stage = Stage.FINISHING;
action.finished = 1;
pending.delete(packet.payload.type);
}
else {
const tx = {
action: packet.payload,
stage: Stage.UNACK,
ack: false,finished: 0,
steps: [],
};
packet.payload.ack = Math.random();
@ -139,11 +130,12 @@ onmessage = async (event) => {
switch (packet.type) {
case 'ActionAck': {
const action = actions.get(packet.payload.ack);
action.stage = Stage.ACK;
action.ack = true;
return;
}
case 'EcsChange': {
ecs = new PredictionEcs({Components, Systems});
mainEntityId = 0;
break;
}
case 'Tick': {

View File

@ -27,6 +27,7 @@ const textEncoder = new TextEncoder();
export default class Engine {
ackingActions = new Map();
connectedPlayers = new Map();
ecses = {};
frame = 0;
@ -250,6 +251,15 @@ export default class Engine {
}
}
if (payload.ack) {
if (!this.ackingActions.has(connection)) {
this.ackingActions.set(connection, []);
}
this.ackingActions.get(connection).push({
type: 'ActionAck',
payload: {
ack: payload.ack,
},
})
this.server.send(
connection,
{
@ -303,6 +313,7 @@ export default class Engine {
if (!connectedPlayer) {
return;
}
this.ackingActions.delete(connection);
this.connectedPlayers.delete(connection);
this.incomingActions.delete(connection);
const {entity, heartbeat, id} = connectedPlayer;
@ -445,6 +456,12 @@ export default class Engine {
update(elapsed) {
for (const [connection, {entity}] of this.connectedPlayers) {
if (this.ackingActions.has(connection)) {
for (const ack of this.ackingActions.get(connection)) {
this.server.send(connection, ack);
}
this.ackingActions.delete(connection);
}
if (!entity) {
continue;
}

View File

@ -17,4 +17,4 @@ export const SERVER_LATENCY = 0;
export const TPS = 60;
export const UPS = 15;
export const UPS = 30;