零基础学CocosCreator·第九季-网络游戏同步策略与ESC架构
课程里的版本好像是1.9,目前使用版本为3.8.3
开始~
目录
- 状态同步
- 帧同步
- 帧同步客户端
- 帧同步服务端
- ECS框架概念
- ECS的解释
- ECS的特点
- Entity
- Component
- System
- World
- ECS实现
- 逻辑帧&渲染帧
- ECS框架使用
- 帧同步&ECS
状态同步
一般游戏的同步策略有两种:状态同步和帧同步
如下时序图为状态同步

- c1操作从a走到b再走到c,因为不必关注细节所以c1将a走到c这个信息告诉给服务端
- 服务端验证这个操作是否合规,将验证结果告诉回c1
- 同时服务端还将这个信息转发给了c2和c3
- c2网络比较快,立刻收到了这条数据,根据插值模拟,模拟出c1从a走到c的动作(当然如果请求频率够快将a到b和b到c都告诉了c2,那就模拟的更精细)
- c3因为网络较慢,过了很久才收到服务端的数据,此时c1已经做下一个动作了,那c3就会采取一个瞬移或加速的方式模拟c1的移动
优点:
- 容易断线重连(因为数据都在服务端)
- 容易防外挂(因为逻辑都在服务端)
- 简单粗暴(客户端只需获取服务端数据并展示)
缺点:
- 服务器压力大(需要承担很大的计算量)
- 流量大(数据均由服务端传送过来)
- 不同玩家屏幕表现不一样
帧同步
帧同步的计算全部在客户端,服务端只负责做每帧收集操作,合并操作并且转发
那么问题来了,怎么保证所有客户端结果相同?
相同输入 + 相同逻辑 = 相同结果
逻辑层和显示层的分离

- 同一帧,c1想要移动,c2想要进行攻击,他们将数据都发送给了服务端
- 服务端只进行合并转发,给两个客户端
- c1收到了c1想要移动,c2想要攻击的数据,并进行模拟
- c2同样收到了c1想要移动,c2想要攻击的数据,并进行模拟
- 下一帧中客户端都没有操作,没有数据传给服务端,服务器同样进行发送操作
注意:
- 现代网游用这种模式,当c2掉线了,服务端仍然逐帧执行,c1并没有受到影响
- 而老代网游模式,每一帧客户端都需要给服务端传送数据(没操作也要传),当c2掉线后,服务端发现收不到c2的数据就会锁帧,所有客户端都需要等待,直到再次所有客户端的数据
- 再老代网游,如果有一个客户端网速很慢,客户端就会拉长帧时间去保证每个客户端的帧更新是同步的,会导致网速快的客户端也很慢
优点:
- 流量低(所有逻辑都在客户端)
- 方便做录像功能(直接客户端再次执行运算逻辑即可)
- 服务器逻辑简化
缺点:- 有可能作弊
- 需要保证各端运算结果一致性(比如随机数,无限小数等)
- 实时性要求比较高(帧同步的特点就是每秒同步很多次)
- 断线重连需要重新跑所有逻辑(可优化)
状态同步和帧同步比较

