Skip to content

Commit

Permalink
store/units: Added a HashPath on the Unit
Browse files Browse the repository at this point in the history
This Hash contains a hash of the Path so we can compare if we need to replace it
when updating the client with the new State or keep the old one. The reason is that
the client is normally faster that the server and so if we just replace the
server value to the client we see some flickering related to every time the
state is set from the sever as the units go back
  • Loading branch information
xescugc committed Dec 7, 2023
1 parent 3d19224 commit 4f4c8f5
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 14 deletions.
7 changes: 3 additions & 4 deletions action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ func NewMoveUnit() *Action {
}
}

type RemoveUnitPayload struct {
UnitID string
}
type RemoveUnitPayload struct{ UnitID string }

func NewRemoveUnit(uid string) *Action {
return &Action{
Expand Down Expand Up @@ -423,7 +421,8 @@ type UpdateStateUnitPayload struct {

Health float64

Path []utils.Step
Path []utils.Step
HashPath string
}

// TODO: or make the action.Action separated or make the store.Player separated
Expand Down
Binary file modified server/assets/wasm/maze-wars.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions store/reduce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func TestSummonUnit(t *testing.T) {

// We need to set the path after the X, Y are set
eu.Path = s.Units.Astar(s.Map, clid, eu.MovingObject, nil)
eu.HashPath = utils.HashSteps(eu.Path)

// AS the Unit is created we remove it from the gold
// and add more income
Expand Down
32 changes: 22 additions & 10 deletions store/units.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ type Unit struct {

Health float64

Path []utils.Step
Path []utils.Step
HashPath string
}

func (u *Unit) Faceset() image.Image {
Expand Down Expand Up @@ -122,6 +123,7 @@ func (us *Units) Reduce(state, a interface{}) interface{} {
}
}
u.Path = us.Astar(us.store.Map, u.CurrentLineID, u.MovingObject, tws)
u.HashPath = utils.HashSteps(u.Path)
ustate.Units[uid.String()] = u
case action.MoveUnit:
us.mxUnits.Lock()
Expand Down Expand Up @@ -203,6 +205,15 @@ func (us *Units) Reduce(state, a interface{}) interface{} {
if u.Health <= 0 {
u.Health = 0
}
case action.RemovePlayer:
us.mxUnits.Lock()
defer us.mxUnits.Unlock()

for id, u := range ustate.Units {
if u.PlayerID == act.RemovePlayer.ID {
delete(ustate.Units, id)
}
}
case action.UpdateState:
us.mxUnits.Lock()
defer us.mxUnits.Unlock()
Expand All @@ -214,20 +225,21 @@ func (us *Units) Reduce(state, a interface{}) interface{} {
for id, u := range act.UpdateState.Units.Units {
delete(uids, id)
nu := Unit(*u)
ou, ok := ustate.Units[id]

if ok {
if ou.HashPath == nu.HashPath {
nu.Path = ou.Path
}
}

// If the path is the same we set it. This cannot be done directly
// as the Unit on the client may be faster than the Unit on the server
ustate.Units[id] = &nu
}
for id := range uids {
delete(ustate.Units, id)
}
case action.RemovePlayer:
us.mxUnits.Lock()
defer us.mxUnits.Unlock()

for id, u := range ustate.Units {
if u.PlayerID == act.RemovePlayer.ID {
delete(ustate.Units, id)
}
}
}
return ustate
}
1 change: 1 addition & 0 deletions store/units_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ func TestUnits_List(t *testing.T) {
}
// We calculate the path also
eunits[0].Path = us.Astar(st.Map, clid, eunits[0].MovingObject, nil)
eunits[0].HashPath = utils.HashSteps(eunits[0].Path)
assert.Equal(t, eunits, units)
}
15 changes: 15 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package utils

import (
"bytes"
"crypto/sha256"
"fmt"
"math"

"github.com/hajimehoshi/ebiten/v2"
Expand Down Expand Up @@ -61,6 +64,10 @@ type Step struct {
Facing ebiten.Key
}

func (s Step) String() string {
return fmt.Sprintf("X:%f, Y:%f, W:%f, H:%f, F:%s", s.X, s.Y, s.W, s.H, s.Facing.String())
}

// NeighborSteps returns all the possible steps around the o
func (o Object) NeighborSteps() []Step {
return []Step{
Expand Down Expand Up @@ -108,3 +115,11 @@ type MovingObject struct {
Facing ebiten.Key
MovingCount int
}

func HashSteps(ss []Step) string {
var buffer bytes.Buffer
for _, s := range ss {
buffer.WriteString(s.String())
}
return fmt.Sprintf("%x", (sha256.Sum256([]byte(buffer.String()))))
}

0 comments on commit 4f4c8f5

Please sign in to comment.