statesync

command
v0.7.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

statesync —— 基于 pkg/gameloop 搭状态同步 + AOI 骨架

examples/gameloop(帧同步)共用同一个 pkg/gameloop.Room, 只换了 OnTick 的策略,就从"下发输入"变成"下发状态":

帧同步 (lockstep) 状态同步 (state sync)
谁算 客户端各自算(要确定性) 服务器权威算
下发什么 输入(全体玩家本帧输入) 状态(实体坐标,AOI 过滤后)
示例 examples/gameloop 本目录

这个示例做了什么

  • 权威模拟:World.Step 每帧把玩家移动输入应用到世界坐标(服务器说了算);
  • AOI(兴趣区域):每帧建一个 pkg/spatial 网格索引;每个连接在出口index.Nearby(自己的坐标, 视野半径) 只取可视实体,下发给该客户端;
  • 扇出模型:Room 每帧只广播一份"权威世界"(*worldTick,内部对象), 各连接的写循环把它投影成各自的 View(AOI 过滤 + 可序列化)再发。 即"内部全量扇出 + 出口按连接过滤",状态同步 + AOI 的常见做法。

运行

go run ./examples/statesync

出生点故意摆成:alice(50,50) 与 bob(120,120) 相距 ≈99 < 视野 100 → 互相可见; carol(800,800) 远处 → 谁也看不见它。3 个 bot 连上后各收自己的 AOI 视图并自校验:

──────── AOI(状态同步)校验 ────────
  alice  视野内: [bob]            (期望 [bob]) ✅
  bob    视野内: [alice]          (期望 [alice]) ✅
  carol  视野内: []               (期望 []) ✅
结论: ✅ 每个客户端只收到视野内实体(AOI 过滤生效)

复用到的 beauty 原语

原语 作用
pkg/gameloop 定步长 tick + 输入聚合 + 权威世界扇出 + 生命周期
pkg/spatial 每帧网格索引,Nearby 做 AOI 视野过滤
pkg/ws 连接:读循环 Push 输入、写循环投影 AOI 视图后写回

生产化提示:本示例每连接在出口做 AOI 过滤(内部全量扇出),连接数很大时应改为 服务器侧按玩家算增量、每连接独立队列下发,并配紧凑二进制(protobuf 等)与按房间 粘连路由。高频动作类的状态更新建议走 pkg/quic不可靠数据报(丢了不重传、 不阻塞后续)而非 WebSocket(TCP,有队头阻塞),关键指令仍可走 QUIC 可靠流。

Documentation

Overview

statesync demo:基于同一个 pkg/gameloop.Room,换个 Handler 就从帧同步切到「状态同步」。

与 examples/gameloop(帧同步:下发"输入")的唯一区别在 OnTick 的策略:

  • 服务器权威模拟:每帧把玩家输入应用到世界坐标(World.Step),这里算出"结果状态";
  • AOI(兴趣区域):每帧建一次 pkg/spatial 网格索引;每个连接在"出口"按自己玩家 的视野半径查询 Nearby,只把可视范围内的实体发给该客户端——下发的是"状态"不是"输入"。

关键设计:Room 每帧只广播一份"权威世界"(*worldTick,内部对象,不直接上线); 每个连接的写循环把它投影成各自的 View(AOI 过滤后、可序列化)再下发。即 "内部全量扇出 + 出口按连接过滤"——状态同步 + AOI 的常见做法。

自带 3 个进程内 bot 验证 AOI:alice/bob 相邻(互相可见),carol 远处(谁也看不见它、它也看不见谁)。

运行:go run ./examples/statesync

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL