mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 03:39:00 +00:00
Updated input prediction approach upon dynamics.
This commit is contained in:
parent
7b878ff947
commit
be5200663c
@ -47,11 +47,10 @@ type Player struct {
|
|||||||
TutorialStage int `db:"tutorial_stage"`
|
TutorialStage int `db:"tutorial_stage"`
|
||||||
|
|
||||||
// other in-battle info fields
|
// other in-battle info fields
|
||||||
LastReceivedInputFrameId int32
|
LastConsecutiveRecvInputFrameId int32
|
||||||
LastUdpReceivedInputFrameId int32
|
LastSentInputFrameId int32
|
||||||
LastSentInputFrameId int32
|
AckingFrameId int32
|
||||||
AckingFrameId int32
|
AckingInputFrameId int32
|
||||||
AckingInputFrameId int32
|
|
||||||
|
|
||||||
UdpAddr *PeerUdpAddr
|
UdpAddr *PeerUdpAddr
|
||||||
BattleUdpTunnelAddr *net.UDPAddr // This addr is used by backend only, not visible to frontend
|
BattleUdpTunnelAddr *net.UDPAddr // This addr is used by backend only, not visible to frontend
|
||||||
|
@ -136,7 +136,7 @@ type Room struct {
|
|||||||
EffectivePlayerCount int32
|
EffectivePlayerCount int32
|
||||||
DismissalWaitGroup sync.WaitGroup
|
DismissalWaitGroup sync.WaitGroup
|
||||||
InputsBuffer *resolv.RingBuffer // Indices are STRICTLY consecutive
|
InputsBuffer *resolv.RingBuffer // Indices are STRICTLY consecutive
|
||||||
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange, LastIndividuallyConfirmedInputList, player.LastReceivedInputFrameId, player.LastUdpReceivedInputFrameId]
|
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange, LastIndividuallyConfirmedInputFrameId, LastIndividuallyConfirmedInputList, player.LastConsecutiveRecvInputFrameId]
|
||||||
RenderFrameBuffer *resolv.RingBuffer // Indices are STRICTLY consecutive
|
RenderFrameBuffer *resolv.RingBuffer // Indices are STRICTLY consecutive
|
||||||
LatestPlayerUpsyncedInputFrameId int32
|
LatestPlayerUpsyncedInputFrameId int32
|
||||||
LastAllConfirmedInputFrameId int32
|
LastAllConfirmedInputFrameId int32
|
||||||
@ -156,8 +156,9 @@ type Room struct {
|
|||||||
TmxPointsMap StrToVec2DListMap
|
TmxPointsMap StrToVec2DListMap
|
||||||
TmxPolygonsMap StrToPolygon2DListMap
|
TmxPolygonsMap StrToPolygon2DListMap
|
||||||
|
|
||||||
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
|
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
|
||||||
LastIndividuallyConfirmedInputList []uint64
|
LastIndividuallyConfirmedInputFrameId []int32
|
||||||
|
LastIndividuallyConfirmedInputList []uint64
|
||||||
|
|
||||||
BattleUdpTunnelLock sync.Mutex
|
BattleUdpTunnelLock sync.Mutex
|
||||||
BattleUdpTunnelAddr *pb.PeerUdpAddr
|
BattleUdpTunnelAddr *pb.PeerUdpAddr
|
||||||
@ -194,8 +195,7 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, speciesId int, se
|
|||||||
pPlayerFromDbInit.AckingFrameId = -1
|
pPlayerFromDbInit.AckingFrameId = -1
|
||||||
pPlayerFromDbInit.AckingInputFrameId = -1
|
pPlayerFromDbInit.AckingInputFrameId = -1
|
||||||
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
pPlayerFromDbInit.LastReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
pPlayerFromDbInit.LastConsecutiveRecvInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
pPlayerFromDbInit.LastUdpReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
|
||||||
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
|
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
|
||||||
|
|
||||||
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
||||||
@ -237,7 +237,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
|
|||||||
pEffectiveInRoomPlayerInstance.AckingFrameId = -1
|
pEffectiveInRoomPlayerInstance.AckingFrameId = -1
|
||||||
pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
|
pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
|
||||||
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
|
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
|
||||||
// [WARNING] DON'T reset "player.LastReceivedInputFrameId" & "player.LastUdpReceivedInputFrameId" upon reconnection!
|
// [WARNING] DON'T reset "player.LastConsecutiveRecvInputFrameId" & "pR.LastIndividuallyConfirmedInputFrameId[...]" upon reconnection!
|
||||||
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
|
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
|
||||||
|
|
||||||
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
||||||
@ -804,6 +804,10 @@ func (pR *Room) OnDismissed() {
|
|||||||
pR.RenderFrameBuffer = resolv.NewRingBuffer(pR.RenderCacheSize)
|
pR.RenderFrameBuffer = resolv.NewRingBuffer(pR.RenderCacheSize)
|
||||||
pR.InputsBuffer = resolv.NewRingBuffer((pR.RenderCacheSize >> 1) + 1)
|
pR.InputsBuffer = resolv.NewRingBuffer((pR.RenderCacheSize >> 1) + 1)
|
||||||
pR.rdfIdToActuallyUsedInput = make(map[int32]*pb.InputFrameDownsync)
|
pR.rdfIdToActuallyUsedInput = make(map[int32]*pb.InputFrameDownsync)
|
||||||
|
pR.LastIndividuallyConfirmedInputFrameId = make([]int32, pR.Capacity)
|
||||||
|
for i := 0; i < pR.Capacity; i++ {
|
||||||
|
pR.LastIndividuallyConfirmedInputFrameId[i] = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
|
}
|
||||||
pR.LastIndividuallyConfirmedInputList = make([]uint64, pR.Capacity)
|
pR.LastIndividuallyConfirmedInputList = make([]uint64, pR.Capacity)
|
||||||
|
|
||||||
pR.LatestPlayerUpsyncedInputFrameId = -1
|
pR.LatestPlayerUpsyncedInputFrameId = -1
|
||||||
@ -817,7 +821,7 @@ func (pR *Room) OnDismissed() {
|
|||||||
|
|
||||||
pR.collisionHolder = resolv.NewCollision()
|
pR.collisionHolder = resolv.NewCollision()
|
||||||
pR.effPushbacks = make([]*battle.Vec2D, pR.Capacity)
|
pR.effPushbacks = make([]*battle.Vec2D, pR.Capacity)
|
||||||
for i := 0; i < len(pR.effPushbacks); i++ {
|
for i := 0; i < pR.Capacity; i++ {
|
||||||
pR.effPushbacks[i] = &battle.Vec2D{X: 0, Y: 0}
|
pR.effPushbacks[i] = &battle.Vec2D{X: 0, Y: 0}
|
||||||
}
|
}
|
||||||
pR.hardPushbackNormsArr = make([][]*battle.Vec2D, pR.Capacity)
|
pR.hardPushbackNormsArr = make([][]*battle.Vec2D, pR.Capacity)
|
||||||
@ -1190,9 +1194,9 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
|
|||||||
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#1: roomId=%v, playerId=%v, clientInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, pR.InputsBufferString(false)))
|
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#1: roomId=%v, playerId=%v, clientInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, pR.InputsBufferString(false)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if clientInputFrameId < player.LastReceivedInputFrameId {
|
if clientInputFrameId < player.LastConsecutiveRecvInputFrameId {
|
||||||
// [WARNING] It's important for correctness that we use "player.LastReceivedInputFrameId" instead of "player.LastUdpReceivedInputFrameId" here!
|
// [WARNING] It's important for correctness that we use "player.LastConsecutiveRecvInputFrameId" instead of "pR.LastIndividuallyConfirmedInputFrameId[player.JoinIndex-1]" here!
|
||||||
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, playerLastReceivedInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, player.LastReceivedInputFrameId, pR.InputsBufferString(false)))
|
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, playerLastConsecutiveRecvInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, player.LastConsecutiveRecvInputFrameId, pR.InputsBufferString(false)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if clientInputFrameId > pR.InputsBuffer.EdFrameId {
|
if clientInputFrameId > pR.InputsBuffer.EdFrameId {
|
||||||
@ -1208,19 +1212,19 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
|
|||||||
/*
|
/*
|
||||||
[WARNING] We have to distinguish whether or not the incoming batch is from UDP here, otherwise "pR.LatestPlayerUpsyncedInputFrameId - pR.LastAllConfirmedInputFrameId" might become unexpectedly large in case of "UDP packet loss + slow ws session"!
|
[WARNING] We have to distinguish whether or not the incoming batch is from UDP here, otherwise "pR.LatestPlayerUpsyncedInputFrameId - pR.LastAllConfirmedInputFrameId" might become unexpectedly large in case of "UDP packet loss + slow ws session"!
|
||||||
|
|
||||||
Moreover, only ws session upsyncs should advance "player.LastReceivedInputFrameId" & "pR.LatestPlayerUpsyncedInputFrameId".
|
Moreover, only ws session upsyncs should advance "player.LastConsecutiveRecvInputFrameId" & "pR.LatestPlayerUpsyncedInputFrameId".
|
||||||
|
|
||||||
Kindly note that the updates of "player.LastReceivedInputFrameId" could be discrete before and after reconnection.
|
Kindly note that the updates of "player.LastConsecutiveRecvInputFrameId" could be discrete before and after reconnection.
|
||||||
*/
|
*/
|
||||||
player.LastReceivedInputFrameId = clientInputFrameId
|
player.LastConsecutiveRecvInputFrameId = clientInputFrameId
|
||||||
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
|
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
|
||||||
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId
|
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if clientInputFrameId > player.LastUdpReceivedInputFrameId {
|
if clientInputFrameId > pR.LastIndividuallyConfirmedInputFrameId[player.JoinIndex-1] {
|
||||||
// No need to update "player.LastUdpReceivedInputFrameId" only when "true == fromUDP", we should keep "player.LastUdpReceivedInputFrameId >= player.LastReceivedInputFrameId" at any moment.
|
// No need to update "pR.LastIndividuallyConfirmedInputFrameId[player.JoinIndex-1]" only when "true == fromUDP", we should keep "pR.LastIndividuallyConfirmedInputFrameId[player.JoinIndex-1] >= player.LastConsecutiveRecvInputFrameId" at any moment.
|
||||||
player.LastUdpReceivedInputFrameId = clientInputFrameId
|
pR.LastIndividuallyConfirmedInputFrameId[player.JoinIndex-1] = clientInputFrameId
|
||||||
// It's safe (in terms of getting an eventually correct "RenderFrameBuffer") to put the following update of "pR.LastIndividuallyConfirmedInputList" which is ONLY used for prediction in "InputsBuffer" out of "false == fromUDP" block.
|
// It's safe (in terms of getting an eventually correct "RenderFrameBuffer") to put the following update of "pR.LastIndividuallyConfirmedInputList" which is ONLY used for prediction in "InputsBuffer" out of "false == fromUDP" block.
|
||||||
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
||||||
}
|
}
|
||||||
@ -1379,7 +1383,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame.Id, pR.Space, pR.CollisionSysMap, pR.SpaceOffsetX, pR.SpaceOffsetY, pR.CharacterConfigsArr, pR.RenderFrameBuffer, pR.collisionHolder, pR.effPushbacks, pR.hardPushbackNormsArr, pR.jumpedOrNotList, pR.dynamicRectangleColliders)
|
battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame.Id, pR.Space, pR.CollisionSysMap, pR.SpaceOffsetX, pR.SpaceOffsetY, pR.CharacterConfigsArr, pR.RenderFrameBuffer, pR.collisionHolder, pR.effPushbacks, pR.hardPushbackNormsArr, pR.jumpedOrNotList, pR.dynamicRectangleColliders, pR.LastIndividuallyConfirmedInputFrameId, pR.LastIndividuallyConfirmedInputList)
|
||||||
pR.CurDynamicsRenderFrameId++
|
pR.CurDynamicsRenderFrameId++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,8 +512,7 @@ cc.Class({
|
|||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
||||||
window.initPersistentSessionClient(self.initAfterWSConnected, null /* Deliberately NOT passing in any `expectedRoomId`. -- YFLu */ );
|
window.initPersistentSessionClient(self.initAfterWSConnected, null /* Deliberately NOT passing in any `expectedRoomId`. -- YFLu */ );
|
||||||
};
|
};
|
||||||
resultPanelScriptIns.onCloseDelegate = () => {
|
resultPanelScriptIns.onCloseDelegate = () => {};
|
||||||
};
|
|
||||||
|
|
||||||
self.gameRuleNode = cc.instantiate(self.gameRulePrefab);
|
self.gameRuleNode = cc.instantiate(self.gameRulePrefab);
|
||||||
self.gameRuleNode.width = self.canvasNode.width;
|
self.gameRuleNode.width = self.canvasNode.width;
|
||||||
@ -1428,7 +1427,7 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
|
|||||||
};
|
};
|
||||||
self.rdfIdToActuallyUsedInput.set(i, inputFrameDownsyncClone);
|
self.rdfIdToActuallyUsedInput.set(i, inputFrameDownsyncClone);
|
||||||
}
|
}
|
||||||
const renderRes = gopkgs.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(self.recentInputCache, i, collisionSys, collisionSysMap, self.spaceOffsetX, self.spaceOffsetY, self.chConfigsOrderedByJoinIndex, self.recentRenderCache, self.collisionHolder, self.effPushbacks, self.hardPushbackNormsArr, self.jumpedOrNotList, self.dynamicRectangleColliders);
|
const renderRes = gopkgs.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(self.recentInputCache, i, collisionSys, collisionSysMap, self.spaceOffsetX, self.spaceOffsetY, self.chConfigsOrderedByJoinIndex, self.recentRenderCache, self.collisionHolder, self.effPushbacks, self.hardPushbackNormsArr, self.jumpedOrNotList, self.dynamicRectangleColliders, self.lastIndividuallyConfirmedInputFrameId, self.lastIndividuallyConfirmedInputList);
|
||||||
const nextRdf = gopkgs.GetRoomDownsyncFrame(self.recentRenderCache, i + 1);
|
const nextRdf = gopkgs.GetRoomDownsyncFrame(self.recentRenderCache, i + 1);
|
||||||
|
|
||||||
if (true == isChasing) {
|
if (true == isChasing) {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -76,7 +76,7 @@
|
|||||||
"shelter_z_reducer",
|
"shelter_z_reducer",
|
||||||
"shelter"
|
"shelter"
|
||||||
],
|
],
|
||||||
"last-module-event-record-time": 1676513919950,
|
"last-module-event-record-time": 1677337364473,
|
||||||
"simulator-orientation": false,
|
"simulator-orientation": false,
|
||||||
"simulator-resolution": {
|
"simulator-resolution": {
|
||||||
"height": 640,
|
"height": 640,
|
||||||
|
@ -490,7 +490,18 @@ func calcHardPushbacksNorms(joinIndex int32, currPlayerDownsync, thatPlayerInNex
|
|||||||
return retCnt
|
return retCnt
|
||||||
}
|
}
|
||||||
|
|
||||||
func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, chConfig *CharacterConfig, inputsBuffer *resolv.RingBuffer) (int, bool, int32, int32) {
|
func updateInputFrameInPlaceUponDynamics(inputFrameId int32, roomCapacity int, confirmedList uint64, inputList []uint64, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64) {
|
||||||
|
for i := 0; i < roomCapacity; i++ {
|
||||||
|
if 0 == (confirmedList & (1 << uint32(i))) {
|
||||||
|
// This in-place update on the "inputsBuffer" is only correct when "delayed input for this player is not yet confirmed"
|
||||||
|
if lastIndividuallyConfirmedInputFrameId[i] < inputFrameId {
|
||||||
|
inputList[i] = lastIndividuallyConfirmedInputList[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, chConfig *CharacterConfig, inputsBuffer *resolv.RingBuffer, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64) (int, bool, int32, int32) {
|
||||||
// returns (patternId, jumpedOrNot, effectiveDx, effectiveDy)
|
// returns (patternId, jumpedOrNot, effectiveDx, effectiveDy)
|
||||||
delayedInputFrameId := ConvertToDelayedInputFrameId(currRenderFrame.Id)
|
delayedInputFrameId := ConvertToDelayedInputFrameId(currRenderFrame.Id)
|
||||||
delayedInputFrameIdForPrevRdf := ConvertToDelayedInputFrameId(currRenderFrame.Id - 1)
|
delayedInputFrameIdForPrevRdf := ConvertToDelayedInputFrameId(currRenderFrame.Id - 1)
|
||||||
@ -503,10 +514,17 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
|
|||||||
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
|
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
delayedInputList := inputsBuffer.GetByFrameId(delayedInputFrameId).(*InputFrameDownsync).InputList
|
delayedInputFrameDownsync := inputsBuffer.GetByFrameId(delayedInputFrameId).(*InputFrameDownsync)
|
||||||
|
delayedInputList := delayedInputFrameDownsync.InputList
|
||||||
|
roomCapacity := len(delayedInputList)
|
||||||
|
updateInputFrameInPlaceUponDynamics(delayedInputFrameId, roomCapacity, delayedInputFrameDownsync.ConfirmedList, delayedInputList, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList)
|
||||||
|
|
||||||
var delayedInputListForPrevRdf []uint64 = nil
|
var delayedInputListForPrevRdf []uint64 = nil
|
||||||
if 0 < delayedInputFrameIdForPrevRdf {
|
if 0 < delayedInputFrameIdForPrevRdf {
|
||||||
delayedInputListForPrevRdf = inputsBuffer.GetByFrameId(delayedInputFrameIdForPrevRdf).(*InputFrameDownsync).InputList
|
delayedInputFrameDownsyncForPrevRdf := inputsBuffer.GetByFrameId(delayedInputFrameIdForPrevRdf).(*InputFrameDownsync)
|
||||||
|
delayedInputListForPrevRdf = delayedInputFrameDownsyncForPrevRdf.InputList
|
||||||
|
|
||||||
|
updateInputFrameInPlaceUponDynamics(delayedInputFrameIdForPrevRdf, roomCapacity, delayedInputFrameDownsyncForPrevRdf.ConfirmedList, delayedInputListForPrevRdf, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList)
|
||||||
}
|
}
|
||||||
|
|
||||||
jumpedOrNot := false
|
jumpedOrNot := false
|
||||||
@ -564,7 +582,7 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
|
|||||||
|
|
||||||
The function "ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame" is creating new heap-memory blocks at 60fps, e.g. nextRenderFramePlayers & nextRenderFrameMeleeBullets & nextRenderFrameFireballBullets & effPushbacks & hardPushbackNorms & jumpedOrNotList & dynamicRectangleColliders("player" & "bullet"), which would induce "possibly performance impacting garbage collections" when many rooms are running simultaneously.
|
The function "ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame" is creating new heap-memory blocks at 60fps, e.g. nextRenderFramePlayers & nextRenderFrameMeleeBullets & nextRenderFrameFireballBullets & effPushbacks & hardPushbackNorms & jumpedOrNotList & dynamicRectangleColliders("player" & "bullet"), which would induce "possibly performance impacting garbage collections" when many rooms are running simultaneously.
|
||||||
*/
|
*/
|
||||||
func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *resolv.RingBuffer, currRenderFrameId int32, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, collisionSpaceOffsetX, collisionSpaceOffsetY float64, chConfigsOrderedByJoinIndex []*CharacterConfig, renderFrameBuffer *resolv.RingBuffer, collision *resolv.Collision, effPushbacks []*Vec2D, hardPushbackNormsArr [][]*Vec2D, jumpedOrNotList []bool, dynamicRectangleColliders []*resolv.Object) bool {
|
func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *resolv.RingBuffer, currRenderFrameId int32, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, collisionSpaceOffsetX, collisionSpaceOffsetY float64, chConfigsOrderedByJoinIndex []*CharacterConfig, renderFrameBuffer *resolv.RingBuffer, collision *resolv.Collision, effPushbacks []*Vec2D, hardPushbackNormsArr [][]*Vec2D, jumpedOrNotList []bool, dynamicRectangleColliders []*resolv.Object, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64) bool {
|
||||||
currRenderFrame := renderFrameBuffer.GetByFrameId(currRenderFrameId).(*RoomDownsyncFrame)
|
currRenderFrame := renderFrameBuffer.GetByFrameId(currRenderFrameId).(*RoomDownsyncFrame)
|
||||||
nextRenderFrameId := currRenderFrameId + 1
|
nextRenderFrameId := currRenderFrameId + 1
|
||||||
roomCapacity := len(currRenderFrame.PlayersArr)
|
roomCapacity := len(currRenderFrame.PlayersArr)
|
||||||
@ -613,7 +631,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *resolv.Rin
|
|||||||
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
|
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
|
||||||
chConfig := chConfigsOrderedByJoinIndex[i]
|
chConfig := chConfigsOrderedByJoinIndex[i]
|
||||||
thatPlayerInNextFrame := nextRenderFramePlayers[i]
|
thatPlayerInNextFrame := nextRenderFramePlayers[i]
|
||||||
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, chConfig, inputsBuffer)
|
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, chConfig, inputsBuffer, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList)
|
||||||
|
|
||||||
jumpedOrNotList[i] = jumpedOrNot
|
jumpedOrNotList[i] = jumpedOrNot
|
||||||
joinIndex := currPlayerDownsync.JoinIndex
|
joinIndex := currPlayerDownsync.JoinIndex
|
||||||
|
@ -106,9 +106,9 @@ func GetCharacterConfigsOrderedByJoinIndex(speciesIdList []int) []*js.Object {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(inputsBuffer *resolv.RingBuffer, currRenderFrameId int32, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, collisionSpaceOffsetX, collisionSpaceOffsetY float64, chConfigsOrderedByJoinIndex []*CharacterConfig, renderFrameBuffer *resolv.RingBuffer, collision *resolv.Collision, effPushbacks []*Vec2D, hardPushbackNormsArr [][]*Vec2D, jumpedOrNotList []bool, dynamicRectangleColliders []*resolv.Object) bool {
|
func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(inputsBuffer *resolv.RingBuffer, currRenderFrameId int32, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, collisionSpaceOffsetX, collisionSpaceOffsetY float64, chConfigsOrderedByJoinIndex []*CharacterConfig, renderFrameBuffer *resolv.RingBuffer, collision *resolv.Collision, effPushbacks []*Vec2D, hardPushbackNormsArr [][]*Vec2D, jumpedOrNotList []bool, dynamicRectangleColliders []*resolv.Object, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64) bool {
|
||||||
// We need access to all fields of RoomDownsyncFrame for displaying in frontend
|
// We need access to all fields of RoomDownsyncFrame for displaying in frontend
|
||||||
return ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer, currRenderFrameId, collisionSys, collisionSysMap, collisionSpaceOffsetX, collisionSpaceOffsetY, chConfigsOrderedByJoinIndex, renderFrameBuffer, collision, effPushbacks, hardPushbackNormsArr, jumpedOrNotList, dynamicRectangleColliders)
|
return ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer, currRenderFrameId, collisionSys, collisionSysMap, collisionSpaceOffsetX, collisionSpaceOffsetY, chConfigsOrderedByJoinIndex, renderFrameBuffer, collision, effPushbacks, hardPushbackNormsArr, jumpedOrNotList, dynamicRectangleColliders, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRoomDownsyncFrame(renderFrameBuffer *resolv.RingBuffer, frameId int32) *js.Object {
|
func GetRoomDownsyncFrame(renderFrameBuffer *resolv.RingBuffer, frameId int32) *js.Object {
|
||||||
|
Loading…
Reference in New Issue
Block a user