Further simplified proto communication.

This commit is contained in:
genxium 2023-01-02 20:42:23 +08:00
parent bd870e4059
commit 69581009ee
12 changed files with 859 additions and 1465 deletions

View File

@ -16,7 +16,6 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
CountdownNanos: rdf.CountdownNanos, CountdownNanos: rdf.CountdownNanos,
BackendUnconfirmedMask: rdf.BackendUnconfirmedMask, BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
ShouldForceResync: rdf.ShouldForceResync, ShouldForceResync: rdf.ShouldForceResync,
PlayerOpPatternToSkillId: make(map[int32]int32),
} }
for i, last := range rdf.PlayersArr { for i, last := range rdf.PlayersArr {
@ -28,55 +27,57 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
DirY: last.DirY, DirY: last.DirY,
VelX: last.VelX, VelX: last.VelX,
VelY: last.VelY, VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
Speed: last.Speed, Speed: last.Speed,
BattleState: last.BattleState, BattleState: last.BattleState,
CharacterState: last.CharacterState, CharacterState: last.CharacterState,
InAir: last.InAir, InAir: last.InAir,
JoinIndex: last.JoinIndex, JoinIndex: last.JoinIndex,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Hp: last.Hp, Hp: last.Hp,
MaxHp: last.MaxHp, MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed, Removed: last.Removed,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
} }
ret.PlayersArr[i] = pbPlayer ret.PlayersArr[i] = pbPlayer
} }
for i, last := range rdf.MeleeBullets { for i, last := range rdf.MeleeBullets {
pbBullet := &pb.MeleeBullet{ pbBullet := &pb.MeleeBullet{
BattleLocalId: last.BattleLocalId, OriginatedRenderFrameId: last.OriginatedRenderFrameId,
OffenderJoinIndex: last.OffenderJoinIndex,
StartupFrames: last.StartupFrames, StartupFrames: last.StartupFrames,
CancellableStFrame: last.CancellableStFrame,
CancellableEdFrame: last.CancellableEdFrame,
ActiveFrames: last.ActiveFrames, ActiveFrames: last.ActiveFrames,
RecoveryFrames: last.RecoveryFrames,
RecoveryFramesOnBlock: last.RecoveryFramesOnBlock,
RecoveryFramesOnHit: last.RecoveryFramesOnHit,
HitboxOffset: last.HitboxOffset,
HitStunFrames: last.HitStunFrames, HitStunFrames: last.HitStunFrames,
BlockStunFrames: last.BlockStunFrames, BlockStunFrames: last.BlockStunFrames,
Pushback: last.Pushback, PushbackVelX: last.PushbackVelX,
ReleaseTriggerType: last.ReleaseTriggerType, PushbackVelY: last.PushbackVelY,
Damage: last.Damage, Damage: last.Damage,
SelfMoveforwardX: last.SelfMoveforwardX, SelfLockVelX: last.SelfLockVelX,
SelfMoveforwardY: last.SelfMoveforwardY, SelfLockVelY: last.SelfLockVelY,
HitboxSizeX: last.HitboxSizeX,
HitboxSizeY: last.HitboxSizeY,
OffenderJoinIndex: last.OffenderJoinIndex, HitboxOffsetX: last.HitboxOffsetX,
OffenderPlayerId: last.OffenderPlayerId, HitboxOffsetY: last.HitboxOffsetY,
HitboxSizeX: last.HitboxSizeX,
HitboxSizeY: last.HitboxSizeY,
BlowUp: last.BlowUp,
} }
ret.MeleeBullets[i] = pbBullet ret.MeleeBullets[i] = pbBullet
} }
for i, last := range rdf.PlayerOpPatternToSkillId {
ret.PlayerOpPatternToSkillId[int32(i)] = int32(last)
}
return ret return ret
} }
/*
func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.PlayerDownsync { func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.PlayerDownsync {
toRet := make([]*pb.PlayerDownsync, len(modelInstances), len(modelInstances)) toRet := make([]*pb.PlayerDownsync, len(modelInstances), len(modelInstances))
if nil == modelInstances { if nil == modelInstances {
@ -113,6 +114,7 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
return toRet return toRet
} }
*/
func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync { func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
toRet := make([]*battle.PlayerDownsync, len(modelInstances), len(modelInstances)) toRet := make([]*battle.PlayerDownsync, len(modelInstances), len(modelInstances))
@ -129,12 +131,18 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
DirY: last.DirY, DirY: last.DirY,
VelX: last.VelX, VelX: last.VelX,
VelY: last.VelY, VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
Speed: last.Speed, Speed: last.Speed,
BattleState: last.BattleState, BattleState: last.BattleState,
CharacterState: last.CharacterState, CharacterState: last.CharacterState,
InAir: last.InAir,
JoinIndex: last.JoinIndex, JoinIndex: last.JoinIndex,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius, ColliderRadius: last.ColliderRadius,
InAir: last.InAir,
Score: last.Score, Score: last.Score,
Removed: last.Removed, Removed: last.Removed,
} }

View File

@ -49,7 +49,7 @@ const (
) )
const ( const (
DEFAULT_PLAYER_RADIUS = float64(12) DEFAULT_PLAYER_RADIUS = int32(float64(12) * battle.WORLD_TO_VIRTUAL_GRID_RATIO)
) )
type RoomBattleState struct { type RoomBattleState struct {
@ -90,8 +90,6 @@ func calRoomScore(inRoomPlayerCount int32, roomPlayerCnt int, currentRoomBattleS
type Room struct { type Room struct {
Id int32 Id int32
Capacity int Capacity int
collisionSpaceOffsetX float64
collisionSpaceOffsetY float64
Players map[int32]*Player Players map[int32]*Player
PlayersArr []*Player // ordered by joinIndex PlayersArr []*Player // ordered by joinIndex
Space *resolv.Space Space *resolv.Space
@ -288,35 +286,14 @@ func (pR *Room) ChooseStage() error {
//Logger.Info("parsed tmx:", zap.Any("stageDiscreteW", stageDiscreteW), zap.Any("strToVec2DListMap", strToVec2DListMap), zap.Any("strToPolygon2DListMap", strToPolygon2DListMap)) //Logger.Info("parsed tmx:", zap.Any("stageDiscreteW", stageDiscreteW), zap.Any("strToVec2DListMap", strToVec2DListMap), zap.Any("strToPolygon2DListMap", strToPolygon2DListMap))
pR.StageDiscreteW = stageDiscreteW pR.SpaceOffsetX = float64((stageDiscreteW*stageTileW) >> 1)
pR.StageDiscreteH = stageDiscreteH pR.SpaceOffsetY = float64((stageDiscreteH*stageTileH) >> 1)
pR.StageTileW = stageTileW
pR.StageTileH = stageTileH
pR.TmxPointsMap = strToVec2DListMap pR.TmxPointsMap = strToVec2DListMap
pR.TmxPolygonsMap = strToPolygon2DListMap pR.TmxPolygonsMap = strToPolygon2DListMap
return nil return nil
} }
func (pR *Room) ConvertToInputFrameId(renderFrameId int32, inputDelayFrames int32) int32 {
if renderFrameId < inputDelayFrames {
return 0
}
return ((renderFrameId - inputDelayFrames) >> pR.InputScaleFrames)
}
func (pR *Room) ConvertToGeneratingRenderFrameId(inputFrameId int32) int32 {
return (inputFrameId << pR.InputScaleFrames)
}
func (pR *Room) ConvertToFirstUsedRenderFrameId(inputFrameId int32, inputDelayFrames int32) int32 {
return ((inputFrameId << pR.InputScaleFrames) + inputDelayFrames)
}
func (pR *Room) ConvertToLastUsedRenderFrameId(inputFrameId int32, inputDelayFrames int32) int32 {
return ((inputFrameId << pR.InputScaleFrames) + inputDelayFrames + (1 << pR.InputScaleFrames) - 1)
}
func (pR *Room) RenderFrameBufferString() string { func (pR *Room) RenderFrameBufferString() string {
return fmt.Sprintf("{renderFrameId: %d, stRenderFrameId: %d, edRenderFrameId: %d, curDynamicsRenderFrameId: %d}", pR.RenderFrameId, pR.RenderFrameBuffer.StFrameId, pR.RenderFrameBuffer.EdFrameId, pR.CurDynamicsRenderFrameId) return fmt.Sprintf("{renderFrameId: %d, stRenderFrameId: %d, edRenderFrameId: %d, curDynamicsRenderFrameId: %d}", pR.RenderFrameId, pR.RenderFrameBuffer.StFrameId, pR.RenderFrameBuffer.EdFrameId, pR.CurDynamicsRenderFrameId)
} }
@ -406,11 +383,7 @@ func (pR *Room) StartBattle() {
pR.RenderFrameBuffer.Put(kickoffFrameJs) pR.RenderFrameBuffer.Put(kickoffFrameJs)
// Refresh "Colliders" // Refresh "Colliders"
spaceW := pR.StageDiscreteW * pR.StageTileW pR.refreshColliders()
spaceH := pR.StageDiscreteH * pR.StageTileH
pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY = float64(spaceW)*0.5, float64(spaceH)*0.5
pR.refreshColliders(spaceW, spaceH)
/* /*
Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached. Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached.
@ -424,7 +397,7 @@ func (pR *Room) StartBattle() {
Logger.Error("battleMainLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r)) Logger.Error("battleMainLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r))
} }
pR.StopBattleForSettlement() pR.StopBattleForSettlement()
Logger.Info(fmt.Sprintf("The `battleMainLoop` for roomId=%v is stopped@renderFrameId=%v, with battleDurationFrames=%v:\n%v", pR.Id, pR.RenderFrameId, pR.BattleDurationFrames, pR.InputsBufferString(false))) // This takes sometime to print Logger.Info(fmt.Sprintf("The `battleMainLoop` for roomId=%v is stopped@renderFrameId=%v:\n%v", pR.Id, pR.RenderFrameId, pR.InputsBufferString(false))) // This takes sometime to print
if pR.FrameDataLoggingEnabled { if pR.FrameDataLoggingEnabled {
rdfIdToActuallyUsedInputDump := pR.rdfIdToActuallyUsedInputString() rdfIdToActuallyUsedInputDump := pR.rdfIdToActuallyUsedInputString()
os.WriteFile(fmt.Sprintf("room_%d.txt", pR.Id), []byte(rdfIdToActuallyUsedInputDump), 0644) // DEBUG ONLY os.WriteFile(fmt.Sprintf("room_%d.txt", pR.Id), []byte(rdfIdToActuallyUsedInputDump), 0644) // DEBUG ONLY
@ -1030,15 +1003,6 @@ func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputF
} }
} }
func (pR *Room) shouldPrefabInputFrameDownsync(prevRenderFrameId int32, renderFrameId int32) (bool, int32) {
for i := prevRenderFrameId + 1; i <= renderFrameId; i++ {
if (0 <= i) && (0 == (i & ((1 << pR.InputScaleFrames) - 1))) {
return true, i
}
}
return false, -1
}
func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputFrameDownsync { func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputFrameDownsync {
/* /*
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked. [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked.
@ -1157,7 +1121,7 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
*/ */
snapshotStFrameId := (pR.LastAllConfirmedInputFrameId - newAllConfirmedCount) snapshotStFrameId := (pR.LastAllConfirmedInputFrameId - newAllConfirmedCount)
refRenderFrameIdIfNeeded := pR.CurDynamicsRenderFrameId - 1 refRenderFrameIdIfNeeded := pR.CurDynamicsRenderFrameId - 1
refSnapshotStFrameId := pR.ConvertToInputFrameId(refRenderFrameIdIfNeeded, pR.InputDelayFrames) refSnapshotStFrameId := battle.ConvertToInputFrameId(refRenderFrameIdIfNeeded, battle.INPUT_DELAY_FRAMES, battle.INPUT_SCALE_FRAMES)
if refSnapshotStFrameId < snapshotStFrameId { if refSnapshotStFrameId < snapshotStFrameId {
snapshotStFrameId = refSnapshotStFrameId snapshotStFrameId = refSnapshotStFrameId
} }
@ -1224,7 +1188,7 @@ func (pR *Room) produceInputsBufferSnapshotWithCurDynamicsRenderFrameAsRef(uncon
} }
} }
func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRenderFrameId int32, spaceOffsetX, spaceOffsetY float64) { func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRenderFrameId int32) {
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked! // [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
if fromRenderFrameId >= toRenderFrameId { if fromRenderFrameId >= toRenderFrameId {
return return
@ -1238,7 +1202,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
panic(fmt.Sprintf("collisionSysRenderFrameId=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v)! RenderFrameBuffer=%v", collisionSysRenderFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, pR.RenderFrameBufferString())) panic(fmt.Sprintf("collisionSysRenderFrameId=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v)! RenderFrameBuffer=%v", collisionSysRenderFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, pR.RenderFrameBufferString()))
} }
currRenderFrame := currRenderFrameTmp.(*battle.RoomDownsyncFrame) currRenderFrame := currRenderFrameTmp.(*battle.RoomDownsyncFrame)
delayedInputFrameId := pR.ConvertToInputFrameId(collisionSysRenderFrameId, pR.InputDelayFrames) delayedInputFrameId := battle.ConvertToDelayedInputFrameId(collisionSysRenderFrameId)
if 0 <= delayedInputFrameId { if 0 <= delayedInputFrameId {
if delayedInputFrameId > pR.LastAllConfirmedInputFrameId { if delayedInputFrameId > pR.LastAllConfirmedInputFrameId {
panic(fmt.Sprintf("delayedInputFrameId=%v is not yet all-confirmed for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false))) panic(fmt.Sprintf("delayedInputFrameId=%v is not yet all-confirmed for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false)))
@ -1262,18 +1226,16 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
} }
} }
nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY) nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.SpaceOffsetX, pR.SpaceOffsetY)
pR.RenderFrameBuffer.Put(nextRenderFrame) pR.RenderFrameBuffer.Put(nextRenderFrame)
pR.CurDynamicsRenderFrameId++ pR.CurDynamicsRenderFrameId++
} }
} }
func (pR *Room) refreshColliders(spaceW, spaceH int32) { func (pR *Room) refreshColliders() {
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups" // Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
topPadding, bottomPadding, leftPadding, rightPadding := pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap pR.Space = resolv.NewSpace(int(pR.SpaceOffsetX*2), int(pR.SpaceOffsetY*2), int(pR.CollisionMinStep), int(pR.CollisionMinStep)) // allocate a new collision space everytime after a battle is settled
pR.Space = resolv.NewSpace(int(spaceW), int(spaceH), int(pR.CollisionMinStep), int(pR.CollisionMinStep)) // allocate a new collision space everytime after a battle is settled
for _, player := range pR.Players { for _, player := range pR.Players {
joinIndex := player.JoinIndex joinIndex := player.JoinIndex
@ -1305,8 +1267,8 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock unlocked: roomId=%v", pR.Id)) Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock unlocked: roomId=%v", pR.Id))
}() }()
if ok, thatRenderFrameId := pR.shouldPrefabInputFrameDownsync(prevRenderFrameId, pR.RenderFrameId); ok { if ok, thatRenderFrameId := battle.ShouldPrefabInputFrameDownsync(prevRenderFrameId, pR.RenderFrameId); ok {
noDelayInputFrameId := pR.ConvertToInputFrameId(thatRenderFrameId, 0) noDelayInputFrameId := battle.ConvertToNoDelayInputFrameId(thatRenderFrameId)
pR.getOrPrefabInputFrameDownsync(noDelayInputFrameId) pR.getOrPrefabInputFrameDownsync(noDelayInputFrameId)
} }
@ -1317,9 +1279,9 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
if 0 <= pR.LastAllConfirmedInputFrameId { if 0 <= pR.LastAllConfirmedInputFrameId {
dynamicsStartedAt := utils.UnixtimeNano() dynamicsStartedAt := utils.UnixtimeNano()
// Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId" // Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId"
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames) + 1 nextDynamicsRenderFrameId := battle.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId) + 1
Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId)) Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId))
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY) pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId)
*pDynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt *pDynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt
} }
@ -1336,7 +1298,7 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
if 0 < unconfirmedMask { if 0 < unconfirmedMask {
// [WARNING] As "pR.CurDynamicsRenderFrameId" was just incremented above, "refSnapshotStFrameId" is most possibly larger than "oldLastAllConfirmedInputFrameId + 1", therefore this initial assignment is critical for `ACTIVE NORMAL TICKER`s to receive consecutive ids of inputFrameDownsync. // [WARNING] As "pR.CurDynamicsRenderFrameId" was just incremented above, "refSnapshotStFrameId" is most possibly larger than "oldLastAllConfirmedInputFrameId + 1", therefore this initial assignment is critical for `ACTIVE NORMAL TICKER`s to receive consecutive ids of inputFrameDownsync.
snapshotStFrameId := oldLastAllConfirmedInputFrameId + 1 snapshotStFrameId := oldLastAllConfirmedInputFrameId + 1
refSnapshotStFrameId := pR.ConvertToInputFrameId(pR.CurDynamicsRenderFrameId-1, pR.InputDelayFrames) refSnapshotStFrameId := battle.ConvertToDelayedInputFrameId(pR.CurDynamicsRenderFrameId-1)
if refSnapshotStFrameId < snapshotStFrameId { if refSnapshotStFrameId < snapshotStFrameId {
snapshotStFrameId = refSnapshotStFrameId snapshotStFrameId = refSnapshotStFrameId
} }

File diff suppressed because it is too large Load Diff

View File

@ -242,34 +242,21 @@ func Serve(c *gin.Context) {
bciFrame := &pb.BattleColliderInfo{ bciFrame := &pb.BattleColliderInfo{
BoundRoomId: pRoom.Id, BoundRoomId: pRoom.Id,
StageName: pRoom.StageName, StageName: pRoom.StageName,
StageDiscreteW: pRoom.StageDiscreteW,
StageDiscreteH: pRoom.StageDiscreteH,
StageTileW: pRoom.StageTileW,
StageTileH: pRoom.StageTileH,
IntervalToPing: int32(Constants.Ws.IntervalToPing), IntervalToPing: int32(Constants.Ws.IntervalToPing),
WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor), WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor),
BattleDurationNanos: pRoom.BattleDurationNanos, BattleDurationNanos: pRoom.BattleDurationNanos,
ServerFps: pRoom.ServerFps,
InputDelayFrames: pRoom.InputDelayFrames,
InputScaleFrames: pRoom.InputScaleFrames,
NstDelayFrames: pRoom.NstDelayFrames,
InputFrameUpsyncDelayTolerance: pRoom.InputFrameUpsyncDelayTolerance, InputFrameUpsyncDelayTolerance: pRoom.InputFrameUpsyncDelayTolerance,
MaxChasingRenderFramesPerUpdate: pRoom.MaxChasingRenderFramesPerUpdate, MaxChasingRenderFramesPerUpdate: pRoom.MaxChasingRenderFramesPerUpdate,
PlayerBattleState: pThePlayer.BattleState, // For frontend to know whether it's rejoining PlayerBattleState: pThePlayer.BattleState, // For frontend to know whether it's rejoining
RollbackEstimatedDtMillis: pRoom.RollbackEstimatedDtMillis, RollbackEstimatedDtMillis: pRoom.RollbackEstimatedDtMillis,
RollbackEstimatedDtNanos: pRoom.RollbackEstimatedDtNanos, RollbackEstimatedDtNanos: pRoom.RollbackEstimatedDtNanos,
WorldToVirtualGridRatio: pRoom.WorldToVirtualGridRatio, InputDelayFrames: pRoom.InputDelayFrames,
VirtualGridToWorldRatio: pRoom.VirtualGridToWorldRatio, InputScaleFrames: pRoom.InputScaleFrames,
SpAtkLookupFrames: pRoom.SpAtkLookupFrames,
RenderCacheSize: pRoom.RenderCacheSize, RenderCacheSize: pRoom.RenderCacheSize,
SnapIntoPlatformOverlap: pRoom.SnapIntoPlatformOverlap,
SnapIntoPlatformThreshold: pRoom.SnapIntoPlatformThreshold,
JumpingInitVelY: pRoom.JumpingInitVelY,
GravityX: pRoom.GravityX,
GravityY: pRoom.GravityY,
CollisionMinStep: pRoom.CollisionMinStep, CollisionMinStep: pRoom.CollisionMinStep,
FrameDataLoggingEnabled: pRoom.FrameDataLoggingEnabled, FrameDataLoggingEnabled: pRoom.FrameDataLoggingEnabled,

View File

@ -4724,7 +4724,7 @@ $packages["resolv"] = (function() {
return $pkg; return $pkg;
})(); })();
$packages["jsexport/battle"] = (function() { $packages["jsexport/battle"] = (function() {
var $pkg = {}, $init, math, resolv, Vec2D, Polygon2D, PlayerDownsync, InputFrameDecoded, Barrier, Bullet, MeleeBullet, FireballBullet, Skill, RoomDownsyncFrame, InputFrameDownsync, RingBuffer, SkillMapperType, CharacterConfig, SatResult, sliceType, sliceType$1, sliceType$2, ptrType, ptrType$1, ptrType$2, sliceType$3, sliceType$4, ptrType$3, ptrType$4, ptrType$5, ptrType$6, ptrType$7, sliceType$5, sliceType$6, sliceType$7, sliceType$8, sliceType$9, ptrType$8, sliceType$10, ptrType$9, sliceType$11, sliceType$12, ptrType$10, sliceType$13, ptrType$11, mapType, ptrType$12, skills, inAirSet, noOpSet, invinsibleSet, nonAttackingSet, NewRingBuffer, ConvertToInputFrameId, decodeInput, CalcPushbacks, isPolygonPairOverlapped, isPolygonPairSeparatedByDir, WorldToVirtualGridPos, VirtualGridToWorldPos, WorldToPolygonColliderBLPos, PolygonColliderBLToWorldPos, PolygonColliderBLToVirtualGridPos, calcHardPushbacksNorms, deriveOpPattern, ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame, GenerateRectCollider, generateRectColliderInCollisionSpace, GenerateConvexPolygonCollider, AlignPolygon2DToBoundingBox; var $pkg = {}, $init, math, resolv, Vec2D, Polygon2D, PlayerDownsync, InputFrameDecoded, Barrier, Bullet, MeleeBullet, FireballBullet, Skill, RoomDownsyncFrame, InputFrameDownsync, RingBuffer, SkillMapperType, CharacterConfig, SatResult, sliceType, sliceType$1, sliceType$2, ptrType, ptrType$1, ptrType$2, sliceType$3, sliceType$4, ptrType$3, ptrType$4, ptrType$5, ptrType$6, ptrType$7, sliceType$5, sliceType$6, sliceType$7, sliceType$8, sliceType$9, ptrType$8, sliceType$10, ptrType$9, sliceType$11, sliceType$12, ptrType$10, sliceType$13, ptrType$11, mapType, ptrType$12, skills, inAirSet, noOpSet, invinsibleSet, nonAttackingSet, NewRingBuffer, ShouldGenerateInputFrameUpsync, ConvertToDelayedInputFrameId, ConvertToNoDelayInputFrameId, ConvertToFirstUsedRenderFrameId, ConvertToLastUsedRenderFrameId, decodeInput, CalcPushbacks, isPolygonPairOverlapped, isPolygonPairSeparatedByDir, WorldToVirtualGridPos, VirtualGridToWorldPos, WorldToPolygonColliderBLPos, PolygonColliderBLToWorldPos, PolygonColliderBLToVirtualGridPos, calcHardPushbacksNorms, deriveOpPattern, ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame, GenerateRectCollider, generateRectColliderInCollisionSpace, GenerateConvexPolygonCollider, AlignPolygon2DToBoundingBox;
math = $packages["math"]; math = $packages["math"];
resolv = $packages["resolv"]; resolv = $packages["resolv"];
Vec2D = $pkg.Vec2D = $newType(0, $kindStruct, "battle.Vec2D", true, "jsexport/battle", true, function(X_, Y_) { Vec2D = $pkg.Vec2D = $newType(0, $kindStruct, "battle.Vec2D", true, "jsexport/battle", true, function(X_, Y_) {
@ -5152,14 +5152,34 @@ $packages["jsexport/battle"] = (function() {
return [ret, oldStFrameId, oldEdFrameId]; return [ret, oldStFrameId, oldEdFrameId];
}; };
RingBuffer.prototype.SetByFrameId = function(pItem, frameId) { return this.$val.SetByFrameId(pItem, frameId); }; RingBuffer.prototype.SetByFrameId = function(pItem, frameId) { return this.$val.SetByFrameId(pItem, frameId); };
ConvertToInputFrameId = function(renderFrameId, inputDelayFrames, inputScaleFrames) { ShouldGenerateInputFrameUpsync = function(renderFrameId) {
var inputDelayFrames, inputScaleFrames, renderFrameId; var renderFrameId;
if (renderFrameId < inputDelayFrames) { return (((renderFrameId & 3)) === 0);
};
$pkg.ShouldGenerateInputFrameUpsync = ShouldGenerateInputFrameUpsync;
ConvertToDelayedInputFrameId = function(renderFrameId) {
var renderFrameId;
if (renderFrameId < 8) {
return 0; return 0;
} }
return ((((renderFrameId - inputDelayFrames >> 0)) >> $min(inputScaleFrames, 31)) >> 0); return (((renderFrameId - 8 >> 0)) >> 2 >> 0);
}; };
$pkg.ConvertToInputFrameId = ConvertToInputFrameId; $pkg.ConvertToDelayedInputFrameId = ConvertToDelayedInputFrameId;
ConvertToNoDelayInputFrameId = function(renderFrameId) {
var renderFrameId;
return (renderFrameId >> 2 >> 0);
};
$pkg.ConvertToNoDelayInputFrameId = ConvertToNoDelayInputFrameId;
ConvertToFirstUsedRenderFrameId = function(inputFrameId) {
var inputFrameId;
return (((inputFrameId << 2 >> 0)) + 8 >> 0);
};
$pkg.ConvertToFirstUsedRenderFrameId = ConvertToFirstUsedRenderFrameId;
ConvertToLastUsedRenderFrameId = function(inputFrameId) {
var inputFrameId;
return (((((inputFrameId << 2 >> 0)) + 8 >> 0) + 4 >> 0) - 1 >> 0);
};
$pkg.ConvertToLastUsedRenderFrameId = ConvertToLastUsedRenderFrameId;
decodeInput = function(encodedInput) { decodeInput = function(encodedInput) {
var btnALevel, btnBLevel, encodedDirection, encodedInput, x, x$1, x$2, x$3; var btnALevel, btnBLevel, encodedDirection, encodedInput, x, x$1, x$2, x$3;
encodedDirection = new $Uint64(encodedInput.$high & 0, (encodedInput.$low & 15) >>> 0); encodedDirection = new $Uint64(encodedInput.$high & 0, (encodedInput.$low & 15) >>> 0);
@ -5408,10 +5428,10 @@ $packages["jsexport/battle"] = (function() {
$s = -1; return (ret.$ptr || (ret.$ptr = new ptrType$4(function() { return this.$target[0]; }, function($v) { this.$target[0] = $v; }, ret))); $s = -1; return (ret.$ptr || (ret.$ptr = new ptrType$4(function() { return this.$target[0]; }, function($v) { this.$target[0] = $v; }, ret)));
/* */ } return; } var $f = {$blk: calcHardPushbacksNorms, $c: true, $r, _i, _r, _ref, _ref$1, _tmp, _tmp$1, _tuple, barrierShape, collision, isBarrier, joinIndex, obj, overlapResult, overlapped, pEffPushback, playerCollider, playerShape, pushbackX, pushbackY, ret, snapIntoPlatformOverlap, $s};return $f; /* */ } return; } var $f = {$blk: calcHardPushbacksNorms, $c: true, $r, _i, _r, _ref, _ref$1, _tmp, _tmp$1, _tuple, barrierShape, collision, isBarrier, joinIndex, obj, overlapResult, overlapped, pEffPushback, playerCollider, playerShape, pushbackX, pushbackY, ret, snapIntoPlatformOverlap, $s};return $f;
}; };
deriveOpPattern = function(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer, inputDelayFrames, inputScaleFrames) { deriveOpPattern = function(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer) {
var _entry, _entry$1, _tmp, _tmp$1, _tmp$2, _tmp$3, _tmp$4, _tmp$5, _tuple, _tuple$1, currPlayerDownsync, currRenderFrame, decodedInput, delayedInputFrameId, delayedInputFrameIdForPrevRdf, delayedInputList, delayedInputListForPrevRdf, effDx, effDy, existent, existent$1, inputDelayFrames, inputScaleFrames, inputsBuffer, joinIndex, jumpedOrNot, patternId, prevBtnALevel, prevBtnBLevel, prevDecodedInput, thatPlayerInNextFrame, x, x$1; var _entry, _entry$1, _tmp, _tmp$1, _tmp$2, _tmp$3, _tmp$4, _tmp$5, _tuple, _tuple$1, currPlayerDownsync, currRenderFrame, decodedInput, delayedInputFrameId, delayedInputFrameIdForPrevRdf, delayedInputList, delayedInputListForPrevRdf, effDx, effDy, existent, existent$1, inputsBuffer, joinIndex, jumpedOrNot, patternId, prevBtnALevel, prevBtnBLevel, prevDecodedInput, thatPlayerInNextFrame, x, x$1;
delayedInputFrameId = ConvertToInputFrameId(currRenderFrame.Id, inputDelayFrames, inputScaleFrames); delayedInputFrameId = ConvertToDelayedInputFrameId(currRenderFrame.Id);
delayedInputFrameIdForPrevRdf = ConvertToInputFrameId(currRenderFrame.Id - 1 >> 0, inputDelayFrames, inputScaleFrames); delayedInputFrameIdForPrevRdf = ConvertToDelayedInputFrameId(currRenderFrame.Id - 1 >> 0);
if (0 >= delayedInputFrameId) { if (0 >= delayedInputFrameId) {
return [-2, false, 0, 0]; return [-2, false, 0, 0];
} }
@ -5491,7 +5511,7 @@ $packages["jsexport/battle"] = (function() {
((i$1 < 0 || i$1 >= jumpedOrNotList.$length) ? ($throwRuntimeError("index out of range"), undefined) : jumpedOrNotList.$array[jumpedOrNotList.$offset + i$1] = false); ((i$1 < 0 || i$1 >= jumpedOrNotList.$length) ? ($throwRuntimeError("index out of range"), undefined) : jumpedOrNotList.$array[jumpedOrNotList.$offset + i$1] = false);
chConfig = ((i$1 < 0 || i$1 >= chConfigsOrderedByJoinIndex.$length) ? ($throwRuntimeError("index out of range"), undefined) : chConfigsOrderedByJoinIndex.$array[chConfigsOrderedByJoinIndex.$offset + i$1]); chConfig = ((i$1 < 0 || i$1 >= chConfigsOrderedByJoinIndex.$length) ? ($throwRuntimeError("index out of range"), undefined) : chConfigsOrderedByJoinIndex.$array[chConfigsOrderedByJoinIndex.$offset + i$1]);
thatPlayerInNextFrame = ((i$1 < 0 || i$1 >= nextRenderFramePlayers.$length) ? ($throwRuntimeError("index out of range"), undefined) : nextRenderFramePlayers.$array[nextRenderFramePlayers.$offset + i$1]); thatPlayerInNextFrame = ((i$1 < 0 || i$1 >= nextRenderFramePlayers.$length) ? ($throwRuntimeError("index out of range"), undefined) : nextRenderFramePlayers.$array[nextRenderFramePlayers.$offset + i$1]);
_tuple = deriveOpPattern(currPlayerDownsync$1, thatPlayerInNextFrame, currRenderFrame, inputsBuffer, 8, 2); _tuple = deriveOpPattern(currPlayerDownsync$1, thatPlayerInNextFrame, currRenderFrame, inputsBuffer);
patternId = _tuple[0]; patternId = _tuple[0];
jumpedOrNot = _tuple[1]; jumpedOrNot = _tuple[1];
effDx = _tuple[2]; effDx = _tuple[2];
@ -6066,7 +6086,7 @@ $packages["jsexport/battle"] = (function() {
return $pkg; return $pkg;
})(); })();
$packages["jsexport"] = (function() { $packages["jsexport"] = (function() {
var $pkg = {}, $init, js, battle, resolv, sliceType, ptrType, sliceType$1, ptrType$1, ptrType$2, sliceType$2, ptrType$3, sliceType$3, ptrType$4, sliceType$4, ptrType$5, sliceType$5, ptrType$6, funcType, funcType$1, funcType$2, funcType$3, funcType$4, funcType$5, funcType$6, funcType$7, funcType$8, funcType$9, funcType$10, ptrType$7, funcType$11, funcType$12, funcType$13, funcType$14, sliceType$6, funcType$15, ptrType$8, ptrType$9, ptrType$10, mapType, sliceType$7, funcType$16, mapType$1, NewInputFrameDownsync, NewRingBufferJs, NewCollisionSpaceJs, NewVec2DJs, NewPolygon2DJs, NewBarrierJs, NewPlayerDownsyncJs, NewMeleeBulletJs, NewRoomDownsyncFrameJs, GetCollisionSpaceObjsJs, GenerateRectColliderJs, GenerateConvexPolygonColliderJs, GetCharacterConfigsOrderedByJoinIndex, ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs, main; var $pkg = {}, $init, js, battle, resolv, sliceType, ptrType, sliceType$1, ptrType$1, ptrType$2, sliceType$2, ptrType$3, sliceType$3, ptrType$4, sliceType$4, ptrType$5, sliceType$5, ptrType$6, funcType, funcType$1, funcType$2, funcType$3, funcType$4, funcType$5, funcType$6, funcType$7, funcType$8, funcType$9, funcType$10, ptrType$7, funcType$11, funcType$12, funcType$13, funcType$14, sliceType$6, funcType$15, ptrType$8, ptrType$9, ptrType$10, mapType, sliceType$7, funcType$16, funcType$17, funcType$18, mapType$1, NewInputFrameDownsync, NewRingBufferJs, NewCollisionSpaceJs, NewVec2DJs, NewPolygon2DJs, NewBarrierJs, NewPlayerDownsyncJs, NewMeleeBulletJs, NewRoomDownsyncFrameJs, GetCollisionSpaceObjsJs, GenerateRectColliderJs, GenerateConvexPolygonColliderJs, GetCharacterConfigsOrderedByJoinIndex, ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs, main;
js = $packages["github.com/gopherjs/gopherjs/js"]; js = $packages["github.com/gopherjs/gopherjs/js"];
battle = $packages["jsexport/battle"]; battle = $packages["jsexport/battle"];
resolv = $packages["resolv"]; resolv = $packages["resolv"];
@ -6086,7 +6106,7 @@ $packages["jsexport"] = (function() {
funcType = $funcType([$Float64, $Float64], [ptrType$5], false); funcType = $funcType([$Float64, $Float64], [ptrType$5], false);
funcType$1 = $funcType([ptrType, sliceType$1], [ptrType$5], false); funcType$1 = $funcType([ptrType, sliceType$1], [ptrType$5], false);
funcType$2 = $funcType([ptrType$1], [ptrType$5], false); funcType$2 = $funcType([ptrType$1], [ptrType$5], false);
funcType$3 = $funcType([$Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Bool], [ptrType$5], false); funcType$3 = $funcType([$Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Bool], [ptrType$5], false);
funcType$4 = $funcType([$Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Bool], [ptrType$5], false); funcType$4 = $funcType([$Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Int32, $Bool], [ptrType$5], false);
funcType$5 = $funcType([$Int32, sliceType$2, sliceType$3], [ptrType$5], false); funcType$5 = $funcType([$Int32, sliceType$2, sliceType$3], [ptrType$5], false);
funcType$6 = $funcType([$Int, $Int, $Int, $Int], [ptrType$5], false); funcType$6 = $funcType([$Int, $Int, $Int, $Int], [ptrType$5], false);
@ -6107,6 +6127,8 @@ $packages["jsexport"] = (function() {
mapType = $mapType($Int32, ptrType$10); mapType = $mapType($Int32, ptrType$10);
sliceType$7 = $sliceType(ptrType$6); sliceType$7 = $sliceType(ptrType$6);
funcType$16 = $funcType([ptrType$8, ptrType$9, ptrType$7, mapType, $Float64, $Float64, sliceType$7], [ptrType$5], false); funcType$16 = $funcType([ptrType$8, ptrType$9, ptrType$7, mapType, $Float64, $Float64, sliceType$7], [ptrType$5], false);
funcType$17 = $funcType([$Int32], [$Int32], false);
funcType$18 = $funcType([$Int32], [$Bool], false);
mapType$1 = $mapType($String, $emptyInterface); mapType$1 = $mapType($String, $emptyInterface);
NewInputFrameDownsync = function(inputFrameId, inputList, confirmedList) { NewInputFrameDownsync = function(inputFrameId, inputList, confirmedList) {
var {$24r, _r, confirmedList, inputFrameId, inputList, $s, $r, $c} = $restore(this, {inputFrameId, inputList, confirmedList}); var {$24r, _r, confirmedList, inputFrameId, inputList, $s, $r, $c} = $restore(this, {inputFrameId, inputList, confirmedList});
@ -6154,9 +6176,9 @@ $packages["jsexport"] = (function() {
return js.MakeWrapper(new battle.Barrier.ptr(boundary)); return js.MakeWrapper(new battle.Barrier.ptr(boundary));
}; };
$pkg.NewBarrierJs = NewBarrierJs; $pkg.NewBarrierJs = NewBarrierJs;
NewPlayerDownsyncJs = function(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius, inAir) { NewPlayerDownsyncJs = function(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, activeSkillId, activeSkillHit, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius, inAir) {
var battleState, characterState, colliderRadius, dirX, dirY, framesInChState, framesToRecover, hp, id, inAir, joinIndex, maxHp, speed, velX, velY, virtualGridX, virtualGridY; var activeSkillHit, activeSkillId, battleState, characterState, colliderRadius, dirX, dirY, framesInChState, framesToRecover, hp, id, inAir, joinIndex, maxHp, speed, velX, velY, virtualGridX, virtualGridY;
return js.MakeWrapper(new battle.PlayerDownsync.ptr(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, battleState, joinIndex, colliderRadius, false, 0, 0, framesToRecover, framesInChState, hp, maxHp, characterState, inAir, 0, 0)); return js.MakeWrapper(new battle.PlayerDownsync.ptr(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, battleState, joinIndex, colliderRadius, false, 0, 0, framesToRecover, framesInChState, hp, maxHp, characterState, inAir, activeSkillId, activeSkillHit));
}; };
$pkg.NewPlayerDownsyncJs = NewPlayerDownsyncJs; $pkg.NewPlayerDownsyncJs = NewPlayerDownsyncJs;
NewMeleeBulletJs = function(originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp) { NewMeleeBulletJs = function(originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp) {
@ -6250,7 +6272,7 @@ $packages["jsexport"] = (function() {
}; };
$pkg.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs = ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs; $pkg.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs = ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs;
main = function() { main = function() {
$global.gopkgs = $externalize($makeMap($String.keyFor, [{ k: "NewVec2DJs", v: new funcType(NewVec2DJs) }, { k: "NewPolygon2DJs", v: new funcType$1(NewPolygon2DJs) }, { k: "NewBarrierJs", v: new funcType$2(NewBarrierJs) }, { k: "NewPlayerDownsyncJs", v: new funcType$3(NewPlayerDownsyncJs) }, { k: "NewMeleeBulletJs", v: new funcType$4(NewMeleeBulletJs) }, { k: "NewRoomDownsyncFrameJs", v: new funcType$5(NewRoomDownsyncFrameJs) }, { k: "NewCollisionSpaceJs", v: new funcType$6(NewCollisionSpaceJs) }, { k: "NewInputFrameDownsync", v: new funcType$7(NewInputFrameDownsync) }, { k: "NewRingBufferJs", v: new funcType$8(NewRingBufferJs) }, { k: "GenerateRectColliderJs", v: new funcType$9(GenerateRectColliderJs) }, { k: "GenerateConvexPolygonColliderJs", v: new funcType$10(GenerateConvexPolygonColliderJs) }, { k: "GetCollisionSpaceObjsJs", v: new funcType$11(GetCollisionSpaceObjsJs) }, { k: "WorldToPolygonColliderBLPos", v: new funcType$12(battle.WorldToPolygonColliderBLPos) }, { k: "PolygonColliderBLToWorldPos", v: new funcType$12(battle.PolygonColliderBLToWorldPos) }, { k: "WorldToVirtualGridPos", v: new funcType$13(battle.WorldToVirtualGridPos) }, { k: "VirtualGridToWorldPos", v: new funcType$14(battle.VirtualGridToWorldPos) }, { k: "GetCharacterConfigsOrderedByJoinIndex", v: new funcType$15(GetCharacterConfigsOrderedByJoinIndex) }, { k: "ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs", v: new funcType$16(ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs) }]), mapType$1); $global.gopkgs = $externalize($makeMap($String.keyFor, [{ k: "NewVec2DJs", v: new funcType(NewVec2DJs) }, { k: "NewPolygon2DJs", v: new funcType$1(NewPolygon2DJs) }, { k: "NewBarrierJs", v: new funcType$2(NewBarrierJs) }, { k: "NewPlayerDownsyncJs", v: new funcType$3(NewPlayerDownsyncJs) }, { k: "NewMeleeBulletJs", v: new funcType$4(NewMeleeBulletJs) }, { k: "NewRoomDownsyncFrameJs", v: new funcType$5(NewRoomDownsyncFrameJs) }, { k: "NewCollisionSpaceJs", v: new funcType$6(NewCollisionSpaceJs) }, { k: "NewInputFrameDownsync", v: new funcType$7(NewInputFrameDownsync) }, { k: "NewRingBufferJs", v: new funcType$8(NewRingBufferJs) }, { k: "GenerateRectColliderJs", v: new funcType$9(GenerateRectColliderJs) }, { k: "GenerateConvexPolygonColliderJs", v: new funcType$10(GenerateConvexPolygonColliderJs) }, { k: "GetCollisionSpaceObjsJs", v: new funcType$11(GetCollisionSpaceObjsJs) }, { k: "WorldToPolygonColliderBLPos", v: new funcType$12(battle.WorldToPolygonColliderBLPos) }, { k: "PolygonColliderBLToWorldPos", v: new funcType$12(battle.PolygonColliderBLToWorldPos) }, { k: "WorldToVirtualGridPos", v: new funcType$13(battle.WorldToVirtualGridPos) }, { k: "VirtualGridToWorldPos", v: new funcType$14(battle.VirtualGridToWorldPos) }, { k: "GetCharacterConfigsOrderedByJoinIndex", v: new funcType$15(GetCharacterConfigsOrderedByJoinIndex) }, { k: "ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs", v: new funcType$16(ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs) }, { k: "ConvertToDelayedInputFrameId", v: new funcType$17(battle.ConvertToDelayedInputFrameId) }, { k: "ConvertToNoDelayInputFrameId", v: new funcType$17(battle.ConvertToNoDelayInputFrameId) }, { k: "ConvertToFirstUsedRenderFrameId", v: new funcType$17(battle.ConvertToFirstUsedRenderFrameId) }, { k: "ConvertToLastUsedRenderFrameId", v: new funcType$17(battle.ConvertToLastUsedRenderFrameId) }, { k: "ShouldGenerateInputFrameUpsync", v: new funcType$18(battle.ShouldGenerateInputFrameUpsync) }]), mapType$1);
}; };
$init = function() { $init = function() {
$pkg.$init = function() {}; $pkg.$init = function() {};

View File

@ -15,7 +15,7 @@ message PlayerDownsync {
int32 speed = 8; // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY" int32 speed = 8; // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
int32 battleState = 9; int32 battleState = 9;
int32 joinIndex = 10; int32 joinIndex = 10;
double colliderRadius = 11; int32 colliderRadius = 11;
bool removed = 12; bool removed = 12;
int32 score = 13; int32 score = 13;
int32 lastMoveGmtMillis = 14; int32 lastMoveGmtMillis = 14;
@ -25,6 +25,8 @@ message PlayerDownsync {
int32 characterState = 18; int32 characterState = 18;
bool inAir = 19; // by design a standalone field only inferred by the collision result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "inAir (prev -> curr)" bool inAir = 19; // by design a standalone field only inferred by the collision result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "inAir (prev -> curr)"
int32 framesInChState = 20; // number of frames elapsed in the current character state int32 framesInChState = 20; // number of frames elapsed in the current character state
int32 activeSkillId = 21;
int32 activeSkillHit = 22;
string name = 997; string name = 997;
string displayName = 998; string displayName = 998;
@ -85,33 +87,29 @@ message MeleeBullet {
// ALL lengths are in world coordinate // ALL lengths are in world coordinate
// for offender // for offender
int32 battleLocalId = 1; int32 originatedRenderFrameId = 1;
int32 startupFrames = 2; int32 offenderJoinIndex = 2;
int32 activeFrames = 3;
int32 recoveryFrames = 4;
int32 recoveryFramesOnBlock = 5;
int32 recoveryFramesOnHit = 6;
double hitboxOffset = 7;
int32 originatedRenderFrameId = 8;
// for defender int32 startupFrames = 3;
int32 hitStunFrames = 9; int32 cancellableStFrame = 4;
int32 blockStunFrames = 10; int32 cancellableEdFrame = 5;
double pushbackX = 11; int32 activeFrames = 6;
double pushbackY = 12;
int32 damage = 13; int32 hitStunFrames = 7;
int32 blockStunFrames = 8;
int32 pushbackVelX = 9;
int32 pushbackVelY = 10;
int32 damage = 11;
int32 offenderJoinIndex = 14; int32 selfLockVelX = 12;
int32 offenderPlayerId = 15; int32 selfLockVelY = 13;
double hitboxSizeX = 16; int32 hitboxOffsetX = 14;
double hitboxSizeY = 17; int32 hitboxOffsetY = 15;
int32 hitboxSizeX = 16;
int32 hitboxSizeY = 17;
double selfLockVelX = 18; bool blowUp = 18;
double selfLockVelY = 19;
int32 releaseTriggerType = 999; // 1: rising-edge, 2: falling-edge
} }
message BattleColliderInfo { message BattleColliderInfo {
@ -127,8 +125,8 @@ message BattleColliderInfo {
int64 rollbackEstimatedDtNanos = 9; int64 rollbackEstimatedDtNanos = 9;
int32 renderCacheSize = 10; int32 renderCacheSize = 10;
int32 spaceOffsetX = 11; double spaceOffsetX = 11;
int32 spaceOffsetY = 12; double spaceOffsetY = 12;
int32 collisionMinStep = 13; int32 collisionMinStep = 13;
bool frameDataLoggingEnabled = 999; bool frameDataLoggingEnabled = 999;
@ -141,5 +139,4 @@ message RoomDownsyncFrame {
repeated MeleeBullet meleeBullets = 4; // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise repeated MeleeBullet meleeBullets = 4; // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise
uint64 backendUnconfirmedMask = 5; // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync uint64 backendUnconfirmedMask = 5; // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
bool shouldForceResync = 6; bool shouldForceResync = 6;
map<int32, int32> playerOpPatternToSkillId = 7;
} }

View File

@ -461,7 +461,7 @@
"array": [ "array": [
0, 0,
0, 0,
210.4189861023336, 210.4441731196186,
0, 0,
0, 0,
0, 0,

View File

@ -107,23 +107,6 @@ cc.Class({
return (0 == inputFrameId % 10); return (0 == inputFrameId % 10);
}, },
_convertToInputFrameId(renderFrameId, inputDelayFrames) {
if (renderFrameId < inputDelayFrames) return 0;
return ((renderFrameId - inputDelayFrames) >> this.inputScaleFrames);
},
_convertToFirstUsedRenderFrameId(inputFrameId, inputDelayFrames) {
return ((inputFrameId << this.inputScaleFrames) + inputDelayFrames);
},
_convertToLastUsedRenderFrameId(inputFrameId, inputDelayFrames) {
return ((inputFrameId << this.inputScaleFrames) + inputDelayFrames + (1 << this.inputScaleFrames) - 1);
},
shouldGenerateInputFrameUpsync(renderFrameId) {
return ((renderFrameId & ((1 << this.inputScaleFrames) - 1)) == 0);
},
_allConfirmed(confirmedList) { _allConfirmed(confirmedList) {
return (confirmedList + 1) == (1 << this.playerRichInfoDict.size); return (confirmedList + 1) == (1 << this.playerRichInfoDict.size);
}, },
@ -586,7 +569,7 @@ cc.Class({
const jsPlayersArr = new Array().fill(null); const jsPlayersArr = new Array().fill(null);
for (let k in pbRdf.playersArr) { for (let k in pbRdf.playersArr) {
const pbPlayer = pbRdf.playersArr[k]; const pbPlayer = pbRdf.playersArr[k];
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir); const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.activeSkillId, pbPlayer.activeSkillHit, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir);
jsPlayersArr[k] = jsPlayer; jsPlayersArr[k] = jsPlayer;
} }
const jsMeleeBulletsArr = []; const jsMeleeBulletsArr = [];
@ -770,7 +753,7 @@ cc.Class({
} }
if (null == firstPredictedYetIncorrectInputFrameId) return; if (null == firstPredictedYetIncorrectInputFrameId) return;
const renderFrameId1 = self._convertToFirstUsedRenderFrameId(firstPredictedYetIncorrectInputFrameId, self.inputDelayFrames) - 1; const renderFrameId1 = gopkgs.ConvertToFirstUsedRenderFrameId(firstPredictedYetIncorrectInputFrameId) - 1;
if (renderFrameId1 >= self.chaserRenderFrameId) return; if (renderFrameId1 >= self.chaserRenderFrameId) return;
/* /*
@ -866,8 +849,8 @@ batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inpu
let st = performance.now(); let st = performance.now();
let prevSelfInput = null, let prevSelfInput = null,
currSelfInput = null; currSelfInput = null;
const noDelayInputFrameId = self._convertToInputFrameId(self.renderFrameId, 0); // It's important that "inputDelayFrames == 0" here const noDelayInputFrameId = gopkgs.ConvertToNoDelayInputFrameId(self.renderFrameId);
if (self.shouldGenerateInputFrameUpsync(self.renderFrameId)) { if (gopkgs.ShouldGenerateInputFrameUpsync(self.renderFrameId)) {
[prevSelfInput, currSelfInput] = self.getOrPrefabInputFrameUpsync(noDelayInputFrameId); [prevSelfInput, currSelfInput] = self.getOrPrefabInputFrameUpsync(noDelayInputFrameId);
} }
@ -902,7 +885,7 @@ batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inpu
*/ */
// [WARNING] Don't try to get "prevRdf(i.e. renderFrameId == latest-1)" by "self.recentRenderCache.getByFrameId(...)" here, as the cache might have been updated by asynchronous "onRoomDownsyncFrame(...)" calls! // [WARNING] Don't try to get "prevRdf(i.e. renderFrameId == latest-1)" by "self.recentRenderCache.getByFrameId(...)" here, as the cache might have been updated by asynchronous "onRoomDownsyncFrame(...)" calls!
if (self.othersForcedDownsyncRenderFrameDict.has(rdf.id)) { if (self.othersForcedDownsyncRenderFrameDict.has(rdf.id)) {
const delayedInputFrameId = self._convertToInputFrameId(rdf.id, 0); const delayedInputFrameId = gopkgs.ConvertToDelayedInputFrameId(rdf.id);
const othersForcedDownsyncRenderFrame = self.othersForcedDownsyncRenderFrameDict.get(rdf.id); const othersForcedDownsyncRenderFrame = self.othersForcedDownsyncRenderFrameDict.get(rdf.id);
if (self.lastAllConfirmedInputFrameId >= delayedInputFrameId && !self.equalRoomDownsyncFrames(othersForcedDownsyncRenderFrame, rdf)) { if (self.lastAllConfirmedInputFrameId >= delayedInputFrameId && !self.equalRoomDownsyncFrames(othersForcedDownsyncRenderFrame, rdf)) {
console.warn(`Mismatched render frame@rdf.id=${rdf.id} w/ inputFrameId=${delayedInputFrameId}: console.warn(`Mismatched render frame@rdf.id=${rdf.id} w/ inputFrameId=${delayedInputFrameId}:
@ -1071,14 +1054,14 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
if (null == currRdf) { if (null == currRdf) {
throw `Couldn't find renderFrame for i=${i} to rollback (are you using Firefox?), self.renderFrameId=${self.renderFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, might've been interruptted by onRoomDownsyncFrame`; throw `Couldn't find renderFrame for i=${i} to rollback (are you using Firefox?), self.renderFrameId=${self.renderFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, might've been interruptted by onRoomDownsyncFrame`;
} }
const j = self._convertToInputFrameId(i, self.inputDelayFrames); const j = gopkgs.ConvertToDelayedInputFrameId(i);
const delayedInputFrame = self.recentInputCache.GetByFrameId(j); // Don't make prediction here, the inputFrameDownsyncs in recentInputCache was already predicted while prefabbing const delayedInputFrame = self.recentInputCache.GetByFrameId(j); // Don't make prediction here, the inputFrameDownsyncs in recentInputCache was already predicted while prefabbing
if (null == delayedInputFrame) { if (null == delayedInputFrame) {
// Shouldn't happen! // Shouldn't happen!
throw `Failed to get cached delayedInputFrame for i=${i}, j=${j}, renderFrameId=${self.renderFrameId}, lastUpsyncInputFrameId=${self.lastUpsyncInputFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, chaserRenderFrameId=${self.chaserRenderFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`; throw `Failed to get cached delayedInputFrame for i=${i}, j=${j}, renderFrameId=${self.renderFrameId}, lastUpsyncInputFrameId=${self.lastUpsyncInputFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, chaserRenderFrameId=${self.chaserRenderFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`;
} }
const jPrev = self._convertToInputFrameId(i - 1, self.inputDelayFrames); const jPrev = gopkgs.ConvertToDelayedInputFrameId(i - 1);
if (self.frameDataLoggingEnabled) { if (self.frameDataLoggingEnabled) {
const actuallyUsedInputClone = delayedInputFrame.InputList.slice(); const actuallyUsedInputClone = delayedInputFrame.InputList.slice();
const inputFrameDownsyncClone = { const inputFrameDownsyncClone = {

View File

@ -28,8 +28,6 @@ cc.Class({
/** Init required prefab ended. */ /** Init required prefab ended. */
self.inputDelayFrames = 8;
self.inputScaleFrames = 2;
self.inputFrameUpsyncDelayTolerance = 2; self.inputFrameUpsyncDelayTolerance = 2;
self.collisionMinStep = 8; self.collisionMinStep = 8;
@ -188,8 +186,8 @@ cc.Class({
let st = performance.now(); let st = performance.now();
let prevSelfInput = null, let prevSelfInput = null,
currSelfInput = null; currSelfInput = null;
const noDelayInputFrameId = self._convertToInputFrameId(self.renderFrameId, 0); // It's important that "inputDelayFrames == 0" here const noDelayInputFrameId = gopkgs.ConvertToNoDelayInputFrameId(self.renderFrameId); // It's important that "inputDelayFrames == 0" here
if (self.shouldGenerateInputFrameUpsync(self.renderFrameId)) { if (gopkgs.ShouldGenerateInputFrameUpsync(self.renderFrameId)) {
const prevAndCurrInputs = self.getOrPrefabInputFrameUpsync(noDelayInputFrameId); const prevAndCurrInputs = self.getOrPrefabInputFrameUpsync(noDelayInputFrameId);
prevSelfInput = prevAndCurrInputs[0]; prevSelfInput = prevAndCurrInputs[0];
currSelfInput = prevAndCurrInputs[1]; currSelfInput = prevAndCurrInputs[1];

View File

@ -86,11 +86,36 @@ var invinsibleSet = map[int32]bool{
var nonAttackingSet = map[int32]bool{} var nonAttackingSet = map[int32]bool{}
func ConvertToInputFrameId(renderFrameId int32, inputDelayFrames int32, inputScaleFrames uint32) int32 { func ShouldPrefabInputFrameDownsync(prevRenderFrameId int32, renderFrameId int32) (bool, int32) {
if renderFrameId < inputDelayFrames { for i := prevRenderFrameId + 1; i <= renderFrameId; i++ {
if (0 <= i) && (0 == (i & ((1 << INPUT_SCALE_FRAMES) - 1))) {
return true, i
}
}
return false, -1
}
func ShouldGenerateInputFrameUpsync(renderFrameId int32) bool {
return ((renderFrameId & ((1 << INPUT_SCALE_FRAMES) - 1)) == 0)
}
func ConvertToDelayedInputFrameId(renderFrameId int32) int32 {
if renderFrameId < INPUT_DELAY_FRAMES {
return 0 return 0
} }
return ((renderFrameId - inputDelayFrames) >> inputScaleFrames) return ((renderFrameId - INPUT_DELAY_FRAMES) >> INPUT_SCALE_FRAMES)
}
func ConvertToNoDelayInputFrameId(renderFrameId int32) int32 {
return (renderFrameId >> INPUT_SCALE_FRAMES)
}
func ConvertToFirstUsedRenderFrameId(inputFrameId int32) int32 {
return ((inputFrameId << INPUT_SCALE_FRAMES) + INPUT_DELAY_FRAMES)
}
func ConvertToLastUsedRenderFrameId(inputFrameId int32) int32 {
return ((inputFrameId << INPUT_SCALE_FRAMES) + INPUT_DELAY_FRAMES + (1 << INPUT_SCALE_FRAMES) - 1)
} }
func decodeInput(encodedInput uint64) *InputFrameDecoded { func decodeInput(encodedInput uint64) *InputFrameDecoded {
@ -343,10 +368,10 @@ func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, play
return &ret return &ret
} }
func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, inputsBuffer *RingBuffer, inputDelayFrames int32, inputScaleFrames uint32) (int, bool, int32, int32) { func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, inputsBuffer *RingBuffer) (int, bool, int32, int32) {
// returns (patternId, jumpedOrNot, effectiveDx, effectiveDy) // returns (patternId, jumpedOrNot, effectiveDx, effectiveDy)
delayedInputFrameId := ConvertToInputFrameId(currRenderFrame.Id, inputDelayFrames, inputScaleFrames) delayedInputFrameId := ConvertToDelayedInputFrameId(currRenderFrame.Id)
delayedInputFrameIdForPrevRdf := ConvertToInputFrameId(currRenderFrame.Id-1, inputDelayFrames, inputScaleFrames) delayedInputFrameIdForPrevRdf := ConvertToDelayedInputFrameId(currRenderFrame.Id-1)
if 0 >= delayedInputFrameId { if 0 >= delayedInputFrameId {
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0 return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
@ -436,7 +461,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
jumpedOrNotList[i] = false jumpedOrNotList[i] = false
chConfig := chConfigsOrderedByJoinIndex[i] chConfig := chConfigsOrderedByJoinIndex[i]
thatPlayerInNextFrame := nextRenderFramePlayers[i] thatPlayerInNextFrame := nextRenderFramePlayers[i]
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer, INPUT_DELAY_FRAMES, INPUT_SCALE_FRAMES) patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer)
if jumpedOrNot { if jumpedOrNot {
thatPlayerInNextFrame.VelY = int32(chConfig.JumpingInitVelY) thatPlayerInNextFrame.VelY = int32(chConfig.JumpingInitVelY)

View File

@ -42,7 +42,7 @@ func NewBarrierJs(boundary *Polygon2D) *js.Object {
}) })
} }
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir bool) *js.Object { func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, activeSkillId, activeSkillHit, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir bool) *js.Object {
return js.MakeWrapper(&PlayerDownsync{ return js.MakeWrapper(&PlayerDownsync{
Id: id, Id: id,
VirtualGridX: virtualGridX, VirtualGridX: virtualGridX,
@ -53,13 +53,15 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
VelY: velY, VelY: velY,
FramesToRecover: framesToRecover, FramesToRecover: framesToRecover,
FramesInChState: framesInChState, FramesInChState: framesInChState,
ActiveSkillId: activeSkillId,
ActiveSkillHit: activeSkillHit,
Speed: speed, Speed: speed,
BattleState: battleState, BattleState: battleState,
CharacterState: characterState,
JoinIndex: joinIndex, JoinIndex: joinIndex,
ColliderRadius: colliderRadius,
Hp: hp, Hp: hp,
MaxHp: maxHp, MaxHp: maxHp,
CharacterState: characterState, ColliderRadius: colliderRadius,
InAir: inAir, InAir: inAir,
}) })
} }
@ -167,5 +169,10 @@ func main() {
"VirtualGridToWorldPos": VirtualGridToWorldPos, "VirtualGridToWorldPos": VirtualGridToWorldPos,
"GetCharacterConfigsOrderedByJoinIndex": GetCharacterConfigsOrderedByJoinIndex, "GetCharacterConfigsOrderedByJoinIndex": GetCharacterConfigsOrderedByJoinIndex,
"ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs": ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs, "ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs": ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs,
"ConvertToDelayedInputFrameId": ConvertToDelayedInputFrameId,
"ConvertToNoDelayInputFrameId": ConvertToNoDelayInputFrameId,
"ConvertToFirstUsedRenderFrameId": ConvertToFirstUsedRenderFrameId,
"ConvertToLastUsedRenderFrameId": ConvertToLastUsedRenderFrameId,
"ShouldGenerateInputFrameUpsync": ShouldGenerateInputFrameUpsync,
}) })
} }