From 0a58e0453aafa516bf8e338deacceda7a1e3be1e Mon Sep 17 00:00:00 2001 From: bdnugget Date: Mon, 13 Jan 2025 10:00:23 +0100 Subject: [PATCH] Fix tickrate and action queue stuff --- actions.proto | 32 -------------------- goonserver | 2 +- main.go | 4 +-- network.go | 82 +++++++++++++++++++++++++-------------------------- player.go | 2 +- types.go | 2 ++ 6 files changed, 47 insertions(+), 77 deletions(-) delete mode 100644 actions.proto diff --git a/actions.proto b/actions.proto deleted file mode 100644 index b059579..0000000 --- a/actions.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; -package actions; - -option go_package = "gitea.boner.be/bdnugget/goonserver/actions"; - -message Action { - enum ActionType { - MOVE = 0; - } - ActionType type = 1; - int32 x = 2; - int32 y = 3; - int32 player_id = 4; -} - -message ActionBatch { - int32 player_id = 1; - repeated Action actions = 2; - int64 tick = 3; -} - -message PlayerState { - int32 player_id = 1; - int32 x = 2; - int32 y = 3; -} - -message ServerMessage { - int32 player_id = 1; - repeated PlayerState players = 2; - int64 current_tick = 3; -} \ No newline at end of file diff --git a/goonserver b/goonserver index 8290131..a459e8b 160000 --- a/goonserver +++ b/goonserver @@ -1 +1 @@ -Subproject commit 8290131998485ef62ccef43ddc7eb807c244ff67 +Subproject commit a459e8b4a5cfa02f0ee588596dba5ce26afac39f diff --git a/main.go b/main.go index 82a9c6d..c834b09 100644 --- a/main.go +++ b/main.go @@ -89,13 +89,13 @@ func main() { rl.ClearBackground(rl.RayWhite) rl.BeginMode3D(camera) DrawMap() - DrawPlayer(player, player.Model) + DrawPlayer(&player, player.Model) for id, other := range otherPlayers { if len(other.TargetPath) > 0 { other.MoveTowards(other.TargetPath[0], deltaTime) } - DrawPlayer(*other, models[int(id)%len(models)].Model) + DrawPlayer(other, models[int(id)%len(models)].Model) } rl.EndMode3D() diff --git a/network.go b/network.go index 3bad96a..2ed166b 100644 --- a/network.go +++ b/network.go @@ -41,26 +41,19 @@ func ConnectToServer() (net.Conn, int32, error) { } func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, otherPlayers map[int32]*Player) { - // Ticker for sending actions aligned with server ticks - ticker := time.NewTicker(ServerTickRate) - defer ticker.Stop() + buf := make([]byte, 4096) + + // Ticker for sending actions + actionTicker := time.NewTicker(ClientTickRate) + defer actionTicker.Stop() - // Goroutine to handle sending player's actions to the server go func() { - for range ticker.C { + for range actionTicker.C { + player.Lock() if len(player.ActionQueue) > 0 { // Bundle all actions that occurred during this tick - actions := make([]*pb.Action, 0, len(player.ActionQueue)) - - for _, actionData := range player.ActionQueue { - action := &pb.Action{ - PlayerId: playerID, - Type: pb.Action_MOVE, - X: int32(actionData.X), - Y: int32(actionData.Y), - } - actions = append(actions, action) - } + actions := make([]*pb.Action, len(player.ActionQueue)) + copy(actions, player.ActionQueue) // Copy to avoid holding lock while sending // Create a batch message batch := &pb.ActionBatch{ @@ -69,29 +62,29 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, ot Tick: player.CurrentTick, } - // Serialize the batch + // Clear the action queue after copying + player.ActionQueue = player.ActionQueue[:0] + player.Unlock() + + // Serialize and send the batch data, err := proto.Marshal(batch) if err != nil { log.Printf("Failed to marshal action batch: %v", err) continue } - // Send batch to server - _, err = conn.Write(data) - if err != nil { + if _, err = conn.Write(data); err != nil { log.Printf("Failed to send actions to server: %v", err) return } - - // Clear the action queue after sending - player.ActionQueue = player.ActionQueue[:0] + } else { + player.Unlock() } } }() // Main loop to handle receiving updates from the server for { - buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { log.Printf("Failed to read from server: %v", err) @@ -104,27 +97,34 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, ot continue } - // Check for tick synchronization - tickDiff := serverMessage.CurrentTick - player.CurrentTick - if tickDiff > MaxTickDesync { - log.Printf("Client too far behind (tick diff: %d), forcing resync", tickDiff) - player.ForceResync(serverMessage.Players[playerID]) - } - - // Update player's current tick + // Update game state with received data + player.Lock() player.CurrentTick = serverMessage.CurrentTick - // Update other players' states - for _, state := range serverMessage.Players { - if state.PlayerId != playerID { - if otherPlayer, exists := otherPlayers[state.PlayerId]; exists { - // Calculate interpolation based on server tick - otherPlayer.UpdatePosition(state, ServerTickRate) - } else { - // Initialize new player - otherPlayers[state.PlayerId] = NewPlayer(state) + // Check for desync + tickDiff := serverMessage.CurrentTick - player.CurrentTick + if tickDiff > MaxTickDesync { + // Force resync if we're too far behind + for _, state := range serverMessage.Players { + if state.PlayerId == playerID { + player.ForceResync(state) + break } } } + player.Unlock() + + // Update other players + for _, state := range serverMessage.Players { + if state.PlayerId == playerID { + continue // Skip self + } + + if otherPlayer, exists := otherPlayers[state.PlayerId]; exists { + otherPlayer.UpdatePosition(state, ServerTickRate) + } else { + otherPlayers[state.PlayerId] = NewPlayer(state) + } + } } } diff --git a/player.go b/player.go index 7ccf945..ee1f881 100644 --- a/player.go +++ b/player.go @@ -7,7 +7,7 @@ import ( rl "github.com/gen2brain/raylib-go/raylib" ) -func DrawPlayer(player Player, model rl.Model) { +func DrawPlayer(player *Player, model rl.Model) { // Draw the player based on its actual position (PosActual) and current tile height playerPos := rl.Vector3{ X: player.PosActual.X, diff --git a/types.go b/types.go index 27ff261..d039417 100644 --- a/types.go +++ b/types.go @@ -4,6 +4,7 @@ import ( pb "gitea.boner.be/bdnugget/goonserver/actions" rl "github.com/gen2brain/raylib-go/raylib" + "sync" time "time" ) @@ -14,6 +15,7 @@ type Tile struct { } type Player struct { + sync.Mutex PosActual rl.Vector3 PosTile Tile TargetPath []Tile