lockstepserver
lockstepserver copied to clipboard
协议可简化
我定义的帧同步服务器协议如下,可以讨论下:
/* 客户端服务器之间仅需通过kcp收发消息,没有实现grpc *\
// 中继服提供的房间中继接口,用于向客户端提供服务。
service Relay {
rpc EnterRoom (EnterReq) returns (EnterResp) {}
// 玩家动作
rpc Act (stream ActMsg) returns (ActResp) {}
// 帧广播
rpc Tick (TickReq) returns (stream TickMsg) {}
}
各消息定义如下:
message EnterReq {
// 服务器可以从 player_token 找到对应的房间和玩家号.
optional string player_token = 1;
// 上个帧号,需要服务器发送之后的帧: last_tick+1, last_tick+2, ...
// 用于断线重连。
// 如果是从头开始,则 last_tick 为0, 开始帧为 1.
optional uint32 last_tick = 2;
}
message EnterResp {
optional bool ok = 1;
optional string error = 2;
optional uint32 player_id = 3;
optional uint32 ifs = 4; // 帧时间间隔
optional uint64 rand_seed = 5; // 随机种子
}
message ActMsg {
// 客户端自定义格式,服务器不会解析.
optional bytes action = 1;
}
message ActResp {
}
message TickReq {
}
// 帧消息。
// 中继服将记录所有帧消息,用于断线重连。
message TickMsg {
optional uint32 tick = 1; // 当前帧号:1,2,...
repeated PlayerActions player_actions = 2; // 所有玩家的动作
// 单个玩家当前帧的所有输入动作。保持输入次序。
message PlayerActions {
optional uint32 player_id = 1;
repeated bytes actions = 2;
}
}
读条准备是客户端逻辑,服务器不管。
抱歉这么久才看见。帧同步服务器的消息确实是可以定义很简单。我的考虑在: 1.希望客户端和帧服务器连上以后,尽量让帧服务器来承担一部分工作,这样可以避免客户端在两个网络层切来切去的麻烦。 2.我把读条,重连这种也算作帧服务器的基础功能。 定位是除了游戏玩法逻辑之外事都承担过来。
通用帧同步服务器应该允许没有读条,没有重连,读条和重连都是和游戏玩法逻辑相关的。如有的游戏可以随时加入房间,不需要等人齐了一起进入。有的游戏断线就算逃跑失败。
读条肯定不是必要的。只不过我们项目中有,这个确实跟需求而定。中途加入不就是重连吗?不给你发前面的帧数据怎么继续下去?请赐教不胜感激
重连是通用功能。我定义的 EnterReq.last_tick 就是用于断线重连的。