fix: prediction
This commit is contained in:
parent
e6f54c3694
commit
46cff307b1
|
@ -1,24 +1,14 @@
|
||||||
import {LRUCache} from 'lru-cache';
|
|
||||||
|
|
||||||
import Components from '@/ecs/components/index.js';
|
import Components from '@/ecs/components/index.js';
|
||||||
import Ecs from '@/ecs/ecs.js';
|
import Ecs from '@/ecs/ecs.js';
|
||||||
import Systems from '@/ecs/systems/index.js';
|
import Systems from '@/ecs/systems/index.js';
|
||||||
import {withResolvers} from '@/util/promise.js';
|
import {readAsset} from '@/util/resources.js';
|
||||||
|
|
||||||
const cache = new LRUCache({
|
|
||||||
max: 128,
|
|
||||||
});
|
|
||||||
|
|
||||||
class PredictionEcs extends Ecs {
|
class PredictionEcs extends Ecs {
|
||||||
async readAsset(uri) {
|
async readAsset(path) {
|
||||||
if (!cache.has(uri)) {
|
const resource = await readAsset(path);
|
||||||
const {promise, resolve, reject} = withResolvers();
|
return resource
|
||||||
cache.set(uri, promise);
|
? resource
|
||||||
fetch(uri)
|
: new ArrayBuffer(0);
|
||||||
.then((response) => resolve(response.ok ? response.arrayBuffer() : new ArrayBuffer(0)))
|
|
||||||
.catch(reject);
|
|
||||||
}
|
|
||||||
return cache.get(uri);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +39,6 @@ function applyClientActions(elapsed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
action.steps.push(elapsed);
|
|
||||||
}
|
}
|
||||||
if (1 === action.finished) {
|
if (1 === action.finished) {
|
||||||
if (!Controlled.locked) {
|
if (!Controlled.locked) {
|
||||||
|
@ -65,20 +54,17 @@ function applyClientActions(elapsed) {
|
||||||
}
|
}
|
||||||
action.finished = 2;
|
action.finished = 2;
|
||||||
}
|
}
|
||||||
|
if (!action.ack) {
|
||||||
|
action.stop += elapsed;
|
||||||
|
}
|
||||||
if (action.ack && 2 === action.finished) {
|
if (action.ack && 2 === action.finished) {
|
||||||
action.steps.shift();
|
action.start += elapsed;
|
||||||
if (0 === action.steps.length) {
|
if (action.start >= action.stop) {
|
||||||
finished.push(id);
|
finished.push(id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let leap = 0;
|
ecs.predict(main, action.stop - action.start);
|
||||||
for (const step of action.steps) {
|
|
||||||
leap += step;
|
|
||||||
}
|
|
||||||
if (leap > 0) {
|
|
||||||
ecs.predict(main, leap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (const id of finished) {
|
for (const id of finished) {
|
||||||
actions.delete(id);
|
actions.delete(id);
|
||||||
|
@ -108,10 +94,13 @@ onmessage = async (event) => {
|
||||||
pending.delete(packet.payload.type);
|
pending.delete(packet.payload.type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
const now = performance.now() / 1000;
|
||||||
const tx = {
|
const tx = {
|
||||||
action: packet.payload,
|
action: packet.payload,
|
||||||
ack: false,finished: 0,
|
ack: false,
|
||||||
steps: [],
|
finished: 0,
|
||||||
|
start: now,
|
||||||
|
stop: now,
|
||||||
};
|
};
|
||||||
packet.payload.ack = Math.random();
|
packet.payload.ack = Math.random();
|
||||||
pending.set(packet.payload.type, packet.payload.ack);
|
pending.set(packet.payload.type, packet.payload.ack);
|
||||||
|
@ -152,9 +141,20 @@ onmessage = async (event) => {
|
||||||
const authoritative = structuredClone(main.toNet(main));
|
const authoritative = structuredClone(main.toNet(main));
|
||||||
applyClientActions(packet.payload.elapsed);
|
applyClientActions(packet.payload.elapsed);
|
||||||
if (ecs.diff[mainEntityId]) {
|
if (ecs.diff[mainEntityId]) {
|
||||||
packet.payload.ecs[mainEntityId] = ecs.diff[mainEntityId];
|
packet.payload.ecs[mainEntityId] ??= {};
|
||||||
|
ecs.mergeDiff(
|
||||||
|
packet.payload.ecs[mainEntityId],
|
||||||
|
ecs.diff[mainEntityId],
|
||||||
|
);
|
||||||
|
const reset = {};
|
||||||
|
for (const componentName in ecs.diff[mainEntityId]) {
|
||||||
|
reset[componentName] = {};
|
||||||
|
for (const property in ecs.diff[mainEntityId][componentName]) {
|
||||||
|
reset[componentName][property] = authoritative[componentName][property];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await ecs.apply({[mainEntityId]: reset});
|
||||||
}
|
}
|
||||||
await ecs.apply({[mainEntityId]: authoritative});
|
|
||||||
}
|
}
|
||||||
ecs.setClean();
|
ecs.setClean();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user