Protobuf changes
This commit is contained in:
parent
4f36c2ee1f
commit
4012a2ed92
32
actions.proto
Normal file
32
actions.proto
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
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;
|
||||||
|
}
|
@ -9,4 +9,13 @@ const (
|
|||||||
TileHeight = 2.0
|
TileHeight = 2.0
|
||||||
TickRate = 600 * time.Millisecond // Server tick rate (600ms)
|
TickRate = 600 * time.Millisecond // Server tick rate (600ms)
|
||||||
serverAddr = "localhost:6969"
|
serverAddr = "localhost:6969"
|
||||||
|
|
||||||
|
// RuneScape-style tick rate (600ms)
|
||||||
|
ServerTickRate = 600 * time.Millisecond
|
||||||
|
|
||||||
|
// Client might run at a higher tick rate for smooth rendering
|
||||||
|
ClientTickRate = 50 * time.Millisecond
|
||||||
|
|
||||||
|
// Maximum number of ticks we can get behind before forcing a resync
|
||||||
|
MaxTickDesync = 5
|
||||||
)
|
)
|
||||||
|
4
go.mod
4
go.mod
@ -1,4 +1,4 @@
|
|||||||
module goonscape
|
module gitea.boner.be/bdnugget/goonscape
|
||||||
|
|
||||||
go 1.23.0
|
go 1.23.0
|
||||||
|
|
||||||
@ -13,3 +13,5 @@ require (
|
|||||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
|
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
|
||||||
golang.org/x/sys v0.26.0 // indirect
|
golang.org/x/sys v0.26.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace gitea.boner.be/bdnugget/goonserver => ./goonserver
|
||||||
|
2
go.sum
2
go.sum
@ -1,5 +1,3 @@
|
|||||||
gitea.boner.be/bdnugget/goonserver v0.0.0-20241011195320-f16e8647dc6b h1:hdhCZH0YGqCsnSl6ru+8I7rxvCyOj5pCtf92urwyruA=
|
|
||||||
gitea.boner.be/bdnugget/goonserver v0.0.0-20241011195320-f16e8647dc6b/go.mod h1:inR1bKrr/vcTba+G1KzmmY6vssMq9oGNOk836VwPa4c=
|
|
||||||
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
|
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
|
||||||
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20240930075631-c66f9e2942fe h1:mInjrbJkUglTM7tBmXG+epnPCE744aj15J7vjJwM4gs=
|
github.com/gen2brain/raylib-go/raylib v0.0.0-20240930075631-c66f9e2942fe h1:mInjrbJkUglTM7tBmXG+epnPCE744aj15J7vjJwM4gs=
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 1d6d3ab2eadf488d6ec0e5ba85005b3e57e372ea
|
Subproject commit f91f72c05d779b99c65b86abdfda205ef8e8f7c0
|
8
input.go
8
input.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,7 +41,12 @@ func HandleInput(player *Player, camera *rl.Camera) {
|
|||||||
// Exclude the first tile (current position)
|
// Exclude the first tile (current position)
|
||||||
if len(path) > 1 {
|
if len(path) > 1 {
|
||||||
player.TargetPath = path[1:]
|
player.TargetPath = path[1:]
|
||||||
player.ActionQueue = append(player.ActionQueue, Action{Type: MoveAction, X: clickedTile.X, Y: clickedTile.Y})
|
player.ActionQueue = append(player.ActionQueue, &pb.Action{
|
||||||
|
Type: pb.Action_MOVE,
|
||||||
|
X: int32(clickedTile.X),
|
||||||
|
Y: int32(clickedTile.Y),
|
||||||
|
PlayerId: player.ID,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
77
network.go
77
network.go
@ -6,7 +6,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,39 +41,51 @@ 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
|
||||||
|
ticker := time.NewTicker(ServerTickRate)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
// Goroutine to handle sending player's actions to the server
|
// Goroutine to handle sending player's actions to the server
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for range ticker.C {
|
||||||
if len(player.ActionQueue) > 0 {
|
if len(player.ActionQueue) > 0 {
|
||||||
// Process the first action in the queue
|
// Bundle all actions that occurred during this tick
|
||||||
actionData := player.ActionQueue[0]
|
actions := make([]*pb.Action, 0, len(player.ActionQueue))
|
||||||
action := &pb.Action{
|
|
||||||
PlayerId: playerID,
|
for _, actionData := range player.ActionQueue {
|
||||||
Type: pb.Action_MOVE,
|
action := &pb.Action{
|
||||||
X: int32(actionData.X),
|
PlayerId: playerID,
|
||||||
Y: int32(actionData.Y),
|
Type: pb.Action_MOVE,
|
||||||
|
X: int32(actionData.X),
|
||||||
|
Y: int32(actionData.Y),
|
||||||
|
}
|
||||||
|
actions = append(actions, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize the action
|
// Create a batch message
|
||||||
data, err := proto.Marshal(action)
|
batch := &pb.ActionBatch{
|
||||||
|
PlayerId: playerID,
|
||||||
|
Actions: actions,
|
||||||
|
Tick: player.CurrentTick,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize the batch
|
||||||
|
data, err := proto.Marshal(batch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to marshal action: %v", err)
|
log.Printf("Failed to marshal action batch: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send action to server
|
// Send batch to server
|
||||||
_, err = conn.Write(data)
|
_, err = conn.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to send action to server: %v", err)
|
log.Printf("Failed to send actions to server: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the action from the queue once it's sent
|
// Clear the action queue after sending
|
||||||
player.ActionQueue = player.ActionQueue[1:]
|
player.ActionQueue = player.ActionQueue[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a delay to match the server's tick rate
|
|
||||||
time.Sleep(TickRate)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -93,27 +104,25 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *Player, ot
|
|||||||
continue
|
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
|
||||||
|
player.CurrentTick = serverMessage.CurrentTick
|
||||||
|
|
||||||
// Update other players' states
|
// Update other players' states
|
||||||
for _, state := range serverMessage.Players {
|
for _, state := range serverMessage.Players {
|
||||||
if state.PlayerId != playerID {
|
if state.PlayerId != playerID {
|
||||||
if otherPlayer, exists := otherPlayers[state.PlayerId]; exists {
|
if otherPlayer, exists := otherPlayers[state.PlayerId]; exists {
|
||||||
// Instead of directly setting position, set up path for smooth movement
|
// Calculate interpolation based on server tick
|
||||||
targetTile := Tile{X: int(state.X), Y: int(state.Y)}
|
otherPlayer.UpdatePosition(state, ServerTickRate)
|
||||||
if otherPlayer.PosTile != targetTile {
|
|
||||||
otherPlayer.TargetPath = []Tile{targetTile}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Initialize new player
|
// Initialize new player
|
||||||
otherPlayers[state.PlayerId] = &Player{
|
otherPlayers[state.PlayerId] = NewPlayer(state)
|
||||||
PosTile: Tile{X: int(state.X), Y: int(state.Y)},
|
|
||||||
PosActual: rl.Vector3{
|
|
||||||
X: float32(state.X * TileSize),
|
|
||||||
Y: float32(state.Y * TileHeight),
|
|
||||||
Z: float32(state.Y * TileSize),
|
|
||||||
},
|
|
||||||
ID: state.PlayerId,
|
|
||||||
Speed: 50.0, // Make sure to set the speed for smooth movement
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
player.go
38
player.go
@ -1,6 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -61,3 +64,38 @@ func (player *Player) MoveTowards(target Tile, deltaTime float32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) UpdatePosition(state *pb.PlayerState, tickRate time.Duration) {
|
||||||
|
targetTile := Tile{X: int(state.X), Y: int(state.Y)}
|
||||||
|
if p.PosTile != targetTile {
|
||||||
|
p.PosTile = targetTile
|
||||||
|
p.LastUpdateTime = time.Now()
|
||||||
|
p.InterpolationProgress = 0
|
||||||
|
p.TargetPath = []Tile{targetTile}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) ForceResync(state *pb.PlayerState) {
|
||||||
|
p.PosTile = Tile{X: int(state.X), Y: int(state.Y)}
|
||||||
|
p.PosActual = rl.Vector3{
|
||||||
|
X: float32(state.X * TileSize),
|
||||||
|
Y: float32(state.Y * TileHeight),
|
||||||
|
Z: float32(state.Y * TileSize),
|
||||||
|
}
|
||||||
|
p.TargetPath = nil
|
||||||
|
p.ActionQueue = nil
|
||||||
|
p.InterpolationProgress = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlayer(state *pb.PlayerState) *Player {
|
||||||
|
return &Player{
|
||||||
|
PosActual: rl.Vector3{
|
||||||
|
X: float32(state.X * TileSize),
|
||||||
|
Y: float32(state.Y * TileHeight),
|
||||||
|
Z: float32(state.Y * TileSize),
|
||||||
|
},
|
||||||
|
PosTile: Tile{X: int(state.X), Y: int(state.Y)},
|
||||||
|
Speed: 50.0,
|
||||||
|
ID: state.PlayerId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
37
types.go
37
types.go
@ -1,6 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import rl "github.com/gen2brain/raylib-go/raylib"
|
import (
|
||||||
|
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
||||||
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
|
|
||||||
|
time "time"
|
||||||
|
)
|
||||||
|
|
||||||
type Tile struct {
|
type Tile struct {
|
||||||
X, Y int
|
X, Y int
|
||||||
@ -8,24 +13,16 @@ type Tile struct {
|
|||||||
Walkable bool
|
Walkable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MoveAction ActionType = iota
|
|
||||||
)
|
|
||||||
|
|
||||||
type Action struct {
|
|
||||||
Type ActionType
|
|
||||||
X, Y int // Target position for movement
|
|
||||||
}
|
|
||||||
|
|
||||||
type Player struct {
|
type Player struct {
|
||||||
PosActual rl.Vector3
|
PosActual rl.Vector3
|
||||||
PosTile Tile
|
PosTile Tile
|
||||||
TargetPath []Tile
|
TargetPath []Tile
|
||||||
Speed float32
|
ActionQueue []*pb.Action
|
||||||
ActionQueue []Action // Queue for player actions
|
Speed float32
|
||||||
Model rl.Model
|
Model rl.Model
|
||||||
Texture rl.Texture2D
|
Texture rl.Texture2D
|
||||||
ID int32
|
ID int32
|
||||||
|
CurrentTick int64
|
||||||
|
LastUpdateTime time.Time
|
||||||
|
InterpolationProgress float32
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user