FPS Sample服务端技术点

本文深入剖析FPSSample教程游戏中的三大技术框架:HDRP渲染管线、DOTS技术堆栈及状态同步机制。详述UDP传输层协议的ACK机制、预测回滚机制提升用户体验、客户端插值解决角色卡顿、服务端延迟补偿优化射击体验以及快照压缩减少数据传输。这些技术共同保障了游戏的实时性和流畅性。

FPS Sample服务端技术点


FPS Sample是一个由Unity官方出品的FPS类型的教程游戏,整个教程游戏的制作水准无论是从画质还是网络同步效果都是比较高的,并且完全开源。游戏中有3个大的技术框架及其使用值得学习

  1. High-Definition Render Pipeline(HDRP).这是unity新推出的两个渲染管线中的能够取得较高画质的一个,从游戏的实际运行效果也可见一斑。
  2. Data-Oriented Technology Stack (DOTS).这也是unity力推的一套提升游戏运行效率的技术,基本包括:①Entity Component System (ECS)机制 ②C# Job System ③burst compiler。youtube上面有一些测试视频能看到有时DOTS能够为场景提供几十倍的性能提升。
  3. 状态同步机制。FPS Sample并没有特别复杂的服务端架构,仅仅是客户端连接上服务端,两端同步指令和状态数据。这个同步的过程正式这篇文章想要描述的主要内容,下文以每一个技术点为小节展开。

基本信息

考虑到实时性,FPS Sample也使用了UDP作为战场内数据同步的传输层协议,为了防止丢包,做了ACK机制和数据重传机制。这个数据重传并不和TCP一样丢了某一帧的数据就再把那一帧的数据重发一份完全一样的,毕竟在实时性很强的射击游戏里面,重传之前的老数据的意义也不大。FPS做的重传方式是将重要信息重传,譬如服务端想要下发生成entityA的一个命令,服务端会一直向发往客户端数据包中写入创建一个entityA的命令,直至收到客户端回复了创建entityA的ACK。在服务端做的另一个方面就是尽量使用一些持续的状态,而不是一个瞬发事件。客户端对于防丢包做法就是传输冗余数据,每一帧向服务端发送用户输入的时候把之前两帧的用户输入再次传输。由于用户输入数据量很小,重复传输用户输入可以很有效的防止丢包,如果一次丢包的概率是 1 0 − 5 10^{-5} 105,那三次都丢包的概率就只有 1 0 − 15 10^{-15} 1015了。