帧同步客户端
客户端职责:
- 玩家操作不直接处理,而是发送给服务器
- 收到服务器一帧数据,模拟一帧
(?帧同步但是逻辑在服务端)
[代码实现]在下面👇
帧同步服务端
具体步骤可以看之前的文章
还是再总结一下:
快速开始NodeJs项目
npm init -y
安装TSnpm install typescript --save-dev
安装WSnpm install ws --save-dev
安装提示npm install @types/ws --save-dev
生成tsconfig.jsontsc --init
安装即时编译npm install ts-node --save-dev
添加nodemonnpm install nodemon --save-dev
服务端职责:
- 把玩家加入到一局游戏中,下发初始消息
- 每一帧收集操作,合包转发
代码实现(客户端+服务端)
ECS框架概念
ECS的解释
- E - Entity 实体
- C - Component 组件
- S - System 系统
ECS的特点
- 网络-数据-逻辑-显示层相互独立
- C/S端可以运行同一份逻辑代码,方便验证作弊
服务端没有creator内api,逻辑显示放在一起的话,服务端跑不了 - 可以方便的进行预测和回退
Entity
- 每个Entity对象都有不同的EntityId
- Component挂在的对象,同种类型的Component只能拥有一个
- 提供Component的增删查和备份
Component
- Component只包含数据,不能拥有逻辑函数
- Component挂载在Entity上
- ComponentId使用不同的位来区分(因为Component操作比较频繁,所以需要使用位运算效率优化)
位运算
System
- System只拥有逻辑,不能包含数据
- System拥有不同Type,比如逻辑帧System,渲染帧System
- 依靠SystemType来确定执行顺序和每帧执行次数
- onUpdate函数由系统自动触发,不能手动调用
World
- ECS世界的入口,单例
- 驱动System和Update
- 提供Entity的增删查功能
- 使用forEach根据ComponentId组合来遍历Entity
ECS实现
实现代码
逻辑帧&渲染帧
如下图,为一帧执行的内容和不同机器的运行速度
- 我们期望1s内能执行60帧,每一帧执行一个逻辑帧和一个渲染帧,那就需要每一帧耗时不超过16.6ms
- 高性能机器每一帧耗时16ms(8+8),可以满足1s执行60帧
- 低性能机器每一帧耗时24ms(12+12),无法满足1s执行60帧,那就会优先执行逻辑帧,不执行渲染帧,去满足1s执行60次逻辑帧,保证高低性能机的逻辑次数一致,以确保执行结果相同

