Skip to content

Commit

Permalink
store/lines: Made the TPS check if there is a time in it
Browse files Browse the repository at this point in the history
If so It'll compare the updated times to that time and check how much the units have to move.

This way we remove the TPS every 1/60s no the server side and we only calculate that once it's
needed
  • Loading branch information
xescugc committed Mar 17, 2024
1 parent 5284cf9 commit a9e5cd7
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 32 deletions.
17 changes: 14 additions & 3 deletions action/action.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package action

import (
"time"

"github.com/xescugc/maze-wars/utils"
"github.com/xescugc/maze-wars/utils/graph"
"nhooyr.io/websocket"
Expand All @@ -27,6 +29,7 @@ type Action struct {
StartGame *StartGamePayload `json:"start_game,omitempty"`
GoHome *GoHomePayload `json:"go_home,omitempty"`
ToggleStats *ToggleStatsPayload `json:"toggle_stats,omitempty"`
TPS *TPSPayload `json:"tps,omitempty"`

OpenTowerMenu *OpenTowerMenuPayload `json:"open_tower_menu,omitempty"`
CloseTowerMenu *CloseTowerMenuPayload `json:"close_tower_menu,omitempty"`
Expand Down Expand Up @@ -79,9 +82,16 @@ func NewSummonUnit(t, pid string, plid, clid int) *Action {
}
}

func NewTPS() *Action {
type TPSPayload struct {
Time time.Time
}

func NewTPS(t time.Time) *Action {
return &Action{
Type: TPS,
TPS: &TPSPayload{
Time: t,
},
}
}

Expand Down Expand Up @@ -509,8 +519,9 @@ type SyncStateUnitPayload struct {

Health float64

Path []graph.Step
HashPath string
Path []graph.Step
HashPath string
CreatedAt time.Time
}

// TODO: or make the action.Action separated or make the store.Player separated
Expand Down
2 changes: 1 addition & 1 deletion client/game/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (ac *ActionDispatcher) SummonUnit(unit, pid string, plid, clid int) {

// TPS is the call for every TPS event
func (ac *ActionDispatcher) TPS() {
tpsa := action.NewTPS()
tpsa := action.NewTPS(time.Time{})
ac.Dispatch(tpsa)
}

Expand Down
6 changes: 1 addition & 5 deletions server/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,6 @@ func (ac *ActionDispatcher) WaitRoomCountdownTick() {
ac.startGame()
}

func (ac *ActionDispatcher) TPS(rooms *RoomsStore) {
tpsa := action.NewTPS()
ac.Dispatch(tpsa)
}

func (ac *ActionDispatcher) UserSignUp(un string) {
ac.Dispatch(action.NewUserSignUp(un))
}
Expand All @@ -103,6 +98,7 @@ func (ac *ActionDispatcher) UserSignOut(un string) {
}

func (ac *ActionDispatcher) SyncState(rooms *RoomsStore) {
ac.Dispatch(action.NewTPS(time.Now()))
rstate := rooms.GetState().(RoomsState)
for _, r := range rstate.Rooms {
if r.Name == rstate.CurrentWaitingRoom {
Expand Down
Binary file modified server/assets/wasm/maze-wars.wasm
Binary file not shown.
4 changes: 0 additions & 4 deletions server/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ func startLoop(ctx context.Context, s *Store) {
stateTicker := time.NewTicker(time.Second / 4)
// The default TPS on of Ebiten client if 60 so to
// emulate that we trigger the move action every TPS
tpsTicker := time.NewTicker(time.Second / 60)
usersTicker := time.NewTicker(5 * time.Second)
for {
select {
Expand All @@ -190,14 +189,11 @@ func startLoop(ctx context.Context, s *Store) {
actionDispatcher.IncomeTick(s.Rooms)
actionDispatcher.WaitRoomCountdownTick()
actionDispatcher.SyncWaitingRoom(s.Rooms)
case <-tpsTicker.C:
actionDispatcher.TPS(s.Rooms)
case <-usersTicker.C:
actionDispatcher.SyncUsers(s.Users)
case <-ctx.Done():
stateTicker.Stop()
secondTicker.Stop()
tpsTicker.Stop()
usersTicker.Stop()
goto FINISH
}
Expand Down
91 changes: 72 additions & 19 deletions store/lines.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package store

import (
"sync"
"time"

"github.com/gofrs/uuid"
"github.com/xescugc/go-flux"
Expand All @@ -12,7 +13,13 @@ import (
"github.com/xescugc/maze-wars/utils/graph"
)

const atScale = true
const (
atScale = true
)

var (
tpsMS = (time.Second / 60).Milliseconds()
)

type Lines struct {
*flux.ReduceStore
Expand All @@ -31,6 +38,17 @@ type Line struct {
Units map[string]*Unit

Graph *graph.Graph

// UpdatedAt is the last time
// something was updated on this Line.
// Towers added, Units added or
// when the Units position was updated
// the last time.
// Used for the SyncState to know how much
// time has passed since the last update
// and move the Units accordingly
// (60 moves per second pass)
UpdatedAt time.Time
}

type Tower struct {
Expand Down Expand Up @@ -59,6 +77,12 @@ type Unit struct {

Path []graph.Step
HashPath string

// CreatedAt has the time of creation so
// on the next SyncState will be moved just
// the diff amount and then it'll be set to 'nil'
// so we know it's on sync
CreatedAt time.Time
}

func (u *Unit) FacesetKey() string { return unit.Units[u.Type].FacesetKey() }
Expand Down Expand Up @@ -168,19 +192,13 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} {

l.Towers[tw.ID] = tw

for _, u := range l.Units {
u.Path = l.Graph.AStar(u.X, u.Y, u.Facing, l.Graph.DeathNode.X, l.Graph.DeathNode.Y, atScale)
u.HashPath = graph.HashSteps(u.Path)
}
recalculateLineUnitSteps(l)
case action.RemoveTower:
// TODO: Add the LineID
for _, l := range lstate.Lines {
if ok := l.Graph.RemoveTower(act.RemoveTower.TowerID); ok {
delete(l.Towers, act.RemoveTower.TowerID)
for _, u := range l.Units {
u.Path = l.Graph.AStar(u.X, u.Y, u.Facing, l.Graph.DeathNode.X, l.Graph.DeathNode.Y, atScale)
u.HashPath = graph.HashSteps(u.Path)
}
recalculateLineUnitSteps(l)
}
}
case action.TowerAttack:
Expand Down Expand Up @@ -225,6 +243,7 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} {
PlayerLineID: act.SummonUnit.PlayerLineID,
CurrentLineID: act.SummonUnit.CurrentLineID,
Health: unit.Units[act.SummonUnit.Type].Health,
CreatedAt: time.Now(),
}

u.Path = l.Graph.AStar(u.X, u.Y, u.Facing, l.Graph.DeathNode.X, l.Graph.DeathNode.Y, atScale)
Expand Down Expand Up @@ -252,6 +271,7 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} {
u.Path = nl.Graph.AStar(u.X, u.Y, u.Facing, nl.Graph.DeathNode.X, nl.Graph.DeathNode.Y, atScale)
u.HashPath = graph.HashSteps(u.Path)

u.CreatedAt = time.Now()
nl.Units[u.ID] = u

break
Expand All @@ -273,16 +293,7 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} {
defer ls.mxLines.Unlock()

for _, l := range lstate.Lines {
for _, u := range l.Units {
if len(u.Path) > 0 {
nextStep := u.Path[0]
u.Path = u.Path[1:]
u.MovingCount += 1
u.Y = nextStep.Y
u.X = nextStep.X
u.Facing = nextStep.Facing
}
}
moveLineUnitsTo(l, act.TPS.Time)
}
case action.RemovePlayer:
ls.mxLines.Lock()
Expand Down Expand Up @@ -365,6 +376,48 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} {
return lstate
}

func recalculateLineUnitSteps(l *Line) {
t := time.Now()
moveLineUnitsTo(l, t)

for _, u := range l.Units {
u.Path = l.Graph.AStar(u.X, u.Y, u.Facing, l.Graph.DeathNode.X, l.Graph.DeathNode.Y, atScale)
u.HashPath = graph.HashSteps(u.Path)
}
}

func moveLineUnitsTo(l *Line, t time.Time) {
lmoves := 1
if !t.IsZero() && !l.UpdatedAt.IsZero() {
lmoves = int(t.Sub(l.UpdatedAt).Milliseconds() / tpsMS)
}
for _, u := range l.Units {
if len(u.Path) > 0 {
umoves := lmoves
if !t.IsZero() && !u.CreatedAt.IsZero() {
umoves = int(t.Sub(u.CreatedAt).Milliseconds() / tpsMS)
// This way we mean it's up to date now
u.CreatedAt = time.Time{}
}
// If we have less moves remaining that the expected amount
// we just move to the last position
if len(u.Path) < umoves {
umoves = len(u.Path) - 1
}
if umoves == 0 {
continue
}
nextStep := u.Path[umoves-1]
u.Path = u.Path[umoves:]
u.MovingCount += umoves
u.Y = nextStep.Y
u.X = nextStep.X
u.Facing = nextStep.Facing
}
}
l.UpdatedAt = t
}

func (ls *Lines) newLine(lid int) *Line {
x, y := ls.store.Map.GetHomeCoordinates(lid)
g, err := graph.New(x+16, y+16, 16, 84, 16, 7, 74, 3)
Expand Down

0 comments on commit a9e5cd7

Please sign in to comment.