refactor: predictor next to client, smoothing
This commit is contained in:
parent
336ec04f66
commit
04a0230248
|
@ -17,7 +17,13 @@ export default class LocalClient extends Client {
|
||||||
{type: 'module'},
|
{type: 'module'},
|
||||||
);
|
);
|
||||||
this.interpolator.addEventListener('message', (event) => {
|
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) {
|
if (CLIENT_PREDICTION) {
|
||||||
|
@ -35,12 +41,7 @@ export default class LocalClient extends Client {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
if (CLIENT_INTERPOLATION) {
|
this.accept(packet);
|
||||||
this.interpolator.postMessage(packet);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.accept(packet);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,12 +55,12 @@ export default class LocalClient extends Client {
|
||||||
}
|
}
|
||||||
this.throughput.$$down += event.data.byteLength;
|
this.throughput.$$down += event.data.byteLength;
|
||||||
const packet = decode(event.data);
|
const packet = decode(event.data);
|
||||||
if (CLIENT_PREDICTION) {
|
if (CLIENT_INTERPOLATION) {
|
||||||
this.predictor.postMessage([1, packet]);
|
|
||||||
}
|
|
||||||
else if (CLIENT_INTERPOLATION) {
|
|
||||||
this.interpolator.postMessage(packet);
|
this.interpolator.postMessage(packet);
|
||||||
}
|
}
|
||||||
|
else if (CLIENT_PREDICTION) {
|
||||||
|
this.predictor.postMessage([1, packet]);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
this.accept(packet);
|
this.accept(packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,17 +27,8 @@ const Flow = {
|
||||||
DOWN: 1,
|
DOWN: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Stage = {
|
|
||||||
UNACK: 0,
|
|
||||||
ACK: 1,
|
|
||||||
FINISHING: 2,
|
|
||||||
FINISHED: 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
const actions = new Map();
|
const actions = new Map();
|
||||||
|
|
||||||
let ecs = new PredictionEcs({Components, Systems});
|
let ecs = new PredictionEcs({Components, Systems});
|
||||||
|
|
||||||
let mainEntityId = 0;
|
let mainEntityId = 0;
|
||||||
|
|
||||||
function applyClientActions(elapsed) {
|
function applyClientActions(elapsed) {
|
||||||
|
@ -46,7 +37,7 @@ function applyClientActions(elapsed) {
|
||||||
const {Controlled} = main;
|
const {Controlled} = main;
|
||||||
const finished = [];
|
const finished = [];
|
||||||
for (const [id, action] of actions) {
|
for (const [id, action] of actions) {
|
||||||
if (Stage.UNACK === action.stage) {
|
if (0 === action.finished && !action.ack) {
|
||||||
if (!Controlled.locked) {
|
if (!Controlled.locked) {
|
||||||
switch (action.action.type) {
|
switch (action.action.type) {
|
||||||
case 'moveUp':
|
case 'moveUp':
|
||||||
|
@ -60,7 +51,7 @@ function applyClientActions(elapsed) {
|
||||||
}
|
}
|
||||||
action.steps.push(elapsed);
|
action.steps.push(elapsed);
|
||||||
}
|
}
|
||||||
if (Stage.FINISHING === action.stage) {
|
if (1 === action.finished) {
|
||||||
if (!Controlled.locked) {
|
if (!Controlled.locked) {
|
||||||
switch (action.action.type) {
|
switch (action.action.type) {
|
||||||
case 'moveUp':
|
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();
|
action.steps.shift();
|
||||||
if (0 === action.steps.length) {
|
if (0 === action.steps.length) {
|
||||||
finished.push(id);
|
finished.push(id);
|
||||||
|
@ -113,13 +104,13 @@ onmessage = async (event) => {
|
||||||
if (0 === packet.payload.value) {
|
if (0 === packet.payload.value) {
|
||||||
const ack = pending.get(packet.payload.type);
|
const ack = pending.get(packet.payload.type);
|
||||||
const action = actions.get(ack);
|
const action = actions.get(ack);
|
||||||
action.stage = Stage.FINISHING;
|
action.finished = 1;
|
||||||
pending.delete(packet.payload.type);
|
pending.delete(packet.payload.type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const tx = {
|
const tx = {
|
||||||
action: packet.payload,
|
action: packet.payload,
|
||||||
stage: Stage.UNACK,
|
ack: false,finished: 0,
|
||||||
steps: [],
|
steps: [],
|
||||||
};
|
};
|
||||||
packet.payload.ack = Math.random();
|
packet.payload.ack = Math.random();
|
||||||
|
@ -139,11 +130,12 @@ onmessage = async (event) => {
|
||||||
switch (packet.type) {
|
switch (packet.type) {
|
||||||
case 'ActionAck': {
|
case 'ActionAck': {
|
||||||
const action = actions.get(packet.payload.ack);
|
const action = actions.get(packet.payload.ack);
|
||||||
action.stage = Stage.ACK;
|
action.ack = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'EcsChange': {
|
case 'EcsChange': {
|
||||||
ecs = new PredictionEcs({Components, Systems});
|
ecs = new PredictionEcs({Components, Systems});
|
||||||
|
mainEntityId = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'Tick': {
|
case 'Tick': {
|
||||||
|
|
|
@ -27,6 +27,7 @@ const textEncoder = new TextEncoder();
|
||||||
|
|
||||||
export default class Engine {
|
export default class Engine {
|
||||||
|
|
||||||
|
ackingActions = new Map();
|
||||||
connectedPlayers = new Map();
|
connectedPlayers = new Map();
|
||||||
ecses = {};
|
ecses = {};
|
||||||
frame = 0;
|
frame = 0;
|
||||||
|
@ -250,6 +251,15 @@ export default class Engine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (payload.ack) {
|
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(
|
this.server.send(
|
||||||
connection,
|
connection,
|
||||||
{
|
{
|
||||||
|
@ -303,6 +313,7 @@ export default class Engine {
|
||||||
if (!connectedPlayer) {
|
if (!connectedPlayer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.ackingActions.delete(connection);
|
||||||
this.connectedPlayers.delete(connection);
|
this.connectedPlayers.delete(connection);
|
||||||
this.incomingActions.delete(connection);
|
this.incomingActions.delete(connection);
|
||||||
const {entity, heartbeat, id} = connectedPlayer;
|
const {entity, heartbeat, id} = connectedPlayer;
|
||||||
|
@ -445,6 +456,12 @@ export default class Engine {
|
||||||
|
|
||||||
update(elapsed) {
|
update(elapsed) {
|
||||||
for (const [connection, {entity}] of this.connectedPlayers) {
|
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) {
|
if (!entity) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,4 @@ export const SERVER_LATENCY = 0;
|
||||||
|
|
||||||
export const TPS = 60;
|
export const TPS = 60;
|
||||||
|
|
||||||
export const UPS = 15;
|
export const UPS = 30;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user