#客户端预测回滚
在FPS Sample中,服务端有着绝对的权威,也就是说客户端并不会上传任何本地信息譬如英雄的血量、位置等,而是由服务端下发到客户端。但是这样就会造成一个问题:客户端接收到用户的输入并上传到服务端,服务端处理之后将整个数据快照发放到客户端这样一个流程至少需要一个rtt (Round-Trip Time),这还是在忽略服务端处理时间的情况下。这样的话很多时候都会给用户一种很卡的感觉。为了解决上述问题,FPS Sampe使用了比较常见的“预测回滚机制”。预测回滚机制包含两个部分,①一个是预测:客户端接受到用户的输入之后一方面将用户输入上传到服务端另一方面会按照和服务端一致的逻辑执行用户输入,这样的话无需等到服务端回复消息玩家控制的角色就可以响应用户输入,能够有效的提升用户体验。②另一个是回滚:单单有预测的话可想而知会造成客户端和服务端数据不一致,所以当服务端快照到达的时候,客户端会先将玩家控制角色的状态设置和服务端完全一致,然后将服务端还未处理的(因为rtt的存在)消息再走一遍预测逻辑。预测回滚机制只对本地玩家控制的角色生效,并不会对其他玩家控制的角色(也就是敌人)起作用,并且在预测的时候并不会创建新的entity,譬如在用户按下鼠标开枪的时候,客户端仅会播放开枪的动画而子弹entity的生成还是需要等到服务端通知才会发生。
为了定位哪些消息是服务端处理了的哪些消息服务端还未处理,客户端会维护几个变量,名称和含义如下表所示,这几个变量的主要逻辑都存在与ClientGameLoop.HandleTime(f

start running... -- [I] [Maix Comm Protocol] listening on uart port: /dev/serial0 -- [I] load cvimodel from: /root/models/my/ny5.maixcam/model_218867.cvimodel -- [I] model info: type: yolov5 input type: rgb mean:0.000000 0.000000 0.000000 scale:0.003922 0.003922 0.003922 labels num: 8 anchors:10.00 13.00 16.00 30.00 33.00 23.00 30.00 61.00 62.00 45.00 59.00 119.00 116.00 90.00 156.00 198.00 373.00 326.00 input size: 224x224 2025-07-11 11:44:10,279 [INFO] YOLOv5 model loaded -- [W] Note that we do not recommend using large resolution RGB888 images, which can take up a lot of memory! [SAMPLE_COMM_SNS_ParseIni]-2191: Parse /mnt/data/sensor_cfg.ini [parse_source_devnum]-1784: devNum = 1 [parse_sensor_name]-1865: sensor = GCORE_GC4653_MIPI_4M_30FPS_10BIT [parse_sensor_busid]-1894: bus_id = 4 [parse_sensor_i2caddr]-1905: sns_i2c_addr = 29 [parse_sensor_mipidev]-1916: mipi_dev = 0 [parse_sensor_laneid]-1927: Lane_id = 4, 3, 2, -1, -1 [parse_sensor_pnswap]-1938: pn_swap = 0, 0, 0, 0, 0 [parse_sensor_mclken]-1960: mclk_en = 1 [parse_sensor_mclk]-1971: mclk = 1 [SAMPLE_COMM_SNS_ParseIni]-2191: Parse /mnt/data/sensor_cfg.ini [parse_source_devnum]-1784: devNum = 1 [parse_sensor_name]-1865: sensor = GCORE_GC4653_MIPI_4M_30FPS_10BIT [parse_sensor_busid]-1894: bus_id = 4 [parse_sensor_i2caddr]-1905: sns_i2c_addr = 29 [parse_sensor_mipidev]-1916: mipi_dev = 0 [parse_sensor_laneid]-1927: Lane_id = 4, 3, 2, -1, -1 [parse_sensor_pnswap]-1938: pn_swap = 0, 0, 0, 0, 0 [parse_sensor_mclken]-1960: mclk_en = 1 [parse_sensor_mclk]-1971: mclk = 1 try release sys ok [_mmf_init]-1144: maix multi-media version:67a90e2-musl_riscv64 maix multi-media init ok try release vio ok try release venc ok ISP Vipipe(0) Allocate pa(0x8acf5000) va(0x0x3fe8fcf000) size(291424) stSnsrMode.u16Width 2560 stSnsrMode.u16Height 1440 25.000000 wdrMode 0 pstSnsObj 0x3fece00d18 ############# [cmos_set_image_mode][1176] fps:25.000000 [SAMPLE_COMM_VI_StartMIPI]-494: sensor 0 stDevAttr.devno 0 awbInit ver 6.9@2021500 0 R:1400 B:3100 CT:2850 1 R:1500 B:2500 CT:3900 2 R:2300 B:1600 CT:6500 Golden 1024 1024 1024 WB Quadratic:0 isWdr:0 20250711 11:44:10.487 2567 E isp setNoiseProfile:3460 Noise profile get fail. Please check ########### PinMux ####################################################################### ########### PinMux End ####################################################################### ViPipe:0,===OS04A10 1520P 30fps 12bit LINE Init OK!=== ******************************************************************************** cvi_bin_isp message gerritId: 97347 commitId: fc6ce647 md5: d6db2297ddfd44e8252c1f3f888f47b2 sensorNum 1 sensorName0 5440577 PQBIN message gerritId: commitId: fc6ce647 md5: d6db2297ddfd44e8252c1f3f888f47b2 sensorNum 1 sensorName0 5440577 author: lxowalle desc: os04a10 createTime: 2024-08-30 11:00:43version: tool Version: v3.0.5.48 mode: ******************************************************************************** [SAMPLE_COMM_ISP_Thread]-95: ISP Dev 0 running! 0 R:1257 B:3920 CT:2788 1 R:1588 B:2858 CT:3968 2 R:2169 B:1819 CT:7154 Golden 1588 1024 2858 wdrLEOnly:1 [SAMPLE_COMM_VO_StartChn]-351: u32Width:480, u32Height:640, u32Square:1 -- [I] [Maix Comm Protocol] exit... -- [I] [Maix Comm Protocol] exit success -- [I] [Maix Comm Protocol] UART /dev/serial0 ready to init 2025-07-11 11:44:12,044 [INFO] UART initialized 2025-07-11 11:44:12,176 [CRITICAL] Login failed: Expecting value: line 1 column 1 (char 0) maix multi-media driver released. ISP Vipipe(0) Free pa(0x8acf5000) va(0x0x3fe8fcf000) program exit failed. exit code: 1. 这个日志报错报什么情况?
最新发布
07-12
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值