组件实体系统实体特定数据
Component Entity System Entity Specific Data
我在 javascript 中编写组件实体系统已经有一段时间了,但我一直回到根本问题上。
您如何处理特定于实体(即单个实例或单个类型)的功能?
这是目前的情况:
按照我构建事物的方式,当一个项目实体被另一个实体存储在库存中时,它并没有被销毁,只是剥离了它的大部分组件。这样一来,如果它被丢弃,或者可能被取回使用,它可以以其旧状态重新激活。剥离的组件存储在附加到实体的 InstanceDataComponent 中(这只是一个 JSON 对象)。
有一个小系统用于管理是否可以拾取物品的内部结构,并为存储的物品添加带有哈希、数量和 ID 的库存记录,但需要管理该实体的转换从 "item" 状态到 "stored" 状态。 应该怎么做?在我看来,要删除哪个组件以及要更改哪些数据的详细信息对于每个项目都需要几乎是唯一的。
假设将来我想要一个实体在两种行为之间动态切换。例如,来回走动直到它被打扰,然后寻找玩家。什么将处理这种转变?
我觉得我对这里的问题和典型架构存在根本性的误解。处理这个问题的干净方法是什么?我是否应该为每组行为转换添加一个组件?这不会以太多被美化的回调包装器的组件而告终吗?还是我遗漏了一些关于实体存储在库存中时应如何更改的信息?
对可能正在经历这种情况的其他人的一些想法。
我目前的解决方案(经过几次迭代)是触发一个全局事件,例如itemPickupSystem:storedItem
并且实体可以为其工厂方法内的任何事件附加处理程序。由于多种原因,这是不可扩展的。我一直在考虑将这些事件移到队列中以便稍后执行。
我的工厂方法变成了回调定义的大杂烩,事情正在退化为回调地狱。此外,这个事件系统必须要走,它是整个系统中唯一打破游戏循环连续性的部分。到目前为止,每个系统都按照定义的顺序启动,所有逻辑都驻留在这些系统中。现在我不能保证一个实体将处于特定状态,因为这些回调可能在不同的时间点被触发。最后,由于执行被全权委托给不属于核心功能的代码,因此无法知道触发事件时调用堆栈的大小。
有时从务实的网络复制的角度最容易想到这个问题,组件之间的界限自然而然。
假设您的演员既可以挥舞也可以储存剑。
我不希望 'transform' 从 inventorySword 到 presentationSword,而是 'inventoryItem' 和 'swordPresentation' 之间的自然界线。
在服务器上,每个玩家都会被分配到他们物品栏中的物品列表。每个项目都有一个世界唯一的 ID。库存项目可能派生为 'SwordItem' 并具有 SwordType 和 Condition%
的属性
在客户端,'swordPresentation' 组件可能会处理以下工作:显示哪个网格、当通过第一人称相机显示时将动画数据附加到哪个套接字,以及如何平滑动画过渡。但是 none 对 游戏的实际状态 很重要,这只是我们的客户看待世界的方式。
如果您要将游戏状态分发给每个客户端,那么您将通过网络传递的所有内容都将是当前玩家的库存,而对于其他玩家来说,每个玩家当前装备的物品以及他们在哪里是(假设他们在视力范围内)
因此,考虑创建一个工厂,根据库存项目创建 'swordPresentation',找到可以作为参数传入的最低限度,以创建组件的表示(可能是剑型,剑% 条件等)。
无论最低限度是什么,您都希望序列化为您的库存项目。
在复制的数据之间建立清晰的界限意味着在编写多人游戏时性能更好,漏洞更少。当您编写单人游戏时,它将帮助您了解保存文件中的内容。
我在 javascript 中编写组件实体系统已经有一段时间了,但我一直回到根本问题上。
您如何处理特定于实体(即单个实例或单个类型)的功能?
这是目前的情况:
按照我构建事物的方式,当一个项目实体被另一个实体存储在库存中时,它并没有被销毁,只是剥离了它的大部分组件。这样一来,如果它被丢弃,或者可能被取回使用,它可以以其旧状态重新激活。剥离的组件存储在附加到实体的 InstanceDataComponent 中(这只是一个 JSON 对象)。
有一个小系统用于管理是否可以拾取物品的内部结构,并为存储的物品添加带有哈希、数量和 ID 的库存记录,但需要管理该实体的转换从 "item" 状态到 "stored" 状态。 应该怎么做?在我看来,要删除哪个组件以及要更改哪些数据的详细信息对于每个项目都需要几乎是唯一的。
假设将来我想要一个实体在两种行为之间动态切换。例如,来回走动直到它被打扰,然后寻找玩家。什么将处理这种转变?
我觉得我对这里的问题和典型架构存在根本性的误解。处理这个问题的干净方法是什么?我是否应该为每组行为转换添加一个组件?这不会以太多被美化的回调包装器的组件而告终吗?还是我遗漏了一些关于实体存储在库存中时应如何更改的信息?
对可能正在经历这种情况的其他人的一些想法。
我目前的解决方案(经过几次迭代)是触发一个全局事件,例如itemPickupSystem:storedItem
并且实体可以为其工厂方法内的任何事件附加处理程序。由于多种原因,这是不可扩展的。我一直在考虑将这些事件移到队列中以便稍后执行。
我的工厂方法变成了回调定义的大杂烩,事情正在退化为回调地狱。此外,这个事件系统必须要走,它是整个系统中唯一打破游戏循环连续性的部分。到目前为止,每个系统都按照定义的顺序启动,所有逻辑都驻留在这些系统中。现在我不能保证一个实体将处于特定状态,因为这些回调可能在不同的时间点被触发。最后,由于执行被全权委托给不属于核心功能的代码,因此无法知道触发事件时调用堆栈的大小。
有时从务实的网络复制的角度最容易想到这个问题,组件之间的界限自然而然。
假设您的演员既可以挥舞也可以储存剑。
我不希望 'transform' 从 inventorySword 到 presentationSword,而是 'inventoryItem' 和 'swordPresentation' 之间的自然界线。
在服务器上,每个玩家都会被分配到他们物品栏中的物品列表。每个项目都有一个世界唯一的 ID。库存项目可能派生为 'SwordItem' 并具有 SwordType 和 Condition%
的属性在客户端,'swordPresentation' 组件可能会处理以下工作:显示哪个网格、当通过第一人称相机显示时将动画数据附加到哪个套接字,以及如何平滑动画过渡。但是 none 对 游戏的实际状态 很重要,这只是我们的客户看待世界的方式。
如果您要将游戏状态分发给每个客户端,那么您将通过网络传递的所有内容都将是当前玩家的库存,而对于其他玩家来说,每个玩家当前装备的物品以及他们在哪里是(假设他们在视力范围内)
因此,考虑创建一个工厂,根据库存项目创建 'swordPresentation',找到可以作为参数传入的最低限度,以创建组件的表示(可能是剑型,剑% 条件等)。
无论最低限度是什么,您都希望序列化为您的库存项目。
在复制的数据之间建立清晰的界限意味着在编写多人游戏时性能更好,漏洞更少。当您编写单人游戏时,它将帮助您了解保存文件中的内容。