Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
9.7 KiB
@esengine/ecs-framework
2.7.1
Patch Changes
-
#402
3e5b778Thanks @esengine! - fix(ecs): 修复 ESM 环境下 require 不存在的问题- 新增
RuntimeConfig模块,作为运行时环境配置的独立存储 Core.runtimeEnvironment和Scene.runtimeEnvironment现在都从RuntimeConfig读取- 移除
Scene.ts中的require()调用,解决 Node.js ESM 环境下的兼容性问题
此修复解决了在 Node.js ESM 环境(如游戏服务端)中使用
scene.isServer时报错ReferenceError: require is not defined的问题。 - 新增
2.7.0
Minor Changes
-
#398
1f3a76aThanks @esengine! - feat(ecs): 添加运行时环境区分机制 | add runtime environment detection新增功能:
Core新增静态属性runtimeEnvironment,支持'server' | 'client' | 'standalone'Core新增isServer/isClient静态只读属性ICoreConfig新增runtimeEnvironment配置项Scene新增isServer/isClient只读属性(默认从 Core 继承,可通过 config 覆盖)- 新增
@ServerOnly()/@ClientOnly()/@NotServer()/@NotClient()方法装饰器
用于网络游戏中区分服务端权威逻辑和客户端逻辑:
// 方式1: 全局设置(推荐) Core.create({ runtimeEnvironment: 'server' }); // 或直接设置静态属性 Core.runtimeEnvironment = 'server'; // 所有场景自动继承 const scene = new Scene(); console.log(scene.isServer); // true // 方式2: 单个场景覆盖(可选) const clientScene = new Scene({ runtimeEnvironment: 'client' }); // 在系统中检查环境 class CollectibleSpawnSystem extends EntitySystem { private checkCollections(): void { if (!this.scene.isServer) return; // 客户端跳过 // ... 服务端权威逻辑 } }
2.6.1
Patch Changes
-
#396
04b08f3Thanks @esengine! - fix(ecs): COMPONENT_ADDED 事件添加 entity 字段修复
ECSEventType.COMPONENT_ADDED事件缺少entity字段的问题,导致 ECSRoom 的@NetworkEntity自动广播功能报错。
2.6.0
Minor Changes
-
feat(ecs): 添加 @NetworkEntity 装饰器,支持自动广播实体生成/销毁
新功能
@NetworkEntity 装饰器
- 标记组件为网络实体,自动广播 spawn/despawn 消息
- 支持
autoSpawn和autoDespawn配置选项 - 通过事件系统(
ECSEventType.COMPONENT_ADDED/ECSEventType.ENTITY_DESTROYED)实现
ECSRoom 增强
- 新增
enableAutoNetworkEntity配置选项(默认启用) - 自动监听组件添加和实体销毁事件
- 简化 GameRoom 实现,无需手动回调
改进
Entity 事件
Entity.destroy()现在发出entity:destroyed事件Entity.active变化时发出entity:enabled/entity:disabled事件- 使用
ECSEventType常量替代硬编码字符串
使用示例
import { Component, ECSComponent, sync, NetworkEntity } from '@esengine/ecs-framework'; @ECSComponent('Enemy') @NetworkEntity('Enemy') class EnemyComponent extends Component { @sync('float32') x: number = 0; @sync('float32') y: number = 0; } // 服务端 const entity = scene.createEntity('Enemy'); entity.addComponent(new EnemyComponent()); // 自动广播 spawn entity.destroy(); // 自动广播 despawn
2.5.1
Patch Changes
-
#392
a08a84bThanks @esengine! - fix(sync): Decoder 现在使用 GlobalComponentRegistry 查找组件 | Decoder now uses GlobalComponentRegistry for component lookup问题 | Problem:
Decoder.ts有自己独立的componentRegistryMap,与GlobalComponentRegistry完全分离。这导致通过@ECSComponent装饰器注册的组件在网络反序列化时找不到,产生 "Unknown component type" 错误。@sync装饰器使用constructor.name作为typeId,而不是@ECSComponent装饰器指定的名称,导致编码和解码使用不同的类型 ID。Decoder.tshad its own localcomponentRegistryMap that was completely separate fromGlobalComponentRegistry. This caused components registered via@ECSComponentdecorator to not be found during network deserialization, resulting in "Unknown component type" errors.@syncdecorator usedconstructor.nameastypeIdinstead of the name specified by@ECSComponentdecorator, causing encoding and decoding to use different type IDs.
修改 | Changes:
- 从 Decoder.ts 中移除本地
componentRegistry - 更新
decodeEntity和decodeSpawn使用GlobalComponentRegistry.getComponentType() - 移除已废弃的
registerSyncComponent和autoRegisterSyncComponent函数 - 更新
@sync装饰器使用getComponentTypeName()获取组件类型名称 - 更新
@ECSComponent装饰器同步更新SYNC_METADATA.typeId - Removed local
componentRegistryfrom Decoder.ts - Updated
decodeEntityanddecodeSpawnto useGlobalComponentRegistry.getComponentType() - Removed deprecated
registerSyncComponentandautoRegisterSyncComponentfunctions - Updated
@syncdecorator to usegetComponentTypeName()for component type name - Updated
@ECSComponentdecorator to sync updateSYNC_METADATA.typeId
现在使用
@ECSComponent装饰器的组件会自动可用于网络同步解码,无需手动注册。Now
@ECSComponentdecorated components are automatically available for network sync decoding without any manual registration.
2.5.0
Minor Changes
-
#390
1f297acThanks @esengine! - feat: ECS 网络状态同步系统@esengine/ecs-framework
新增
@sync装饰器和二进制编解码器,支持基于 Component 的网络状态同步:import { Component, ECSComponent, sync } from '@esengine/ecs-framework'; @ECSComponent('Player') class PlayerComponent extends Component { @sync('string') name: string = ''; @sync('uint16') score: number = 0; @sync('float32') x: number = 0; @sync('float32') y: number = 0; }新增导出
sync- 标记需要同步的字段装饰器SyncType- 支持的同步类型SyncOperation- 同步操作类型(FULL/DELTA/SPAWN/DESPAWN)encodeSnapshot/decodeSnapshot- 批量编解码encodeSpawn/decodeSpawn- 实体生成编解码encodeDespawn/processDespawn- 实体销毁编解码ChangeTracker- 字段级变更追踪initChangeTracker/clearChanges/hasChanges- 变更追踪工具函数
内部方法标记
将以下方法标记为
@internal,用户应通过Core.update()驱动更新:Scene.update()SceneManager.update()WorldManager.updateAll()
@esengine/network
新增
ComponentSyncSystem,基于@sync装饰器自动同步组件状态:import { ComponentSyncSystem } from '@esengine/network'; // 服务端:编码状态 const data = syncSystem.encodeAllEntities(false); // 客户端:解码状态 syncSystem.applySnapshot(data);修复
- 将
@esengine/ecs-framework从 devDependencies 移到 peerDependencies
@esengine/server
新增
ECSRoom,带有 ECS World 支持的房间基类:import { ECSRoom } from '@esengine/server/ecs'; // 服务端启动 Core.create(); setInterval(() => Core.update(1 / 60), 16); // 定义房间 class GameRoom extends ECSRoom { onCreate() { this.addSystem(new PhysicsSystem()); } onJoin(player: Player) { const entity = this.createPlayerEntity(player.id); entity.addComponent(new PlayerComponent()); } }设计
- 每个
ECSRoom在Core.worldManager中创建独立的 World Core.update()统一更新 Time 和所有 WorldonTick()只处理状态同步逻辑