v0.12.1
Sprite 平铺
Sprite 组件新增 tileSize 和 tileSpacing 属性,支持纹理重复平铺:
- 设置
tileSize为期望的 tile 尺寸(如{x: 64, y: 64}),纹理会重复填满 Sprite 的size区域 - 设置
tileSpacing在 tile 之间添加间距(如{x: 4, y: 4}),该字段仅在tileSize非零时出现在 Inspector 中 - 两种模式均生成 N×M 个四边形,通过批处理系统自动合并为单次 draw call
- 支持精灵翻转和锚点设置
启动页 MCP
MCP 工具现在在打开项目前即可使用:
- Bridge 服务器在 Tauri
setup()阶段启动,早于前端加载 - 启动页新增 MCP 工具:
get_editor_status、list_recent_projects、list_examples、open_project、create_from_example - 新增 MCP 构建工具:
build_project(触发 playable/wechat 构建)和list_build_configs(查询可用构建配置) LauncherBridge处理项目管理工具;编辑器模式工具在首次调用时延迟发现编辑器
统一脚本编译
脚本编译统一为单一 ScriptCompiler 类,合并了此前两套分散的 VirtualFS 插件和 SDK 解析策略:
- Play Mode 使用 esbuild context 增量编译
- 构建导出使用单次编译
- 提取
scriptDiscovery.ts打破ScriptLoader与ScriptCompiler的循环依赖
SDK 核心拆分
App 瘦身
app.ts 从 1090 行减少到 729 行,提取了相机系统和数学工具:
- CameraPlugin(
camera/CameraPlugin.ts):多相机收集、正交/透视投影、Canvas 缩放模式适配和渲染系统现在是独立插件 - mat4(
math/mat4.ts):ortho、perspective、invertTranslation、multiply提取为纯函数,带 Float32Array 对象池 createWebApp()变为纯组装函数——只做插件注册,不再内联系统定义
World 门面重构
world.ts 从 1101 行减少到 674 行,拆分为 5 个聚焦内部类:
| 模块 | 职责 |
|---|---|
ecs/BuiltinBridge | C++ Registry 方法缓存、ptr 布局直读直写、颜色格式转换 |
ecs/ScriptStorage | TypeScript Map 组件存储、实体-组件追踪 |
ecs/NameIndex | 双向名称-实体索引 |
ecs/ChangeTracker | 基于 tick 的 added/changed/removed 检测 |
ecs/QueryCache | 缓存实体查询,支持组件级失效 |
所有 World 公开 API 签名保持不变——拆分是内部的(Facade 模式)。
AppContext 替代 globalThis
3 个 globalThis.__esengine_* 隐式耦合点被替换为显式 AppContext:
getDefaultContext().componentRegistry替代globalThis.__esengine_componentRegistrygetDefaultContext().pendingSystems替代globalThis.__esengine_pendingSystemsgetDefaultContext().editorBridge替代globalThis.__esengine_registerComponent
支持多 App 实例隔离,测试时通过 setDefaultContext() 清理状态。
组件级查询缓存
查询缓存此前在任何实体变更时全部失效。现在每个缓存条目追踪其依赖的组件类型,仅在相关组件变更时失效。
编辑器架构
EditorEventBus
新的类型化发布-订阅事件总线替代 EditorStore 上的 6 套手动监听器:
emit()立即投递,用于结构性变更emitBatched()通过requestAnimationFrame批量投递——同一帧内的同类事件合并(最后一次写入生效)- 事件类型:
selection:changed、scene:synced、property:changed、hierarchy:changed、entity:lifecycle、component:changed、visibility:changed、tiletool:changed、gizmo:requested
Store 拆分
EditorStore 拆分为聚焦的独立 Store:
- SelectionStore:实体/资源选择状态、焦点追踪
- TileToolStore:Tile 笔刷工具、图章、翻转状态
- EditorStore(瘦身后):场景数据、命令历史、世界变换缓存——通知全部走 EventBus
所有 Store 注册到 IoC 容器,使用类型化 token。
增量同步
编辑器属性编辑现在使用字段级 WASM 直写,而非整个组件重新添加:
- 利用
PTR_LAYOUTS直接写入HEAPF32/HEAPU32/HEAPU8中的单个字段 - Transform 拖拽操作只写
position.x/y/z(3 个 float),而非完整的 20+ 字段组件 - 没有 ptr 布局的组件回退到完整组件同步
构建管线
- WASM 构建缓存哈希校验:缓存现在计算所有 C++/HPP 源文件和
CMakeLists.txt的哈希值,在源码变更时失效,而非仅检查输出文件是否存在 - 引擎源码解析:开发模式现在优先使用项目根目录的
src/esengine/,而非过时的 toolchain 副本,确保新组件被包含在构建中 - Toolchain 清单:在
toolchain.manifest.json中添加 yoga 库,支持 UILayoutSystem 的 flex 布局 - Playable 构建修复:用 SDK 的
uiPlugins数组(唯一数据源)替代硬编码的COMPONENT_TO_PLUGIN映射(缺少 10+ 组件)
Bug 修复
- 修复
Assets.baseUrl未传播到HttpBackend,导致loadTexture、loadMaterial、loadFont、loadSpine等 Loader 方法忽略 baseUrl——此前仅fetchJson有效 - 修复
Assets.fetchJson/fetchText/fetchBinary未通过baseUrl解析相对路径,导致 Play Mode 中 Tauri 的 JSON 加载失败 - 修复
HttpBackend.resolveUrl仅识别http:///https://——现在支持asset://、blob://等 URI scheme - 修复
UIRenderOrderPlugin强制要求安装CollectionView插件——执行顺序已通过系统级runBefore/runAfter保证 - 修复 WASM toolchain 同步拷贝了根目录的
CMakeLists.txt(引用了不可用的 yogacore 源码) - 修复新增组件到
WebBindings.generated.cpp后 WASM 构建缓存未失效 - 修复 Assets API 文档引用了不存在的
loadJson/loadText/loadBinary方法(实际 API 为fetchJson/fetchText/fetchBinary) - 修复 Sprite 无间隔平铺(
tileSpacing = 0)只渲染一个 tile——纹理默认为ClampToEdge,改为两种模式统一使用 quad 平铺 - 修复 Inspector 的
visibleWhen/hiddenWhen规则在控制属性变化时不会动态更新——此前需要取消选中再重新选中实体 - Transform Inspector 中移除
worldPosition、worldRotation、worldScale显示——这些是系统计算的只读值