mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 11:48:56 +00:00
Fixed prediction update upon last all-confirmed input frame changes.
This commit is contained in:
parent
f0e624aa85
commit
58add91a54
@ -440,7 +440,7 @@
|
|||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
216.05530045313827,
|
209.7912853806815,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -138,18 +138,26 @@ cc.Class({
|
|||||||
|
|
||||||
_dumpToFullFrameCache: function(fullFrame) {
|
_dumpToFullFrameCache: function(fullFrame) {
|
||||||
const self = this;
|
const self = this;
|
||||||
while (self.recentFrameCacheEd - self.recentFrameCacheSt >= self.recentFrameCacheMaxCount) {
|
self.recentFrameCache.set(fullFrame.id, fullFrame);
|
||||||
delete self.recentFrameCache[self.recentFrameCacheSt++];
|
if (fullFrame.id >= self.recentFrameCacheEd) {
|
||||||
|
// Should be consecutive
|
||||||
|
++self.recentFrameCacheEd;
|
||||||
|
}
|
||||||
|
while (self.recentFrameCacheEd - self.recentFrameCacheSt >= self.recentFrameCacheMaxCount) {
|
||||||
|
self.recentFrameCache.delete(self.recentFrameCacheSt++);
|
||||||
}
|
}
|
||||||
self.recentFrameCache[self.recentFrameCacheEd++] = fullFrame;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_dumpToInputCache: function(inputFrameDownsync) {
|
_dumpToInputCache: function(inputFrameDownsync) {
|
||||||
const self = this;
|
const self = this;
|
||||||
while (self.recentInputCacheEd - self.recentInputCacheSt >= self.recentInputCacheMaxCount) {
|
self.recentInputCache.set(inputFrameDownsync.inputFrameId, inputFrameDownsync);
|
||||||
delete self.recentInputCache[self.recentInputCacheSt++];
|
if (inputFrameDownsync.inputFrameId >= self.recentInputCacheEd) {
|
||||||
|
// Should be consecutive
|
||||||
|
++self.recentInputCacheEd;
|
||||||
|
}
|
||||||
|
while (self.recentInputCacheEd - self.recentInputCacheSt >= self.recentInputCacheMaxCount) {
|
||||||
|
self.recentInputCache.delete(self.recentInputCacheSt++);
|
||||||
}
|
}
|
||||||
self.recentInputCache[self.recentInputCacheEd++] = inputFrameDownsync;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_convertToInputFrameId(renderFrameId, inputDelayFrames) {
|
_convertToInputFrameId(renderFrameId, inputDelayFrames) {
|
||||||
@ -180,11 +188,11 @@ cc.Class({
|
|||||||
if (0 == instance.recentInputCacheEd) {
|
if (0 == instance.recentInputCacheEd) {
|
||||||
prefabbedInputList = new Array(instance.playerRichInfoDict.size).fill(0);
|
prefabbedInputList = new Array(instance.playerRichInfoDict.size).fill(0);
|
||||||
} else {
|
} else {
|
||||||
if (null == instance.recentInputCache || null == instance.recentInputCache[instance.recentInputCacheEd-1]) {
|
if (!instance.recentInputCache.has(instance.recentInputCacheEd-1)) {
|
||||||
console.warn("_generateInputFrameUpsync: recentInputCache is NOT having inputFrameId=", instance.recentInputCacheEd-1, "; recentInputCache=", instance._stringifyRecentInputCache(false));
|
console.warn("_generateInputFrameUpsync: recentInputCache is NOT having inputFrameId=", instance.recentInputCacheEd-1, "; recentInputCache=", instance._stringifyRecentInputCache(false));
|
||||||
prefabbedInputList = new Array(instance.playerRichInfoDict.size).fill(0);
|
prefabbedInputList = new Array(instance.playerRichInfoDict.size).fill(0);
|
||||||
} else {
|
} else {
|
||||||
prefabbedInputList = Array.from(instance.recentInputCache[instance.recentInputCacheEd-1].inputList);
|
prefabbedInputList = Array.from(instance.recentInputCache.get(instance.recentInputCacheEd-1).inputList);
|
||||||
selfPlayerLastInputFrameInput = prefabbedInputList[(instance.selfPlayerInfo.joinIndex-1)]; // it's an integer, thus making a copy here, not impacted by later assignments
|
selfPlayerLastInputFrameInput = prefabbedInputList[(instance.selfPlayerInfo.joinIndex-1)]; // it's an integer, thus making a copy here, not impacted by later assignments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,9 +224,9 @@ cc.Class({
|
|||||||
const instance = this;
|
const instance = this;
|
||||||
let inputFrameUpsyncBatch = [];
|
let inputFrameUpsyncBatch = [];
|
||||||
for (let i = instance.lastUpsyncInputFrameId+1; i <= inputFrameId; ++i) {
|
for (let i = instance.lastUpsyncInputFrameId+1; i <= inputFrameId; ++i) {
|
||||||
const inputFrameDownsync = instance.recentInputCache[i];
|
const inputFrameDownsync = instance.recentInputCache.get(i);
|
||||||
if (null == inputFrameDownsync) {
|
if (null == inputFrameDownsync) {
|
||||||
console.warn("_sendInputFrameUpsyncBatch: recentInputCache is NOT having inputFrameId=", i, "; recentInputCache=", JSON.stringify(instance.recentInputCache));
|
console.warn("_sendInputFrameUpsyncBatch: recentInputCache is NOT having inputFrameId=", i, "; recentInputCache=", instance._stringifyRecentInputCache(false));
|
||||||
} else {
|
} else {
|
||||||
const inputFrameUpsync = {
|
const inputFrameUpsync = {
|
||||||
inputFrameId: i,
|
inputFrameId: i,
|
||||||
@ -328,19 +336,19 @@ cc.Class({
|
|||||||
self.lastRoomDownsyncFrameId = 0;
|
self.lastRoomDownsyncFrameId = 0;
|
||||||
self.renderFrameId = 0; // After battle started
|
self.renderFrameId = 0; // After battle started
|
||||||
self.inputDelayFrames = 8;
|
self.inputDelayFrames = 8;
|
||||||
self.inputScaleFrames = 3;
|
self.inputScaleFrames = 2;
|
||||||
self.lastDownsyncInputFrameId = -1;
|
self.lastDownsyncInputFrameId = -1;
|
||||||
self.lastAllConfirmedInputFrameId = -1;
|
self.lastAllConfirmedInputFrameId = -1;
|
||||||
self.lastUpsyncInputFrameId = -1;
|
self.lastUpsyncInputFrameId = -1;
|
||||||
self.inputFrameUpsyncDelayTolerance = 3;
|
self.inputFrameUpsyncDelayTolerance = 2;
|
||||||
|
|
||||||
self.recentFrameCache = {};
|
self.recentFrameCache = new Map();
|
||||||
self.recentFrameCacheSt = 0; // closed index
|
self.recentFrameCacheSt = 0; // closed index
|
||||||
self.recentFrameCacheEd = 0; // open index
|
self.recentFrameCacheEd = 0; // open index
|
||||||
self.recentFrameCacheMaxCount = 1024;
|
self.recentFrameCacheMaxCount = 1024;
|
||||||
|
|
||||||
self.selfPlayerInfo = null; // This field is kept for distinguishing "self" and "others".
|
self.selfPlayerInfo = null; // This field is kept for distinguishing "self" and "others".
|
||||||
self.recentInputCache = {}; // TODO: Use a ringbuf instead
|
self.recentInputCache = new Map(); // TODO: Use a ringbuf instead
|
||||||
self.recentInputCacheSt = 0; // closed index
|
self.recentInputCacheSt = 0; // closed index
|
||||||
self.recentInputCacheEd = 0; // open index
|
self.recentInputCacheEd = 0; // open index
|
||||||
self.recentInputCacheMaxCount = 1024;
|
self.recentInputCacheMaxCount = 1024;
|
||||||
@ -580,13 +588,13 @@ cc.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log("Received inputFrameDownsyncBatch=", batch, ", now correspondingLastLocalInputFrame=", self.recentInputCache[batch[batch.length-1].inputFrameId]);
|
// console.log("Received inputFrameDownsyncBatch=", batch, ", now correspondingLastLocalInputFrame=", self.recentInputCache.get(batch[batch.length-1].inputFrameId));
|
||||||
let firstPredictedYetIncorrectInputFrameId = null;
|
let firstPredictedYetIncorrectInputFrameId = null;
|
||||||
let firstPredictedYetIncorrectInputFrameJoinIndex = null;
|
let firstPredictedYetIncorrectInputFrameJoinIndex = null;
|
||||||
for (let k in batch) {
|
for (let k in batch) {
|
||||||
const inputFrameDownsync = batch[k];
|
const inputFrameDownsync = batch[k];
|
||||||
const inputFrameDownsyncId = inputFrameDownsync.inputFrameId;
|
const inputFrameDownsyncId = inputFrameDownsync.inputFrameId;
|
||||||
const localInputFrame = self.recentInputCache[inputFrameDownsyncId];
|
const localInputFrame = self.recentInputCache.get(inputFrameDownsyncId);
|
||||||
if (null == localInputFrame) {
|
if (null == localInputFrame) {
|
||||||
console.warn("handleInputFrameDownsyncBatch: recentInputCache is NOT having inputFrameDownsyncId=", inputFrameDownsyncId, "; now recentInputCache=", self._stringifyRecentInputCache(false));
|
console.warn("handleInputFrameDownsyncBatch: recentInputCache is NOT having inputFrameDownsyncId=", inputFrameDownsyncId, "; now recentInputCache=", self._stringifyRecentInputCache(false));
|
||||||
} else {
|
} else {
|
||||||
@ -714,10 +722,9 @@ cc.Class({
|
|||||||
let s = [];
|
let s = [];
|
||||||
s.push("Battle stats: lastUpsyncInputFrameId=" + self.lastUpsyncInputFrameId + ", lastDownsyncInputFrameId=" + self.lastDownsyncInputFrameId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId);
|
s.push("Battle stats: lastUpsyncInputFrameId=" + self.lastUpsyncInputFrameId + ", lastDownsyncInputFrameId=" + self.lastDownsyncInputFrameId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId);
|
||||||
|
|
||||||
for (let inputFrameDownsyncId in self.recentInputCache) {
|
self.recentInputCache.forEach((inputFrameDownsync, inputFrameId) => {
|
||||||
const inputFrameDownsync = self.recentInputCache[inputFrameDownsyncId];
|
|
||||||
s.push(JSON.stringify(inputFrameDownsync));
|
s.push(JSON.stringify(inputFrameDownsync));
|
||||||
}
|
});
|
||||||
|
|
||||||
console.log(s.join('\n'));
|
console.log(s.join('\n'));
|
||||||
},
|
},
|
||||||
@ -786,7 +793,7 @@ cc.Class({
|
|||||||
|
|
||||||
const delayedInputFrameDownsync = self.assembleInputFrameDownsync(delayedInputFrameId);
|
const delayedInputFrameDownsync = self.assembleInputFrameDownsync(delayedInputFrameId);
|
||||||
if (null == delayedInputFrameDownsync) {
|
if (null == delayedInputFrameDownsync) {
|
||||||
console.warn("update(dt): recentInputCache is NOT having inputFrameId=", delayedInputFrameId, "; recentInputCache=", instance._stringifyRecentInputCache(false));
|
console.warn("update(dt): recentInputCache is NOT having inputFrameId=", delayedInputFrameId, "; recentInputCache=", self._stringifyRecentInputCache(false));
|
||||||
} else {
|
} else {
|
||||||
self._applyInputFrameDownsyncDynamics(delayedInputFrameDownsync, false);
|
self._applyInputFrameDownsyncDynamics(delayedInputFrameDownsync, false);
|
||||||
}
|
}
|
||||||
@ -957,9 +964,9 @@ cc.Class({
|
|||||||
|
|
||||||
assembleInputFrameDownsync(inputFrameId) {
|
assembleInputFrameDownsync(inputFrameId) {
|
||||||
const self = this;
|
const self = this;
|
||||||
let inputFrameDownsync = self.recentInputCache[inputFrameId];
|
let inputFrameDownsync = self.recentInputCache.get(inputFrameId);
|
||||||
if (-1 != self.lastAllConfirmedInputFrameId && inputFrameId > self.lastAllConfirmedInputFrameId) {
|
if (-1 != self.lastAllConfirmedInputFrameId && inputFrameId > self.lastAllConfirmedInputFrameId) {
|
||||||
const lastAllConfirmedInputFrame = self.recentInputCache[self.lastAllConfirmedInputFrameId];
|
const lastAllConfirmedInputFrame = self.recentInputCache.get(self.lastAllConfirmedInputFrameId);
|
||||||
for (let i = 0; i < inputFrameDownsync.inputList.length; ++i) {
|
for (let i = 0; i < inputFrameDownsync.inputList.length; ++i) {
|
||||||
if (i == self.selfPlayerInfo.joinIndex-1) continue;
|
if (i == self.selfPlayerInfo.joinIndex-1) continue;
|
||||||
inputFrameDownsync.inputList[i] = lastAllConfirmedInputFrame.inputList[i];
|
inputFrameDownsync.inputList[i] = lastAllConfirmedInputFrame.inputList[i];
|
||||||
@ -993,7 +1000,7 @@ cc.Class({
|
|||||||
|
|
||||||
_rollbackAndReplay(inputFrameId1, renderFrameId1, inputFrameId2, renderFrameId2) {
|
_rollbackAndReplay(inputFrameId1, renderFrameId1, inputFrameId2, renderFrameId2) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const rdf1 = self.recentFrameCache[renderFrameId1];
|
const rdf1 = self.recentFrameCache.get(renderFrameId1);
|
||||||
if (null == rdf1) {
|
if (null == rdf1) {
|
||||||
console.error("renderFrameId1=", renderFrameId1, "doesn't exist in recentFrameCache ", self._stringifyRecentFrameCache(false), ": COULDN'T ROLLBACK!");
|
console.error("renderFrameId1=", renderFrameId1, "doesn't exist in recentFrameCache ", self._stringifyRecentFrameCache(false), ": COULDN'T ROLLBACK!");
|
||||||
return;
|
return;
|
||||||
@ -1036,12 +1043,10 @@ cc.Class({
|
|||||||
|
|
||||||
_stringifyRecentFrameCache(usefullOutput) {
|
_stringifyRecentFrameCache(usefullOutput) {
|
||||||
if (true == usefullOutput) {
|
if (true == usefullOutput) {
|
||||||
|
|
||||||
let s = [];
|
let s = [];
|
||||||
for (let renderFrameId in self.recentFrameCache) {
|
self.recentFrameCache.forEach((roomDownsyncFrame, renderFrameId) => {
|
||||||
const roomDownsyncFrame = self.recentFrameCache[renderFrameId];
|
|
||||||
s.push(JSON.stringify(roomDownsyncFrame));
|
s.push(JSON.stringify(roomDownsyncFrame));
|
||||||
}
|
});
|
||||||
|
|
||||||
return s.join('\n');
|
return s.join('\n');
|
||||||
}
|
}
|
||||||
@ -1050,7 +1055,12 @@ cc.Class({
|
|||||||
|
|
||||||
_stringifyRecentInputCache(usefullOutput) {
|
_stringifyRecentInputCache(usefullOutput) {
|
||||||
if (true == usefullOutput) {
|
if (true == usefullOutput) {
|
||||||
return JSON.stringify(this.recentInputCache);
|
let s = [];
|
||||||
|
self.recentInputCache.forEach((inputFrameDownsync, inputFrameId) => {
|
||||||
|
s.push(JSON.stringify(inputFrameDownsync));
|
||||||
|
});
|
||||||
|
|
||||||
|
return s.join('\n');
|
||||||
}
|
}
|
||||||
return "[stInputFrameId=" + self.recentInputCacheSt + ", edInputFrameId=" + self.recentInputCacheEd + ")";
|
return "[stInputFrameId=" + self.recentInputCacheSt + ", edInputFrameId=" + self.recentInputCacheEd + ")";
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user