Fix tickrate and action queue stuff
This commit is contained in:
parent
8d70129c73
commit
0a58e0453a
@ -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;
|
|
||||||
}
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 8290131998485ef62ccef43ddc7eb807c244ff67
|
Subproject commit a459e8b4a5cfa02f0ee588596dba5ce26afac39f
|
4
main.go
4
main.go
@ -89,13 +89,13 @@ func main() {
|
|||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
rl.BeginMode3D(camera)
|
rl.BeginMode3D(camera)
|
||||||
DrawMap()
|
DrawMap()
|
||||||
DrawPlayer(player, player.Model)
|
DrawPlayer(&player, player.Model)
|
||||||
|
|
||||||
for id, other := range otherPlayers {
|
for id, other := range otherPlayers {
|
||||||
if len(other.TargetPath) > 0 {
|
if len(other.TargetPath) > 0 {
|
||||||
other.MoveTowards(other.TargetPath[0], deltaTime)
|
other.MoveTowards(other.TargetPath[0], deltaTime)
|
||||||
}
|
}
|
||||||
DrawPlayer(*other, models[int(id)%len(models)].Model)
|
DrawPlayer(other, models[int(id)%len(models)].Model)
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
74
network.go
74
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) {
|
func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, otherPlayers map[int32]*Player) {
|
||||||
// Ticker for sending actions aligned with server ticks
|
buf := make([]byte, 4096)
|
||||||
ticker := time.NewTicker(ServerTickRate)
|
|
||||||
defer ticker.Stop()
|
// Ticker for sending actions
|
||||||
|
actionTicker := time.NewTicker(ClientTickRate)
|
||||||
|
defer actionTicker.Stop()
|
||||||
|
|
||||||
// Goroutine to handle sending player's actions to the server
|
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range actionTicker.C {
|
||||||
|
player.Lock()
|
||||||
if len(player.ActionQueue) > 0 {
|
if len(player.ActionQueue) > 0 {
|
||||||
// Bundle all actions that occurred during this tick
|
// Bundle all actions that occurred during this tick
|
||||||
actions := make([]*pb.Action, 0, len(player.ActionQueue))
|
actions := make([]*pb.Action, len(player.ActionQueue))
|
||||||
|
copy(actions, player.ActionQueue) // Copy to avoid holding lock while sending
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a batch message
|
// Create a batch message
|
||||||
batch := &pb.ActionBatch{
|
batch := &pb.ActionBatch{
|
||||||
@ -69,29 +62,29 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, ot
|
|||||||
Tick: player.CurrentTick,
|
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)
|
data, err := proto.Marshal(batch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to marshal action batch: %v", err)
|
log.Printf("Failed to marshal action batch: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send batch to server
|
if _, err = conn.Write(data); err != nil {
|
||||||
_, err = conn.Write(data)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed to send actions to server: %v", err)
|
log.Printf("Failed to send actions to server: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Clear the action queue after sending
|
player.Unlock()
|
||||||
player.ActionQueue = player.ActionQueue[:0]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Main loop to handle receiving updates from the server
|
// Main loop to handle receiving updates from the server
|
||||||
for {
|
for {
|
||||||
buf := make([]byte, 4096)
|
|
||||||
n, err := conn.Read(buf)
|
n, err := conn.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to read from server: %v", err)
|
log.Printf("Failed to read from server: %v", err)
|
||||||
@ -104,27 +97,34 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, ot
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for tick synchronization
|
// Update game state with received data
|
||||||
tickDiff := serverMessage.CurrentTick - player.CurrentTick
|
player.Lock()
|
||||||
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
|
|
||||||
player.CurrentTick = serverMessage.CurrentTick
|
player.CurrentTick = serverMessage.CurrentTick
|
||||||
|
|
||||||
// Update other players' states
|
// Check for desync
|
||||||
|
tickDiff := serverMessage.CurrentTick - player.CurrentTick
|
||||||
|
if tickDiff > MaxTickDesync {
|
||||||
|
// Force resync if we're too far behind
|
||||||
for _, state := range serverMessage.Players {
|
for _, state := range serverMessage.Players {
|
||||||
if state.PlayerId != playerID {
|
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 {
|
if otherPlayer, exists := otherPlayers[state.PlayerId]; exists {
|
||||||
// Calculate interpolation based on server tick
|
|
||||||
otherPlayer.UpdatePosition(state, ServerTickRate)
|
otherPlayer.UpdatePosition(state, ServerTickRate)
|
||||||
} else {
|
} else {
|
||||||
// Initialize new player
|
|
||||||
otherPlayers[state.PlayerId] = NewPlayer(state)
|
otherPlayers[state.PlayerId] = NewPlayer(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
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
|
// Draw the player based on its actual position (PosActual) and current tile height
|
||||||
playerPos := rl.Vector3{
|
playerPos := rl.Vector3{
|
||||||
X: player.PosActual.X,
|
X: player.PosActual.X,
|
||||||
|
2
types.go
2
types.go
@ -4,6 +4,7 @@ import (
|
|||||||
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
|
|
||||||
|
"sync"
|
||||||
time "time"
|
time "time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ type Tile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Player struct {
|
type Player struct {
|
||||||
|
sync.Mutex
|
||||||
PosActual rl.Vector3
|
PosActual rl.Vector3
|
||||||
PosTile Tile
|
PosTile Tile
|
||||||
TargetPath []Tile
|
TargetPath []Tile
|
||||||
|
Loading…
x
Reference in New Issue
Block a user