Files
esengine/packages/engine-core/src/ModuleManifest.ts
YHH beaa1d09de feat: 预制体系统与架构改进 (#303)
* feat(prefab): 实现预制体系统和编辑器 UX 改进

## 预制体系统
- 新增 PrefabSerializer: 预制体序列化/反序列化
- 新增 PrefabInstanceComponent: 追踪预制体实例来源和修改
- 新增 PrefabService: 预制体核心服务
- 新增 PrefabLoader: 预制体资产加载器
- 新增预制体命令: Create/Instantiate/Apply/Revert/BreakLink

## 预制体编辑模式
- 支持双击 .prefab 文件进入编辑模式
- 预制体编辑模式工具栏 (保存/退出)
- 预制体实例指示器和操作菜单

## 编辑器 UX 改进
- SceneHierarchy 快捷键: F2 重命名, Ctrl+D 复制, ↑↓ 导航
- 支持双击实体名称内联编辑
- 删除实体时显示子节点数量警告
- 右键菜单添加重命名/复制选项及快捷键提示
- 布局持久化和重置功能

## Bug 修复
- 修复 editor-runtime 组件类重复导致的 TransformComponent 不识别问题
- 修复 .prefab-name 样式覆盖导致预制体工具栏文字不可见
- 修复 Inspector 资源字段高度不正确问题

* feat(editor): 改进编辑器 UX 交互体验

- ContentBrowser: 加载动画 spinner、搜索高亮、改进空状态设计
- SceneHierarchy: 选中项自动滚动到视图、搜索清除按钮
- PropertyInspector: 输入框本地状态管理、Enter/Escape 键处理
- EntityInspector: 组件折叠状态持久化、属性搜索清除按钮
- Viewport: 变换操作实时数值显示
- 国际化: 添加相关文本 (en/zh)

* fix(build): 修复 Web 构建资产加载和编辑器 UX 改进

构建系统修复:
- 修复 asset-catalog.json 字段名不匹配 (entries vs assets)
- 修复 BrowserFileSystemService 支持两种目录格式
- 修复 bundle 策略检测逻辑 (空对象判断)
- 修复 module.json 中 assetExtensions 声明和类型推断

行为树修复:
- 修复 BehaviorTreeExecutionSystem 使用 loadAsset 替代 loadAssetByPath
- 修复 BehaviorTreeAssetType 常量与 module.json 类型名一致 (behavior-tree)

编辑器 UX 改进:
- 构建完成对话框添加"打开文件夹"按钮
- 构建完成对话框样式优化 (圆形图标背景、按钮布局)
- SceneHierarchy 响应式布局 (窄窗口自动隐藏 Type 列)
- SceneHierarchy 隐藏滚动条

错误追踪:
- 添加全局错误处理器写入日志文件 (%TEMP%/esengine-editor-crash.log)
- 添加 append_to_log Tauri 命令

* feat(render): 修复 UI 渲染和点击特效系统

## UI 渲染修复
- 修复 GUID 验证 bug,使用统一的 isValidGUID() 函数
- 修复 UI 渲染顺序随机问题,Rust 端使用 IndexMap 替代 HashMap
- Web 运行时添加 assetPathResolver 支持 GUID 解析
- UIInteractableComponent.blockEvents 默认值改为 false

## 点击特效系统
- 新增 ClickFxComponent 和 ClickFxSystem
- 支持在点击位置播放粒子效果
- 支持多种触发模式和粒子轮换

## Camera 系统重构
- CameraSystem 从 ecs-engine-bindgen 移至 camera 包
- 新增 CameraManager 统一管理相机

## 编辑器改进
- 改进属性面板 UI 交互
- 粒子编辑器面板优化
- Transform 命令系统

* feat(render): 实现 Sorting Layer 系统和 Overlay 渲染层

- 新增 SortingLayerManager 管理排序层级 (Background, Default, Foreground, UI, Overlay)
- 实现 ISortable 接口,统一 Sprite、UI、Particle 的排序属性
- 修复粒子 Overlay 层被 UI 遮挡问题:添加独立的 Overlay Pass 在 UI 之后渲染
- 更新粒子资产格式:从 sortingOrder 改为 sortingLayer + orderInLayer
- 更新粒子编辑器面板支持新的排序属性
- 优化 UI 渲染系统使用新的排序层级

* feat(ci): 集成 SignPath 代码签名服务

- 添加 SignPath 自动签名工作流(Windows)
- 配置 release-editor.yml 支持代码签名
- 将构建改为草稿模式,等待签名完成后发布
- 添加证书文件到 .gitignore 防止泄露

* fix(asset): 修复 Web 构建资产路径解析和全局单例移除

## 资产路径修复
- 修复 Tauri 本地服务器 `/asset?path=...` 路径解析,正确与 root 目录连接
- BrowserPathResolver 支持两种模式:
  - 'proxy': 使用 /asset?path=... 格式(编辑器 Run in Browser)
  - 'direct': 使用直接路径 /assets/path.png(独立 Web 构建)
- BrowserRuntime 使用 'direct' 模式,无需 Tauri 代理

## 架构改进 - 移除全局单例
- 移除 globalAssetManager 导出,改用 AssetManagerToken 依赖注入
- 移除 globalPathResolver 导出,改用 PathResolutionService
- 移除 globalPathResolutionService 导出
- ParticleUpdateSystem/ClickFxSystem 通过 setAssetManager() 注入依赖
- EngineService 使用 new AssetManager() 替代全局实例

## 新增服务
- PathResolutionService: 统一路径解析接口
- RuntimeModeService: 运行时模式查询服务
- SerializationContext: EntityRef 序列化上下文

## 其他改进
- 完善 ServiceToken 注释说明本地定义的意图
- 导出 BrowserPathResolveMode 类型

* fix(build): 添加 world-streaming composite 设置修复类型检查

* fix(build): 移除 world-streaming 引用避免 composite 冲突

* fix(build): 将 const enum 改为 enum 兼容 isolatedModules

* fix(build): 添加缺失的 IAssetManager 导入
2025-12-13 19:44:08 +08:00

302 lines
9.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Module Manifest Types.
* 模块清单类型定义。
*
* This is the single source of truth for module/plugin configuration.
* Each engine module should have a module.json file containing this information.
* 这是模块/插件配置的唯一数据源。
* 每个引擎模块应该有一个包含此信息的 module.json 文件。
*/
/**
* Module category for organization in UI.
* 用于 UI 组织的模块分类。
*/
export type ModuleCategory =
| 'Core'
| 'Rendering'
| 'Physics'
| 'AI'
| 'Audio'
| 'Networking'
| 'Other';
/**
* Platform requirements for the module.
* 模块的平台要求。
*/
export type ModulePlatform = 'web' | 'desktop' | 'mobile';
/**
* Module exports definition.
* 模块导出定义。
*/
export interface ModuleExports {
/** Exported component classes | 导出的组件类 */
components?: string[];
/** Exported system classes | 导出的系统类 */
systems?: string[];
/** Exported asset loaders | 导出的资源加载器 */
loaders?: string[];
/** Other exported items | 其他导出项 */
other?: string[];
}
/**
* Module manifest definition (Unified Plugin/Module config).
* 模块清单定义(统一的插件/模块配置)。
*
* This interface matches the structure of module.json files.
* 此接口匹配 module.json 文件的结构。
*/
export interface ModuleManifest {
// ==================== Core Identifiers ====================
/** Unique module identifier | 唯一模块标识符 */
id: string;
/** Package name (npm style) | 包名npm 风格) */
name: string;
/** Display name for UI | UI 显示名称 */
displayName: string;
/** Module description | 模块描述 */
description: string;
/** Module version | 模块版本 */
version: string;
// ==================== Classification ====================
/** Category for grouping in UI | UI 分组分类 */
category: ModuleCategory;
/** Tags for search and filtering | 用于搜索和过滤的标签 */
tags?: string[];
/** Icon name (Lucide icon) | 图标名Lucide 图标) */
icon?: string;
// ==================== Lifecycle ====================
/** Whether this is a core module (cannot be disabled) | 是否为核心模块(不能禁用) */
isCore: boolean;
/** Whether enabled by default in new projects | 新项目中是否默认启用 */
defaultEnabled: boolean;
/** Whether this is an engine built-in module | 是否为引擎内置模块 */
isEngineModule?: boolean;
// ==================== Content ====================
/** Whether this module can contain content/assets | 是否可以包含内容/资源 */
canContainContent?: boolean;
/** Platform requirements | 平台要求 */
platforms?: ModulePlatform[];
// ==================== Dependencies ====================
/** Module IDs this module depends on | 此模块依赖的模块 ID */
dependencies: string[];
/**
* External package dependencies that need to be included in import map.
* 需要包含在 import map 中的外部包依赖。
*
* These are runtime dependencies that are dynamically imported by the module.
* 这些是模块动态导入的运行时依赖。
*
* Example: ["@esengine/rapier2d"]
*/
externalDependencies?: string[];
// ==================== Exports ====================
/** Exported items for dependency checking | 导出项用于依赖检查 */
exports: ModuleExports;
// ==================== Asset Configuration ====================
// ==================== 资产配置 ====================
/**
* Asset file extensions supported by this module.
* 此模块支持的资产文件扩展名。
*
* Used by build pipeline to determine which files to copy and their types.
* 构建管线使用此配置决定复制哪些文件及其类型。
*
* Example:
* ```json
* {
* "assetExtensions": {
* ".particle": "particle",
* ".particle.json": "particle",
* ".btree": "behavior-tree"
* }
* }
* ```
*/
assetExtensions?: Record<string, string>;
// ==================== Editor Integration ====================
/**
* Associated editor package name.
* 关联的编辑器包名。
* e.g., "@esengine/tilemap-editor" for "@esengine/tilemap"
*/
editorPackage?: string;
// ==================== Performance (auto-calculated at build time) ====================
// ==================== 性能(构建时自动计算) ====================
/** JS bundle size in bytes | JS 包大小(字节) */
jsSize?: number;
/** Whether this module requires WASM | 是否需要 WASM */
requiresWasm?: boolean;
/** WASM file size in bytes | WASM 文件大小(字节) */
wasmSize?: number;
/**
* Unified WASM configuration for all WASM-related modules.
* 统一的 WASM 配置,用于所有 WASM 相关模块。
*
* This replaces the legacy wasmPaths, runtimeWasmPath, and wasmBindings fields.
* 此配置替代旧的 wasmPaths、runtimeWasmPath 和 wasmBindings 字段。
*/
wasmConfig?: {
/**
* List of WASM files to copy during build.
* 构建时需要复制的 WASM 文件列表。
*
* Each entry specifies source location and output destination.
* 每个条目指定源位置和输出目标。
*/
files: Array<{
/**
* Source file path relative to engine modules directory.
* 源文件路径,相对于引擎模块目录。
*
* Supports multiple candidate paths (first existing one is used).
* 支持多个候选路径(使用第一个存在的)。
*
* Example: ["rapier2d/pkg/rapier_wasm2d_bg.wasm", "rapier2d/rapier_wasm2d_bg.wasm"]
*/
src: string | string[];
/**
* Destination path relative to build output directory.
* 目标路径,相对于构建输出目录。
*
* Example: "wasm/rapier_wasm2d_bg.wasm" or "libs/es-engine/es_engine_bg.wasm"
*/
dst: string;
}>;
/**
* Runtime WASM path for dynamic loading (used by JS code at runtime).
* 运行时 WASM 路径用于动态加载JS 代码在运行时使用)。
*
* This is the path that runtime code uses to fetch the WASM file.
* 这是运行时代码用来获取 WASM 文件的路径。
*
* Example: "wasm/rapier_wasm2d_bg.wasm"
*/
runtimePath?: string;
/**
* Whether this is the core engine WASM module.
* 是否是核心引擎 WASM 模块。
*
* The core engine WASM (e.g., es_engine) must be initialized first
* before the runtime can start. Only one module should have this flag.
* 核心引擎 WASM如 es_engine必须在运行时启动前首先初始化。
* 只有一个模块应该设置此标志。
*/
isEngineCore?: boolean;
};
// ==================== Build Configuration ====================
// ==================== 构建配置 ====================
/**
* Output path for the built module file.
* 构建后模块文件的输出路径。
*
* Example: "dist/index.mjs"
*/
outputPath?: string;
/**
* Plugin export name for dynamic loading.
* 用于动态加载的插件导出名。
*
* Example: "SpritePlugin"
*/
pluginExport?: string;
/**
* Additional files to include when copying module.
* 复制模块时需要包含的额外文件。
*
* Glob patterns relative to the module's dist directory.
* 相对于模块 dist 目录的 glob 模式。
*
* Example: ["chunk-*.js", "worker.js"]
*/
includes?: string[];
// ==================== Build Pipeline Configuration ====================
// ==================== 构建管线配置 ====================
/**
* Core service exports that should be explicitly exported first.
* 需要显式优先导出的核心服务。
*
* Used to avoid naming conflicts when re-exporting modules.
* 用于避免重新导出模块时的命名冲突。
*
* Example: ["createServiceToken", "PluginServiceRegistry"]
*/
coreServiceExports?: string[];
/**
* Whether this module is the runtime entry point (provides default export).
* 此模块是否为运行时入口点(提供默认导出)。
*
* Only one module should have this set to true (typically platform-web).
* 只有一个模块应该设置为 true通常是 platform-web
*/
isRuntimeEntry?: boolean;
/**
* Standard entry file names to search for user scripts.
* 用于搜索用户脚本的标准入口文件名。
*
* Build pipeline will try these files in order.
* 构建管线将按顺序尝试这些文件。
*
* Example: ["index.ts", "main.ts", "game.ts"]
*/
userScriptEntries?: string[];
/**
* Additional external packages that user scripts might import.
* 用户脚本可能导入的额外外部包。
*
* These packages will be marked as external during bundling.
* 这些包在打包时将被标记为外部依赖。
*
* Example: ["@esengine/ecs-framework", "@esengine/core"]
*/
userScriptExternals?: string[];
}