ECS框架使用
实现和使用放在一起了
使用ECS实现一个简单的demo(箭头旋转前进)
实现代码
帧同步&ECS
代码实现
相关文章:
零基础学CocosCreator·第九季-网络游戏同步策略与ESC架构
课程里的版本好像是1.9,目前使用版本为3.8.3 开始~ 目录 状态同步帧同步帧同步客户端帧同步服务端ECS框架概念ECS的解释ECS的特点EntityComponentSystemWorld ECS实现逻辑帧&渲染帧 ECS框架使用帧同步&ECS 状态同步 一般游戏的同步策略有两种:…...
为什么配置Redis时候要序列化配置呢
序列化和反序列化?: 序列化:将对象转换为二进制数据,以便存储到Redis中。 反序列化:将Redis中的二进制数据转换回对象,以便在应用程序中使用。 1. 默认序列化器的问题 如果不配置序列化器,Re…...
使用爬虫获取1688商品分类:实战案例指南
在电商领域,获取商品分类信息对于市场分析、选品决策和竞争情报收集至关重要。1688作为国内领先的B2B电商平台,提供了丰富的商品分类数据。通过爬虫技术,我们可以高效地获取这些分类信息,为商业决策提供有力支持。 一、为什么选择…...
C#打印设计器
C# 打印设计器,功能强大却操作简单,小白也能快速上手! 主要功能: 支持多种设计元素: 文字、图片、图形、二维码、条形码等,满足您多样化的设计需求。 灵活排版,精准定位: 支持拖拽…...
Codeforces Round 1004 (Div. 2)(A-E)
题目链接:Dashboard - Codeforces Round 1004 (Div. 2) - Codeforces A. Adjacent Digit Sums 思路 只有两种情况:n1之后没有进位,y-x1。n1之后进位(y-x-1)%90。 代码 void solve(){int x,y;cin>>x>>y;if(y-x1){cout<<…...
pnpm的使用
pnpm的使用 1.安装和使用2.统一包管理工具下载依赖 1.安装和使用 pnpm:performant npm ,意味“高性能的npm”。 pnpm由npm/yarn衍生而来,解决了npm/yarn内部潜在的bug,极大的优化了性能,扩展了使用场景。被誉为“最先进的包管理工具”。 pnpm安装指令: npm i -g p…...
vscode调试redis
系统:ubuntu redis:redis-6.0.3 1.在vs中安装c/c编译插件 2.用vscode打开redis-6.0.3 3.在菜单中找到run->Add Configuration… 4.会在目录中生成一个./vscode目录,里面包含launch.json,修改launch.json中的program:${workspaceFolder}…...
Windows逆向工程入门之汇编指令格式与操作数类型
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 一、汇编指令格式基础 二、操作数类型详解 1. 立即数(Immediate) 2. 寄存器操作数(Register) 3. 内存操作数(Memory&#…...
亚远景-ASPICE 4.0与敏捷开发:如何实现高效协同
ASPICE 4.0与敏捷开发的结合是汽车软件开发领域的重要趋势。通过合理融合,可以实现高效协同,提升软件开发的质量和效率。以下是实现高效协同的关键要点: 1. 理解ASPICE 4.0与敏捷开发的互补性 ASPICE 4.0强调软件开发过程的规范性、可追溯性…...
pptx文档提取信息
目录 一、前言二、python-pptx提取核心代码三、LibreOffice 转换pdf再提取的核心代码一、前言 pptx文档提取解析常用的库。 如果只需要解析 .pptx 的文本、表格、图片,推荐使用 python-pptx(开源,轻量级)。 如果需要高性能、支持 .ppt、动画、格式转换,推荐 Aspose.Slid…...
蓝桥杯篇---超声波距离测量频率测量
文章目录 简介第一部分:超声波的简介工作原理1.发射超声波2.接收反射波3.计算时间差4.计算距离 硬件连接1.Trig2.Echo 示例代码代码说明注意事项1.声速2.延时精度3.硬件连接 第二部分:频率测量简介频率测量原理1.信号输入2.计数3.计算频率 硬件连接示例代…...
ML.Net二元分类
ML.Net二元分类 文章目录 ML.Net二元分类前言项目的创建机器学习模型的创建添加模型选择方案训练环境的选择训练数据的添加训练数据的选择训练数据的格式要预测列的选择模型评估模型的使用总结前言 ML.NET是由Microsoft为.NET开发者平台创建的免费、开源、跨平台的机器学习…...
vite让每个scss文件自动导入某段内容
写了如下一个scss函数,希望自动导入到每个scss文件里面 vite.config.ts里面如下配置 import fs from fsconst filePath resolve(__dirname, ./src/assets/css/index.scss);const Minxcss fs.readFileSync(filePath, utf8); css: {preprocessorOptions: {scss: {…...
分享一个使用的音频裁剪chrome扩展-Ringtone Maker
一、插件简介 铃声制作器是一个简单易用的 Chrome 扩展,专门用于制作手机铃声。它支持裁剪音频文件的特定片段,并将其下载为 WAV 格式,方便我们在手机上使用。无论是想从一段长音频中截取精彩部分作为铃声,还是对现有的音频进行个…...
基于Python的Optimal Interpolation (OI) 方法实现
前言 Optimal Interpolation (OI) 方法概述与实现 Optimal Interpolation (OI) 是一种广泛应用于气象学、海洋学等领域的空间数据插值方法。该方法通过结合观测数据与模型预测数据,最小化误差方差,从而实现对空间数据的最优插值。以下是OI方法的一般步骤…...
初学 mybatis
前言 回顾之前 不使用 mybatis 框架,我们是怎么通过Java 操作数据库的 "jdbc" 前提:使用maven 构建的项目 1 添加 关于jdbc 的依赖,以及辅助操作数据库的 commons-dubli jar包 截取 前后端项目 2 添加配置文件里面内容有&…...
机器学习:k均值
所有代码和文档均在golitter/Decoding-ML-Top10: 使用 Python 优雅地实现机器学习十大经典算法。 (github.com),欢迎查看。 在“无监督学习”中,训练样本的标记信息是未知的,目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律&…...
保姆级GitHub大文件(100mb-2gb)上传教程
GLF(Git Large File Storage)安装使用 使用GitHub desktop上传大于100mb的文件时报错 The following files are over 100MB. lf you commit these files, you will no longer beable to push this repository to GitHub.com.term.rarWe recommend you a…...
1.【BUUCTF】[SUCTF 2019]EasyWeb
进入题目页面如下 给出源码开始代码审计 <?php // 定义一个名为 get_the_flag 的函数,该函数主要处理文件上传逻辑 function get_the_flag(){// 构造用户上传文件的目录,目录名是 "upload/tmp_" 加上客户端 IP 地址的 MD5 哈希值$userdir…...
CloudberryDB(七)二级索引
在CloudberryDB中,二级索引的概念与PostgreSQL中的类似。但是,由于分布式特性,创建和使用二级索引需要考虑一些额外的因素。以下是关于二级索引的一些要点: 1. **创建索引**:在Greenplum中,可以使用CREATE…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
