mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 03:39:00 +00:00
Updated documentation.
This commit is contained in:
parent
cccbeb1c29
commit
114e6b0501
@ -1,11 +1,11 @@
|
|||||||
Under the current "input delay" algorithm, the lag of a single player would cause all the other players to receive outdated commands, e.g. when at a certain moment
|
Under the current "input delay" algorithm, the lag of a single player would cause all the other players to receive outdated commands, e.g. when at a certain moment
|
||||||
- player#1: renderFrameId = 100, significantly lagged due to local CPU being overheated
|
- player#1: renderFrameId = 100, significantly lagged due to local CPU overheated
|
||||||
- player#2: renderFrameId = 240
|
- player#2: renderFrameId = 240
|
||||||
- player#3: renderFrameId = 239
|
- player#3: renderFrameId = 239
|
||||||
- player#4: renderFrameId = 242
|
- player#4: renderFrameId = 242
|
||||||
|
|
||||||
players #2, #3 #4 would receive "outdated(in their subjective feelings)" from then on, and be forced to rollback many frames.
|
players #2, #3 #4 would receive "outdated(in their subjective feelings) but all-confirmed commands" from then on, thus forced to rollback and chase many frames - the lag due to "large range of frame-chasing" would then further deteriorate the situation - like an avalanche.
|
||||||
|
|
||||||
In a "no-server & p2p" setup, I couldn't think of a proper way to cope with such edge case. On the frontend we could only mitigate the impact to players #2, #3, #4 by certain buffering mechanisms.
|
In a "no-server & p2p" setup, I couldn't think of a proper way to cope with such edge case. Solely on the frontend we could only mitigate the impact to players #2, #3, #4, e.g. a potential lag due to "large range of frame-chasing" is proactively avoided in `<proj-root>/frontend/assets/scripts/Map.js, function update(dt)` for more information.
|
||||||
|
|
||||||
However in a "server as authority" setup, the server could force confirming an inputFrame without player#1's upsync, and notify player#1 to apply a "roomDownsyncFrame" as well as drop all its outdated local inputFrames.
|
However in a "server as authority" setup, the server could force confirming an inputFrame without player#1's upsync, and notify player#1 to apply a "roomDownsyncFrame" as well as drop all its outdated local inputFrames.
|
||||||
|
@ -440,7 +440,7 @@
|
|||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
216.05530045313827,
|
209.73151519075364,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -631,7 +631,7 @@ cc.Class({
|
|||||||
--------------------------------------------------------
|
--------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
if (renderFrameId1 < self.chaserRenderFrameId) {
|
if (renderFrameId1 < self.chaserRenderFrameId) {
|
||||||
// The actual rollback-and-replay would later be executed in update(dt).
|
// The actual rollback-and-chase would later be executed in update(dt).
|
||||||
console.warn("Mismatched input detected, resetting chaserRenderFrameId: inputFrameId1:", inputFrameId1, ", renderFrameId1:", renderFrameId1, ", chaserRenderFrameId before reset: ", self.chaserRenderFrameId);
|
console.warn("Mismatched input detected, resetting chaserRenderFrameId: inputFrameId1:", inputFrameId1, ", renderFrameId1:", renderFrameId1, ", chaserRenderFrameId before reset: ", self.chaserRenderFrameId);
|
||||||
self.chaserRenderFrameId = renderFrameId1;
|
self.chaserRenderFrameId = renderFrameId1;
|
||||||
} else {
|
} else {
|
||||||
@ -798,15 +798,16 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let t1 = performance.now();
|
let t1 = performance.now();
|
||||||
|
// Use "fractional-frame-chasing" to guarantee that "self.update(dt)" is not jammed by a "large range of frame-chasing". See `<proj-root>/ConcerningEdgeCases.md` for the motivation.
|
||||||
const prevChaserRenderFrameId = self.chaserRenderFrameId;
|
const prevChaserRenderFrameId = self.chaserRenderFrameId;
|
||||||
let nextChaserRenderFrameId = (prevChaserRenderFrameId + self.maxChasingRenderFramesPerUpdate);
|
let nextChaserRenderFrameId = (prevChaserRenderFrameId + self.maxChasingRenderFramesPerUpdate);
|
||||||
if (nextChaserRenderFrameId > self.renderFrameId) nextChaserRenderFrameId = self.renderFrameId;
|
if (nextChaserRenderFrameId > self.renderFrameId) nextChaserRenderFrameId = self.renderFrameId;
|
||||||
self.rollbackAndReplay(prevChaserRenderFrameId, nextChaserRenderFrameId, self.chaserCollisionSys, self.chaserCollisionSysMap);
|
self.rollbackAndChase(prevChaserRenderFrameId, nextChaserRenderFrameId, self.chaserCollisionSys, self.chaserCollisionSysMap);
|
||||||
self.chaserRenderFrameId = nextChaserRenderFrameId; // Move the cursor "self.chaserRenderFrameId", keep in mind that "self.chaserRenderFrameId" is not monotonic!
|
self.chaserRenderFrameId = nextChaserRenderFrameId; // Move the cursor "self.chaserRenderFrameId", keep in mind that "self.chaserRenderFrameId" is not monotonic!
|
||||||
let t2 = performance.now();
|
let t2 = performance.now();
|
||||||
|
|
||||||
// Inside "self.rollbackAndReplay", the "self.latestCollisionSys" is ALWAYS ROLLED BACK to "self.recentRenderCache.get(self.renderFrameId)" before being applied dynamics from corresponding inputFrameDownsync, REGARDLESS OF whether or not "self.chaserRenderFrameId == self.renderFrameId" now.
|
// Inside "self.rollbackAndChase", the "self.latestCollisionSys" is ALWAYS ROLLED BACK to "self.recentRenderCache.get(self.renderFrameId)" before being applied dynamics from corresponding inputFrameDownsync, REGARDLESS OF whether or not "self.chaserRenderFrameId == self.renderFrameId" now.
|
||||||
const rdf = self.rollbackAndReplay(self.renderFrameId, self.renderFrameId+1, self.latestCollisionSys, self.latestCollisionSysMap);
|
const rdf = self.rollbackAndChase(self.renderFrameId, self.renderFrameId+1, self.latestCollisionSys, self.latestCollisionSysMap);
|
||||||
|
|
||||||
self.applyRoomDownsyncFrameDynamics(rdf);
|
self.applyRoomDownsyncFrameDynamics(rdf);
|
||||||
let t3 = performance.now();
|
let t3 = performance.now();
|
||||||
@ -1011,7 +1012,7 @@ cc.Class({
|
|||||||
return inputFrameDownsync;
|
return inputFrameDownsync;
|
||||||
},
|
},
|
||||||
|
|
||||||
rollbackAndReplay(renderFrameIdSt, renderFrameIdEd, collisionSys, collisionSysMap) {
|
rollbackAndChase(renderFrameIdSt, renderFrameIdEd, collisionSys, collisionSysMap) {
|
||||||
if (renderFrameSt >= renderFrameIdEd) {
|
if (renderFrameSt >= renderFrameIdEd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user