mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 03:39:00 +00:00
Refined experimental toggle for in-place inputsBuffer update upon dynamics.
This commit is contained in:
parent
91d16b1cc4
commit
b9827f8430
@ -156,9 +156,10 @@ type Room struct {
|
|||||||
TmxPointsMap StrToVec2DListMap
|
TmxPointsMap StrToVec2DListMap
|
||||||
TmxPolygonsMap StrToPolygon2DListMap
|
TmxPolygonsMap StrToPolygon2DListMap
|
||||||
|
|
||||||
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
|
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
|
||||||
LastIndividuallyConfirmedInputFrameId []int32
|
allowUpdateInputFrameInPlaceUponDynamics bool
|
||||||
LastIndividuallyConfirmedInputList []uint64
|
LastIndividuallyConfirmedInputFrameId []int32
|
||||||
|
LastIndividuallyConfirmedInputList []uint64
|
||||||
|
|
||||||
BattleUdpTunnelLock sync.Mutex
|
BattleUdpTunnelLock sync.Mutex
|
||||||
BattleUdpTunnelAddr *pb.PeerUdpAddr
|
BattleUdpTunnelAddr *pb.PeerUdpAddr
|
||||||
@ -804,6 +805,7 @@ 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.allowUpdateInputFrameInPlaceUponDynamics = true
|
||||||
pR.LastIndividuallyConfirmedInputFrameId = make([]int32, pR.Capacity)
|
pR.LastIndividuallyConfirmedInputFrameId = make([]int32, pR.Capacity)
|
||||||
for i := 0; i < pR.Capacity; i++ {
|
for i := 0; i < pR.Capacity; i++ {
|
||||||
pR.LastIndividuallyConfirmedInputFrameId[i] = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
pR.LastIndividuallyConfirmedInputFrameId[i] = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
@ -1303,6 +1305,9 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
|
|||||||
panic(fmt.Sprintf("inputFrameId=%v doesn't exist for roomId=%v! InputsBuffer=%v", j, pR.Id, pR.InputsBufferString(false)))
|
panic(fmt.Sprintf("inputFrameId=%v doesn't exist for roomId=%v! InputsBuffer=%v", j, pR.Id, pR.InputsBufferString(false)))
|
||||||
}
|
}
|
||||||
inputFrameDownsync := tmp.(*battle.InputFrameDownsync)
|
inputFrameDownsync := tmp.(*battle.InputFrameDownsync)
|
||||||
|
if pR.allowUpdateInputFrameInPlaceUponDynamics {
|
||||||
|
battle.UpdateInputFrameInPlaceUponDynamics(j, pR.Capacity, inputFrameDownsync.ConfirmedList, inputFrameDownsync.InputList, pR.LastIndividuallyConfirmedInputFrameId, pR.LastIndividuallyConfirmedInputList, int32(MAGIC_JOIN_INDEX_INVALID))
|
||||||
|
}
|
||||||
unconfirmedMask |= (allConfirmedMask ^ inputFrameDownsync.ConfirmedList)
|
unconfirmedMask |= (allConfirmedMask ^ inputFrameDownsync.ConfirmedList)
|
||||||
inputFrameDownsync.ConfirmedList = allConfirmedMask
|
inputFrameDownsync.ConfirmedList = allConfirmedMask
|
||||||
pR.onInputFrameDownsyncAllConfirmed(inputFrameDownsync, -1)
|
pR.onInputFrameDownsyncAllConfirmed(inputFrameDownsync, -1)
|
||||||
@ -1383,7 +1388,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, pR.LastIndividuallyConfirmedInputFrameId, pR.LastIndividuallyConfirmedInputList, false)
|
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, false, MAGIC_JOIN_INDEX_INVALID) // "allowUpdateInputFrameInPlaceUponDynamics" is instead used when "forceConfirmationIfApplicable"
|
||||||
pR.CurDynamicsRenderFrameId++
|
pR.CurDynamicsRenderFrameId++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1427,8 +1427,8 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
|
|||||||
};
|
};
|
||||||
self.rdfIdToActuallyUsedInput.set(i, inputFrameDownsyncClone);
|
self.rdfIdToActuallyUsedInput.set(i, inputFrameDownsyncClone);
|
||||||
}
|
}
|
||||||
const allowUpdateInputFrameInPlaceUponDynamics = (false == isChasing);
|
const allowUpdateInputFrameInPlaceUponDynamics = (!isChasing);
|
||||||
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, allowUpdateInputFrameInPlaceUponDynamics);
|
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, allowUpdateInputFrameInPlaceUponDynamics, self.selfPlayerInfo.joinIndex);
|
||||||
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
@ -490,18 +490,24 @@ func calcHardPushbacksNorms(joinIndex int32, currPlayerDownsync, thatPlayerInNex
|
|||||||
return retCnt
|
return retCnt
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateInputFrameInPlaceUponDynamics(inputFrameId int32, roomCapacity int, confirmedList uint64, inputList []uint64, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64) {
|
func UpdateInputFrameInPlaceUponDynamics(inputFrameId int32, roomCapacity int, confirmedList uint64, inputList []uint64, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64, toExcludeJoinIndexUpdateInputFrameInPlaceUponDynamics int32) {
|
||||||
for i := 0; i < roomCapacity; i++ {
|
for i := 0; i < roomCapacity; i++ {
|
||||||
if 0 == (confirmedList & (1 << uint32(i))) {
|
if int32(i+1) == toExcludeJoinIndexUpdateInputFrameInPlaceUponDynamics {
|
||||||
// This in-place update on the "inputsBuffer" is only correct when "delayed input for this player is not yet confirmed"
|
// On frontend, a "self input" is only confirmed by websocket downsync, which is quite late and might get the "self input" incorrectly overwritten if not excluded here
|
||||||
if lastIndividuallyConfirmedInputFrameId[i] < inputFrameId {
|
continue
|
||||||
inputList[i] = lastIndividuallyConfirmedInputList[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"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if lastIndividuallyConfirmedInputFrameId[i] >= inputFrameId {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
inputList[i] = (lastIndividuallyConfirmedInputList[i] & uint64(15))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, chConfig *CharacterConfig, inputsBuffer *resolv.RingBuffer, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64, allowUpdateInputFrameInPlaceUponDynamics bool) (int, bool, int32, int32) {
|
func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, chConfig *CharacterConfig, inputsBuffer *resolv.RingBuffer) (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)
|
||||||
@ -516,10 +522,6 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
|
|||||||
|
|
||||||
delayedInputFrameDownsync := inputsBuffer.GetByFrameId(delayedInputFrameId).(*InputFrameDownsync)
|
delayedInputFrameDownsync := inputsBuffer.GetByFrameId(delayedInputFrameId).(*InputFrameDownsync)
|
||||||
delayedInputList := delayedInputFrameDownsync.InputList
|
delayedInputList := delayedInputFrameDownsync.InputList
|
||||||
roomCapacity := len(delayedInputList)
|
|
||||||
if allowUpdateInputFrameInPlaceUponDynamics {
|
|
||||||
updateInputFrameInPlaceUponDynamics(delayedInputFrameId, roomCapacity, delayedInputFrameDownsync.ConfirmedList, delayedInputList, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList)
|
|
||||||
}
|
|
||||||
|
|
||||||
var delayedInputListForPrevRdf []uint64 = nil
|
var delayedInputListForPrevRdf []uint64 = nil
|
||||||
if 0 < delayedInputFrameIdForPrevRdf {
|
if 0 < delayedInputFrameIdForPrevRdf {
|
||||||
@ -582,7 +584,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, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64, allowUpdateInputFrameInPlaceUponDynamics bool) 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, allowUpdateInputFrameInPlaceUponDynamics bool, toExcludeJoinIndexUpdateInputFrameInPlaceUponDynamics int32) 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)
|
||||||
@ -628,10 +630,21 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *resolv.Rin
|
|||||||
|
|
||||||
bulletLocalId := currRenderFrame.BulletLocalIdCounter
|
bulletLocalId := currRenderFrame.BulletLocalIdCounter
|
||||||
// 1. Process player inputs
|
// 1. Process player inputs
|
||||||
|
delayedInputFrameId := ConvertToDelayedInputFrameId(currRenderFrame.Id)
|
||||||
|
|
||||||
|
if 0 < delayedInputFrameId {
|
||||||
|
delayedInputFrameDownsync := inputsBuffer.GetByFrameId(delayedInputFrameId).(*InputFrameDownsync)
|
||||||
|
delayedInputList := delayedInputFrameDownsync.InputList
|
||||||
|
roomCapacity := len(delayedInputList)
|
||||||
|
if allowUpdateInputFrameInPlaceUponDynamics {
|
||||||
|
UpdateInputFrameInPlaceUponDynamics(delayedInputFrameId, roomCapacity, delayedInputFrameDownsync.ConfirmedList, delayedInputList, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList, toExcludeJoinIndexUpdateInputFrameInPlaceUponDynamics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList, allowUpdateInputFrameInPlaceUponDynamics)
|
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, chConfig, inputsBuffer)
|
||||||
|
|
||||||
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, lastIndividuallyConfirmedInputFrameId []int32, lastIndividuallyConfirmedInputList []uint64, allowUpdateInputFrameInPlaceUponDynamics bool) 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, allowUpdateInputFrameInPlaceUponDynamics bool, toExcludeJoinIndexUpdateInputFrameInPlaceUponDynamics int32) 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, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList, allowUpdateInputFrameInPlaceUponDynamics)
|
return ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer, currRenderFrameId, collisionSys, collisionSysMap, collisionSpaceOffsetX, collisionSpaceOffsetY, chConfigsOrderedByJoinIndex, renderFrameBuffer, collision, effPushbacks, hardPushbackNormsArr, jumpedOrNotList, dynamicRectangleColliders, lastIndividuallyConfirmedInputFrameId, lastIndividuallyConfirmedInputList, allowUpdateInputFrameInPlaceUponDynamics, toExcludeJoinIndexUpdateInputFrameInPlaceUponDynamics)
|
||||||
}
|
}
|
||||||
|
|
||||||
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