Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于技能组件的问题 #9

Closed
jxianglonggg opened this issue Mar 18, 2022 · 9 comments
Closed

关于技能组件的问题 #9

jxianglonggg opened this issue Mar 18, 2022 · 9 comments

Comments

@jxianglonggg
Copy link

想定义1个实体的技能组件,用来记录这个实体所拥有的技能信息 比如cd之类的,由于1个实体拥有多个技能,所有这个技能组件会是一个数组结构,但是目前好像无法注册数组类型的组件,我目前想到的解决方法是我定义一个技能数组的userdata,然后注册这个userdata类型。刚用ecs写逻辑,不知道这个做法是否正确。

@cloudwu
Copy link
Owner

cloudwu commented Mar 18, 2022

直接定义成 lua 类型 https://github.com/cloudwu/luaecs/blob/master/test13.lua#L17 ,你就可以放任何 lua 对象,包括 table 了。

@jxianglonggg
Copy link
Author

好的,谢谢云大,我看例子里放的是字符串。

@Gowa2017
Copy link

兄弟 其实你这个问题 就是一个实体要不要拥有多个组件的问题。
针对这种问题 其实没有什么好的办法。要么就是把所有技能揉在一起 当成一个子组件的样子,它有多个技能组件的实例。

要么就把技能单独放,关联角色实体的id。但这样的话就不得不维护一个从技能与角色的这么一个状态。

@cloudwu
Copy link
Owner

cloudwu commented Mar 23, 2022

我最近的一点点不成熟想法,写一下供讨论:

从数据角度讲,是不是我们不应该只用一个 world 来储存数据?而应该把 world 看成是一张(二维)表,它只保存一个系统可能会同时访问,关联在一起的数据。即一次 select 就能拿出来的数据组。

有些数据的关联关系超过了行列就能表示的时候,我们需要第三个维度,这个时候采用多张表更合适。

例如,我们把所有的 buf 、所有的技能、所有的物品格,都放在不同的表里。

以物品格为例,在物品表(world) 中,一个 entity 表示的是一个物品,它属于哪个角色就是由一个组件中的 id 决定的。我们可以用角色 id + 物品格 id 构成一个全局 id ,指代一个特定的格子。利用 select 已有的 order 特性,就可以把同一角色身上的所有格子按次序遍历出来。

分开多张表可以方便 entity 的管理,component 类型也相当于多了一层名字空间。可能处理起来更方便。

@Gowa2017
Copy link

这个符合直觉。我很赞同。
采用三维表是站在 c 的角度和内存布局来看。
弄对于采用单一组件是一一lua表,其实感觉上一样。不过是享受不到 c 内存的好处。

本质上 我们的 ecs 当前是个稀疏矩阵。关联其他表来查询的话 在表示上怎么来弄。在编写 System 的时候是不是处理方式还会有不同。单纯的 select 是不是还得提供 join 语法?

@Gowa2017
Copy link

我们看看起来是要解决的是传统 ecs

难以处理 实体与实体间的关系 和 实体上可能不止一个组件实例的问题。

@rockingdice
Copy link

碰巧看到这个讨论,提供一点其他框架的作者的见解,云风有空可以看看(如果你还没看过的话):
https://skypjack.github.io/2019-06-25-ecs-baf-part-4/
这是entt作者的博客

从性能的角度去想,他是不建议使用同类型的多个component的,而且一个component里去使用动态分配的std::vector这种也是不建议的,那么其实最后的解决思路就是用多个entity的方式,做hierarchy去解决。

另外还有一个ppt我觉得做的也不错,讲ecs和sql关系的:
https://docs.google.com/presentation/d/1LOgKiBkS_839ezMwzjBcLxHkj_IlLJo6C83v1uVjhaE/edit#slide=id.g5a6fe73109_0_0

最终ecs的发展方向就是类似关系型数据库吧,而这些数据库可以参考的优化方案可就太多了。

前后统一了属于是[doge]

@cloudwu
Copy link
Owner

cloudwu commented Apr 3, 2023

补充一点想法:

如果一个 entity 需要关联不定数量的一种东西(未必只是一个 component ),例如,一个玩家需要关联 n 个技能。怎么处理这个 n ?

我想可以考虑这样一种方法。把技能也当作 entity 而不是 component 。但是在数据结构上,是排列在玩家这个 entity 之后的。所以,设想整体数据结构,就是每两个玩家 entity 之间,夹着不定数量的技能 entity 。

我们在 api 层面需要提供一种能力,就是 select 是可以嵌套的,内层 select 可以指定一个检索范围,这个范围是由外层 select 迭代器决定的。这样,应用时就可以在 select 玩家的过程中,再 select 一个区间的技能。也可以把技能作为一个整体来遍历。

如此,我们就可以有了一个带层次的数据结构。

这种结构的缺陷是,每个玩家身上的技能数量 n 本身改变的时候,可能性能非常的差。在这方面,可能可以通过一些已有机制做一点优化。例如:我们能给出一个估计的最大 n ,那么结合已有的 flag 机制,把暂时不用的技能打上标记在 select 过程过滤掉。只在必要的时候扩展 n (涉及大量的内存移动)。

如果想进一步的优化,或许需要设计一种叫做稀疏 components pool 的数据结构来维持技能这种 entity 。比如可以用平衡树的方式来储存。

@Gowa2017
Copy link

实际上图也可以用稀疏矩阵来表示,但那样的情况下,也无法避免需要随机访问(根据 EID),和当前的模式就不太一样了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants