
VolatileEntities
VolatileEntities 是一个基于 ECS 的 Hytale 框架,它允许你创建和管理非持久性或时间控制的实体,而不会在世界中留下“垃圾”。
VolatileEntities
VolatileEntities 是一个基于 ECS 的 Hytale 框架,允许你创建和管理非持久化或时间控制实体,且不会在世界中留下“垃圾”。
它旨在:
- 提供对实体生命周期的精细控制(距离、超时、所有者断开连接等),
- 在服务器重启时自动清理实体,
- 并在你的插件卸载后确保清理。
核心功能
重启时的自动非持久化
任何带有 VolatileComponent 的实体都会在服务器重启后的第一个游戏刻自动移除,这得益于:
- 组件编解码器 (
VolatileComponent.CODEC) 处理的expiredOnLoad标志, - 以及
VolatileTickSystem系统会销毁“从磁盘加载”的易失实体。
这保证了易失实体永远不会在重启后存活,即使它们曾被保存到磁盘。
运行时灵活 TTL(插件运行时)
使用 VolatileConfig 和 VolatilePolicy,你可以精确控制实体在运行时的存活时间:
IDLE_TIMEOUT– 在 X 个游戏刻或秒无活动后消失,MAX_DISTANCE– 当与链接实体距离过远时消失,LINKED_ENTITY_INVALID– 当链接实体变得无效时消失,CUSTOM– 通过VolatileContext上的谓词实现完全自定义的消失逻辑。
所有这些都在你的插件加载时由 VolatileTickSystem 评估。
策略组合
策略不是排他性的。
单个易失实体可以同时组合多个策略。实体将在任何策略条件满足时立即被移除。
例如,一个实体可以:
- 在 10 秒不活动后消失(
IDLE_TIMEOUT), - 或者在与目标距离过远时消失(
MAX_DISTANCE), - 或者在其所有者断开连接时被移除(
OWNER_DISCONNECT)。
这让你无需编写自定义代码即可表达复杂的生命周期。
VolatileEntities.builder()
.withinDistance(targetRef, 30f)
.idleTimeoutSeconds(10f)
.ownedBy(playerUuid)
.spawn(commandBuffer);
组合易失策略(示例)
此示例演示如何将多个 VolatilePolicy 规则组合到一个 VolatileConfig 中。
策略不是排他性的:一个实体可以同时应用多个生命周期规则。
实体将在任何策略条件满足时被移除。
示例:与另一个实体绑定的区块边界实体
VolatileConfig.VolatileConfigBuilder configBuilder = VolatileConfig.builder()
// 区块卸载时自动移除实体
.policy(VolatilePolicy.CHUNK_UNLOAD)
// 一旦策略条件变为无效,立即移除
.removeOnInvalid(true);
// 可选地将此易失实体链接到另一个实体(例如,一个怪物或 NPC)
if (linkedEntity != null) {
configBuilder
.policy(VolatilePolicy.LINKED_ENTITY_INVALID)
.linkedEntity(linkedEntity);
}
VolatileConfig config = configBuilder.build();
return new VolatileComponent(config);
使用 Hytale 的 DespawnComponent 实现绝对 TTL(区块卸载/重载安全)
VolatileEntities 与 Hytale 原版系统干净地集成:
DespawnComponent+DespawnSystem处理绝对、实时 TTL,USE_DESPAWN_TTL策略告诉 VolatileEntities 将 TTL 处理完全委托给DespawnComponent。
这意味着:
- TTL 基于实时(
TimeResource),而非游戏刻, - 区块卸载/重载是安全的,
- 如果区块重载时消失时间已过,实体立即被移除。
因此,你可以选择:
- 运行时、仅联机 TTL(
IDLE_TIMEOUT),或 - 绝对 TTL,即使在卸载时也继续计时(
USE_DESPAWN_TTL+DespawnComponent)。
插件卸载后的清理
为了解决经典的“移除模组后实体残留”问题,VolatileEntities 使用了一种保活模式:
VolatileDespawnKeepAliveSystem持续刷新易失实体上的原版DespawnComponent(使用USE_DESPAWN_TTL的除外),- 当你的插件安装时,消失截止时间被不断向前推,
- 一旦你的插件被移除,最后的消失截止时间最终会到达。
此时,Hytale 的核心 DespawnSystem 会自动清理所有剩余的易失实体,即使你的插件已不存在。
无需手动扫描世界。没有孤儿实体。
高级策略
除了核心 TTL 策略外,该框架还支持:
CHUNK_UNLOAD– 当区块卸载时自动移除易失实体(由VolatileChunkUnloadSystem处理,这是一个EntityEventSystem<ChunkUnloadEvent>)。OWNER_DISCONNECT– 当玩家断开连接时,标记或移除属于该玩家的易失实体(由VolatileOwnerDisconnectListener处理,监听PlayerDisconnectEvent)。
将这些策略组合在一起,为临时实体提供了强大的生命周期工具集。
典型用例
使用 VolatileEntities 将以下实体标记为易失:
- 全息投影,
- 弹射物,
- 视觉效果,
- 临时 NPC,
- 辅助或标记实体
使它们:
- 在重启时消失,
- 可选地遵循运行时规则(超时、距离、所有权、自定义逻辑),
- 并且仍保证在插件卸载后被清理。
使用示例
1) 将现有实体标记为易失(仅重启)
如果你已经手动生成了一个实体(例如全息投影),你可以简单地附加一个 VolatileComponent 使其非持久化。
holder.addComponent(
VolatileComponent.getComponentType(),
VolatileComponent.restartOnly()
);
结果:
- 实体在服务器运行期间存在,
- 在重启后的第一个游戏刻被移除,
- 卸载安全清理仍然适用。
2) 绝对 TTL(10 秒实时)
要在固定实时时间后消失实体(即使跨越区块卸载),结合使用 DespawnComponent 和 USE_DESPAWN_TTL:
holder.addComponent(
DespawnComponent.getComponentType(),
DespawnComponent.despawnInSeconds(time, 10f)
);
VolatileConfig cfg = VolatileConfig.builder()
.policy(VolatilePolicy.USE_DESPAWN_TTL)
.build();
holder.addComponent(
VolatileComponent.getComponentType(),
new VolatileComponent(cfg)
);
这里:
- Hytale 自行处理 TTL,
- VolatileEntities 不会刷新消失时间,
- 重启和卸载清理仍然得到保证。
3) 标记一个已存在的实体为易失
你可以在实体已经存在后将其标记为易失:
store.putComponent(
ref,
VolatileComponent.getComponentType(),
VolatileComponent.restartOnly()
);
无需重新生成或手动消失逻辑。
API 参考(快速概览)
VolatileComponent – 工厂方法
restartOnly()– 仅运行时有效,重启时移除withTimeout(int ticks)/withTimeoutSeconds(float seconds, int tickRate)withinDistance(Ref<EntityStore> target, float distance)linkedTo(Ref<EntityStore> target)ownedBy(UUID playerUuid)useDespawnTtl()
VolatileConfig
用于高级控制的预设和构建器:
chunkBound()linkedTo(ref)withinDistance(ref, distance)ownedBy(playerUuid)withTimeout(ticks)useDespawnTtl()custom(ctx -> { ... })
VolatileEntities.builder()
为了方便,构建器 API 提供了流畅的方式来生成易失实体:
VolatileEntities.builder()
.at(new Vector3d(x, y, z))
.with(MyComponent.TYPE, new MyComponent(...))
.withinDistance(targetRef, 50f)
.idleTimeoutSeconds(10f)
.spawn(commandBuffer);
安装
将 VolatileEntities JAR 文件放入你的服务器的插件文件夹。
在你的插件清单中声明依赖:
{
"Group": "Ender_Griefeur99",
"Name": "MyPlugin",
"Version": "1.0.0",
"Main": "fr.ender_griefeur99.myplugin.MyPlugin",
"ServerVersion": "*",
"IncludesAssetPack": false,
"Dependencies": {
"Ender_Griefeur99:VolatileEntities": "*"
}
}
正在加载版本记录…

正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。