跳转到内容

v0.12.1

Sprite 平铺

Sprite 组件新增 tileSizetileSpacing 属性,支持纹理重复平铺:

  • 设置 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_statuslist_recent_projectslist_examplesopen_projectcreate_from_example
  • 新增 MCP 构建工具:build_project(触发 playable/wechat 构建)和 list_build_configs(查询可用构建配置)
  • LauncherBridge 处理项目管理工具;编辑器模式工具在首次调用时延迟发现编辑器

统一脚本编译

脚本编译统一为单一 ScriptCompiler 类,合并了此前两套分散的 VirtualFS 插件和 SDK 解析策略:

  • Play Mode 使用 esbuild context 增量编译
  • 构建导出使用单次编译
  • 提取 scriptDiscovery.ts 打破 ScriptLoaderScriptCompiler 的循环依赖

SDK 核心拆分

App 瘦身

app.ts 从 1090 行减少到 729 行,提取了相机系统和数学工具:

  • CameraPlugincamera/CameraPlugin.ts):多相机收集、正交/透视投影、Canvas 缩放模式适配和渲染系统现在是独立插件
  • mat4math/mat4.ts):orthoperspectiveinvertTranslationmultiply 提取为纯函数,带 Float32Array 对象池
  • createWebApp() 变为纯组装函数——只做插件注册,不再内联系统定义

World 门面重构

world.ts 从 1101 行减少到 674 行,拆分为 5 个聚焦内部类:

模块职责
ecs/BuiltinBridgeC++ Registry 方法缓存、ptr 布局直读直写、颜色格式转换
ecs/ScriptStorageTypeScript Map 组件存储、实体-组件追踪
ecs/NameIndex双向名称-实体索引
ecs/ChangeTracker基于 tick 的 added/changed/removed 检测
ecs/QueryCache缓存实体查询,支持组件级失效

所有 World 公开 API 签名保持不变——拆分是内部的(Facade 模式)。

AppContext 替代 globalThis

3 个 globalThis.__esengine_* 隐式耦合点被替换为显式 AppContext

  • getDefaultContext().componentRegistry 替代 globalThis.__esengine_componentRegistry
  • getDefaultContext().pendingSystems 替代 globalThis.__esengine_pendingSystems
  • getDefaultContext().editorBridge 替代 globalThis.__esengine_registerComponent

支持多 App 实例隔离,测试时通过 setDefaultContext() 清理状态。

组件级查询缓存

查询缓存此前在任何实体变更时全部失效。现在每个缓存条目追踪其依赖的组件类型,仅在相关组件变更时失效。

编辑器架构

EditorEventBus

新的类型化发布-订阅事件总线替代 EditorStore 上的 6 套手动监听器:

  • emit() 立即投递,用于结构性变更
  • emitBatched() 通过 requestAnimationFrame 批量投递——同一帧内的同类事件合并(最后一次写入生效)
  • 事件类型:selection:changedscene:syncedproperty:changedhierarchy:changedentity:lifecyclecomponent:changedvisibility:changedtiletool:changedgizmo: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,导致 loadTextureloadMaterialloadFontloadSpine 等 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 中移除 worldPositionworldRotationworldScale 显示——这些是系统计算的只读值