diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index 6bb7b36..9bdc96d 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -1121,13 +1121,14 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame } self.applyRoomDownsyncFrameDynamics(rdf, prevRdf); self.showDebugBoundaries(rdf); - if (self.showNetworkDoctorInfo) { - self.showNetworkDoctorLabels(); - } ++self.renderFrameId; // [WARNING] It's important to increment the renderFrameId AFTER all the operations above!!! self.lastRenderFrameIdTriggeredAt = performance.now(); let t3 = performance.now(); - self.skipRenderFrameFlag = self.networkDoctor.isTooFast(self); + const [skipRenderFrameFlag, inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, doctorRollbackFrames, skippedRenderFrameCnt] = self.networkDoctor.isTooFast(self); + self.skipRenderFrameFlag = skipRenderFrameFlag; + if (self.showNetworkDoctorInfo) { + self.showNetworkDoctorLabels(inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, doctorRollbackFrames, skippedRenderFrameCnt); + } } catch (err) { console.error("Error during Map.update", err); self.onBattleStopped(); // TODO: Popup to ask player to refresh browser @@ -1626,14 +1627,13 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`); } }, - showNetworkDoctorLabels() { + showNetworkDoctorLabels(inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt) { const self = this; - const [inputFrameFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt] = self.networkDoctor.stats(); if (self.inputFrameFrontLabel) { - self.inputFrameFrontLabel.string = `${inputFrameFront} inputFrameId front`; + self.inputFrameFrontLabel.string = `inputFrameId front: ${inputFrameIdFront}`; } if (self.sendingQLabel) { - self.sendingQLabel.string = `${sendingFps} fps sending`; + self.sendingQLabel.string = `fps sending: ${sendingFps}`; if (sendingFps < self.networkDoctor.inputRateThreshold) { self.sendingQLabel.node.color = cc.Color.RED; } else { @@ -1641,7 +1641,7 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`); } } if (self.inputFrameDownsyncQLabel) { - self.inputFrameDownsyncQLabel.string = `${srvDownsyncFps} fps srv-downsync`; + self.inputFrameDownsyncQLabel.string = `fps srv-downsync: ${srvDownsyncFps}`; if (srvDownsyncFps < self.networkDoctor.inputRateThreshold) { self.inputFrameDownsyncQLabel.node.color = cc.Color.RED; } else { @@ -1649,7 +1649,7 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`); } } if (self.peerInputFrameUpsyncQLabel) { - self.peerInputFrameUpsyncQLabel.string = `${peerUpsyncFps} fps peer-upsync`; + self.peerInputFrameUpsyncQLabel.string = `fps peer-upsync: ${peerUpsyncFps}`; if (peerUpsyncFps > self.networkDoctor.peerUpsyncFps) { self.peerInputFrameUpsyncQLabel.node.color = cc.Color.RED; } else { @@ -1665,7 +1665,7 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`); } } if (self.skippedRenderFrameCntLabel) { - self.skippedRenderFrameCntLabel.string = `${skippedRenderFrameCnt} frames skipped` + self.skippedRenderFrameCntLabel.string = `frames skipped: ${skippedRenderFrameCnt}` } }, }); diff --git a/frontend/assets/scripts/NetworkDoctor.js b/frontend/assets/scripts/NetworkDoctor.js index 0b4c100..0ede564 100644 --- a/frontend/assets/scripts/NetworkDoctor.js +++ b/frontend/assets/scripts/NetworkDoctor.js @@ -55,7 +55,8 @@ NetworkDoctor.prototype.logRollbackFrames = function(x) { }; NetworkDoctor.prototype.stats = function() { - let sendingFps = 0, + let inputFrameIdFront = this.inputFrameIdFront, + sendingFps = 0, srvDownsyncFps = 0, peerUpsyncFps = 0, rollbackFrames = this.immediateRollbackFrames; @@ -77,7 +78,7 @@ NetworkDoctor.prototype.stats = function() { const elapsedMillis = ed.t - st.t; peerUpsyncFps = Math.round(this.peerInputFrameUpsyncCnt * 1000 / elapsedMillis); } - return [this.inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, this.skippedRenderFrameCnt]; + return [inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, this.skippedRenderFrameCnt]; }; NetworkDoctor.prototype.logSkippedRenderFrameCnt = function() { @@ -85,11 +86,11 @@ NetworkDoctor.prototype.logSkippedRenderFrameCnt = function() { } NetworkDoctor.prototype.isTooFast = function(mapIns) { - const [sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt] = this.stats(); + const [inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt] = this.stats(); if (sendingFps >= this.inputRateThreshold + 3) { // Don't send too fast console.log(`Sending too fast, sendingFps=${sendingFps}`); - return true; + return [true, inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt]; } else { const sendingFpsNormal = (sendingFps >= this.inputRateThreshold); // An outstanding lag within the "inputFrameDownsyncQ" will reduce "srvDownsyncFps", HOWEVER, a constant lag wouldn't impact "srvDownsyncFps"! In native platforms we might use PING value might help as a supplement information to confirm that the "selfPlayer" is not lagged within the time accounted by "inputFrameDownsyncQ". @@ -105,11 +106,11 @@ NetworkDoctor.prototype.isTooFast = function(mapIns) { if ((selfInputFrameIdFront > minInputFrameIdFront) && ((selfInputFrameIdFront - minInputFrameIdFront) > (mapIns.inputFrameUpsyncDelayTolerance + 1))) { // first comparison condition is to avoid numeric overflow console.log(`Game logic ticking too fast, selfInputFrameIdFront=${selfInputFrameIdFront}, minInputFrameIdFront=${minInputFrameIdFront}, inputFrameUpsyncDelayTolerance=${mapIns.inputFrameUpsyncDelayTolerance}`); - return true; + return [true, inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt]; } } } - return false; + return [false, inputFrameIdFront, sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt]; }; module.exports = NetworkDoctor;