美文网首页前端开发那些事儿
基于ECS的大地图同步方案(下)

基于ECS的大地图同步方案(下)

作者: 李相赫的乐芙兰 | 来源:发表于2021-06-07 22:35 被阅读0次

前面两节讲述了ECS框架以及大地图同步的实现方案,本篇最为这个系列的最后一篇,主题是“没有银弹”,讨论一下基于ECS同步的局限性。
1.难以对复杂数据类型(比如vector,map或者自定义的class)进行同步
a.复杂类型的变化不容易描述
上节中所述,同步的重点在于如何判断数据发生了变化。在当前的实现方案中,是采用变化标记+版本号的方式来管理看到一个实体时到底需要同步哪些数据的。对于基础类型来说(比如int、string),当值发生了变化,那就直接将变化标记置为true,等需要同步时将整个变量的值写进同步包里即可。而对于复杂类型,如果只变化了一部分,就需要同步整个变量,那显然是一件效率非常低的事,而描述到底哪一部分发生了变化,逻辑由过于复杂(试想一下该怎么描述一个map的各种变化情况)
b.复杂类型的序列化难以扩展
同步数据包需要对变化的变量进行序列化和反序列化的支持,而如果要序列化自定义类型,则每加一种类型就需要修改一次序列化的接口。由于客户端需也需要调用对应的反序列化的dll,每加一种类型就得更新客户端的dll(对手机包来说就得整包更新)这显然也是无法接受的

2.一个实体上相同的组件只能有一份
ECS的设计理念中,同一个Entity中不允许存在两个相同的Component。比如一个建筑实体,只能有一个ComponentBuilding,一个ComponentPosition,这在大多数情况下是满足需求的。但是假如一个建筑拥有多个技能,此时不能在实体上附加多个ComponentSkill。
为了应对这种情况,项目中采用为每一个技能创建一个技能实体,在技能实体上附加ComponentSkill。然后在建筑实体上附加一个ComponentSkillMgr,在这个组件中记录所有技能实体的id,用来管理建筑的所有技能。

3.同步的延迟性
游戏世界中实体的变化是随时都可能发生的,而数据同步是按固定的同步帧,对视野内的实体进行标记检测来判断需要哪些数据的。如果一个实体的某个数据,在一帧中变化了多次,检测时只知道这个数据发生了变化以及最后的值,但无法知道变化的过程。
可能有人会说为什么不在发生变化的时候立即同步呢?这就回到第一节中讲到的视野同步方案选择的问题了。因为SLG大地图沙盘无法想MMORPG一样有“视野对”的概念,当一个实体发生了变化,此时它时很难知道到底应该同步给哪些玩家的(也许可以但计算量会非常巨大)
由于客户端获取到的实体变化时延迟的(甚至是不全的),就需要在逻辑上做一些额外的处理。

4.链表
由于ECS支持一个实体自由的增加和删除组件,所以在存储时大量采用链表的结构
a.system在管理同一个组件的所有实例时采用链表的结构
这就要求在每帧Update遍历组件时必须一次性全部遍历,而无法拆到多个帧中分批Update(因为到了下一帧,链表可能已经发生了变化,无法维护上一帧到底遍历到哪里接着往后遍历)。如果服务器的实体非常多,每帧全部遍历会导致卡顿的化则处理起来比较棘手。
b.一个实体内部管理所拥有的组件时采用链表结构
如果一类实体上挂的组件非常多(比如一个部队可能挂10几个组件),在获取某个组件的开销的时间常数将会比较大,而获取组件是一个调用频率非常之高的操作,这可能会是一个隐患

最后总结一些在实际项目中对于上面这些问题的“妥协”做法:

1.只对大地图可见(需要进行视野同步)的逻辑物使用ECS方式管理和同步,其他与视野同步无关的对象,采用传统的OOP和protobuf消息的方式同步
2.组件中需要同步的变量禁止使用复杂类型
3.如果一个父对象实体包含多种相同的子对象,则将每个子对象实例化成独立的实体,然后在父对象实体中记录这些子对象实体的id
4.如果在一个同步帧期间一个变量发生了多次变化,并且这些变化的过程都需要同步,则与客户端约定使用字符串的方式记录变化并同步这个字符串

相关文章

  • 基于ECS的大地图同步方案(下)

    前面两节讲述了ECS框架以及大地图同步的实现方案,本篇最为这个系列的最后一篇,主题是“没有银弹”,讨论一下基于EC...

  • 基于ECS的大地图同步方案(上)

    最近打算回顾一下在自己在slg向的沙盘大地图游戏开发中遇到的一些问题和解决方案,本篇(大概会分上中下3节)主要讲述...

  • 基于ECS的大地图同步方案(中)

    上节[%5Bhttps://www.jianshu.com/p/3977d75fef48%5D(https://w...

  • 基于ECS的游戏同步设计

    前言 早期为了实现对服务器的快速实现,忽略了系统上的设计。使用传统的面向对象的方式对业务需求进行实现,导致了项目...

  • App中高德地图如何显示国外地址

    上篇《基于Android平台的全球地图方案》大概描述了不同地图之间的差异,以及在国内要显示国外的地址有哪些方案。本...

  • tiny ecs(2:简单背景)

    背景 最近公司需求用ecs写slg地图与战斗场景,使用的框架为tiny-ecs[https://github.co...

  • 基于fabric的地图定位,SVG热力地图

    基于fabric的地图定位,SVG热力地图 基于fabric的地图定位,SVG热力地图 基于 fabricjs v...

  • (16)MGR

    问题:MySQL高可用方案,异步和半同步复制,难可用和不丢数据间取舍,MGR基于Paxos多数派,作为半同步复制的...

  • 基于Android平台的全球地图方案

    现状 百度地图、高德地图在国外无法显示详细地面信息或显示不全面,Google Map在国内不好使。 需求 根据坐标...

  • 战斗系统设计概述

    同步方案: 在同步方案上采用的是状态同步的方案,主要的考虑是状态同步是网易多款实时手游均采用的方案,得到了验证,风...

网友评论

    本文标题:基于ECS的大地图同步方案(下)

    本文链接:https://www.haomeiwen.com/subject/iwuqeltx.html