aboutsummaryrefslogtreecommitdiff
path: root/internal/net
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-17 20:15:57 -0400
committerhistoria <[not public]>2026-07-17 20:15:57 -0400
commit9898d42f2d4ef61b5cbec7e212914d1495e04772 (patch)
treeafa604ad77a7a03832ebbd60e77c47d4961b9d77 /internal/net
parentc23c87b56fd568956d263bb8b8c5d26fbd8d01ee (diff)
downloadthehouseoficarus-9898d42f2d4ef61b5cbec7e212914d1495e04772.tar.gz
feat: add deterministic order to mob/player tick processing, document how tick processing works
Diffstat (limited to 'internal/net')
-rw-r--r--internal/net/server.go19
1 files changed, 19 insertions, 0 deletions
diff --git a/internal/net/server.go b/internal/net/server.go
index 11339d7..9da90ea 100644
--- a/internal/net/server.go
+++ b/internal/net/server.go
@@ -11,7 +11,9 @@ import (
"math/big"
"net"
"net/http"
+ "sort"
"sync"
+ "sync/atomic"
"time"
"thehouseoficarus/internal/color"
@@ -70,8 +72,22 @@ type Session struct {
PendingUndigRoom int
promptVisible bool
writeMu sync.Mutex
+
+ // seq is a monotonically increasing sequence number assigned when the
+ // session is added to a Hub. Hub.AllSessions and Hub.PlayersInRoom sort
+ // sessions by seq so per-tick consumers iterate players in a stable,
+ // registration order instead of Go's randomized map iteration order.
+ // Sessions constructed without being added (e.g. in tests) keep seq=0
+ // and tie-break by map-append order, which is also deterministic.
+ seq uint64
}
+// sessionSeq is the source of Session.seq values. It is incremented under the
+// adding Hub's mutex, so no extra atomicity is needed for correctness; atomic
+// access keeps the package-level default counter safe if Hub.Add is ever
+// called concurrently across hubs (it isn't today, but this is defensive).
+var sessionSeq atomic.Uint64
+
type Server struct {
config *config.Config
telnetLn net.Listener
@@ -106,6 +122,7 @@ func (h *Hub) OnRemove(cb func(*Session)) {
func (h *Hub) Add(s *Session) {
h.mu.Lock()
defer h.mu.Unlock()
+ s.seq = sessionSeq.Add(1)
h.sessions[s] = true
}
@@ -165,6 +182,7 @@ func (h *Hub) AllSessions() []*Session {
for s := range h.sessions {
out = append(out, s)
}
+ sort.SliceStable(out, func(i, j int) bool { return out[i].seq < out[j].seq })
return out
}
@@ -177,6 +195,7 @@ func (h *Hub) PlayersInRoom(roomID int) []*Session {
out = append(out, s)
}
}
+ sort.SliceStable(out, func(i, j int) bool { return out[i].seq < out[j].seq })
return out
}