UGC2.0经验补全:基建、跨端、创作运行时与源码复盘

自动关联目录:UGC2.0经验补全:基建、跨端、创作运行时与源码复盘

这篇是 UGC2.0 的完整技术底座,不是最终背诵稿。它一方面还原本人直接做过的页面协议、原生宿主、制品、多端构建和自动化;另一方面把对象模型、三 VM、编辑/试玩运行时、网络、云资产和玩法能力补成系统架构。两部分必须使用不同主语。

一、经验边界与时间边界

1.1 经验来源

层级定义可以怎么说典型范围
X1 直接交付有个人提交、设计、联调或交付证据我负责、我设计并实现PixUI 页面协议与宿主、制品构建、多端出包、UI 自动化
X2 项目内参与接过上下游、做过适配或排障我参与、我负责其中的……元件管理 UI 联调、材质二进制化、试玩发布恢复、AI 编辑器集成
X3 源码复盘团队平台能力,本人结合当前源码补全团队系统、我复盘后的理解Instance 对象模型、三 VM、完整编辑运行时、网络复制、云资产、技能与行为系统

1.2 时间口径

  • 2026.08 - 2026.10 是本人以 UGC2.0 基建为工作重心的阶段。
  • Web/PixUI 经验在 2026.06 起已经积累,与 UGC2.0 有技术连续性,但不能把所有 Web 业务页面都算作 UGC2.0。
  • 当前源码仍在快速演进。页面框架、多端构建和自动化与本人时间窗口直接重合;多关卡、完整三 VM 和部分运行时能力需要逐项区分当期版本与后续演进。

1.3 一句话口径

我在 UGC2.0 直接负责的核心不是一个页面,而是页面运行基础设施、内容制品和跨端交付三块:把 TypeScript 页面、Lua 编辑服务和 C++ PixUI 宿主之间的协议与生命周期补完整;把 JSON/二进制转换和 ArtifactBuilder 接进保存发布;再打通 Android、iOS、自动化和 UI 可测试性。对象模型、三 VM、运行时网络和完整玩法能力属于团队平台,我已经基于源码补全,但不会说成个人独立设计。

二、UGC2.0 的产品与技术本质

UGC1.0 以受控元件和属性配置为主要表达单元;UGC2.0 更进一步,需要提供接近“可编程世界运行时”的统一基础。它至少同时是:

  1. 对象系统:用统一 Instance 树表达场景、服务、角色、脚本和 UI。
  2. 创作 IDE:对象树、属性、Gizmo、脚本、预制体、撤销和调试共同工作。
  3. 多角色运行时:编辑、客户端试玩和服务端试玩拥有独立 VM 与生命周期。
  4. 内容编译链:作者源经过冻结、校验、转换、制品化和发布,成为可验证的运行输入。
  5. 跨端宿主:PC、Android、iOS 和其他目标在不同能力边界下使用同一内容语义。
  6. 平台生态:对象、脚本、资产和运行时 API 必须支持权限、版本、安全和长期兼容。

完整闭环:

创建工程
  -> Instance 树与资产初始化
  -> 场景 / 属性 / 脚本 / UI 编辑
  -> 撤销、保存、预制体和本地验证
  -> 冻结作者快照
  -> ArtifactBuilder 计划、转换、校验和提交
  -> 上传 / 发布 / 下载 / 缓存
  -> Client / Server VM 加载制品并试玩
  -> 自动化、日志和性能证据回流

三、总体架构

层核心职责关键边界
创作界面层React/TypeScript 页面、对象树、属性、工具栏、资源与脚本面板页面只持有展示状态,领域状态由运行时服务拥有
页面运行层页面注册、栈、生命周期、原生 PixUI 视图、消息协议逻辑页面与原生 View 分离;旧页面消息必须失效
编辑领域层选择、Gizmo、命令、事务、撤销、预制体和编辑服务所有修改走可审计命令或事务,不让 UI 直接改底层对象
对象与脚本层DataModel/Instance、属性、信号、Service、Luau、绑定稳定身份、反射契约、VM 隔离和安全 API
Play 运行层Client/Server VM、场景、角色、技能、行为、网络和多关卡编辑态与试玩态不共享活对象;服务端保持权威
内容与资产层JSON、FlatBuffers、QZBIN、Prefab、Bundle、云资产作者源与发布制品分离;格式版本与语义版本分离
构建与交付层ArtifactBuilder、多端构建、发布下载、缓存和预加载不可变输入、确定性输出、失败无半成品、全链可验证
质量与运维层UI 自动化、白盒、日志、性能、兼容和诊断测试使用稳定语义标识;每层留下可关联证据

五条主链:

  • 编辑链:输入 -> 页面命令 -> Lua 编辑服务 -> 编辑事务 -> Instance 树 -> 页面状态更新。
  • 页面链:逻辑路由 -> 原生 View -> 页面上下文 -> 订阅领域 -> suspend/resume/dispose。
  • 运行链:作者快照 -> 制品 -> Client/Server VM -> 场景与服务 -> 网络游玩。
  • 交付链:Inventory -> Processor DAG -> 事务输出 -> Manifest -> Verify -> 发布。
  • 质量链:协议测试 -> 浏览器组件测试 -> UE 自动化 -> 真机构建与运行证据。

四、完整模块图谱

4.1 对象模型与编辑内核

模块层级业务价值实现与追问点
DataModel/Instance 树X3用统一层级表达世界和服务稳定 ObjectId、父子关系、类信息、销毁语义、遍历
Class 与继承X3给创作者稳定的能力分类类注册、继承检查、默认对象、版本、API 暴露
Property 与 AttributeX2/X3统一属性编辑、脚本访问和序列化元数据、类型转换、只读、默认值、变更信号
Signal/EventX3让对象和服务低耦合协作连接句柄、解绑、错误隔离、跨 VM/网络边界
ServiceProviderX3通过服务而非全局变量访问平台能力服务注册、角色准入、生命周期、测试替身
对象身份与引用X3支持保存、复制、撤销和跨文件引用ID 生成、引用解析、悬空引用、重映射
SceneSubsystemX3向不同 VM 提供当前 World 的场景门面绑定注入、角色差异、World 清理、事件桥接
选择与 OutlinerX2/X3连接视口对象与编辑器树选中唯一权威、多选、深层节点、对象销毁
Gizmo 与变换X2/X3提供移动、旋转和缩放拖拽事务、坐标空间、吸附、输入穿透
属性面板X1/X2基于元数据编辑不同类型对象Schema 驱动、批量值、混合态、校验、提交节流
Undo/事务X3保证创作操作可逆和可组合事务边界、对象快照、嵌套、回滚、脏标记
Prefab 与自定义类X2/X3复用对象结构与能力模板身份、实例覆盖、依赖、升级、断链
编辑态脚本X3让工具和对象在编辑时执行逻辑准入 API、事件、资源预算、与试玩隔离
插件平台X3扩展创作工具而不侵入核心生命周期、权限、API 版本、故障隔离

4.2 VM、脚本与网络运行时

模块层级业务价值实现与追问点
Edit VMX2/X3承载作者脚本和编辑服务绑定编辑 World、进入试玩前释放、返回后重建
Client VMX3承载本机玩家运行逻辑和表现当前 Client World 生命周期、travel 清理、重建
Server VMX3承载 DS 权威玩法独立进程、权威状态、资源准入、服务端 API
VM 工厂与 generationX3防止旧 VM 回调污染新世界角色、owner、递增代际、进程互斥、关闭屏障
Lua/Luau 绑定X2/X3将 C++ 引擎能力暴露为脚本 APIC 闭包、userdata、类型检查、所有权、析构
沙箱与 API 治理X3在开放编程能力下控制安全和兼容白名单、配额、权限、API 版本、错误隔离
IRPCX3支持 Client/Server 脚本远程调用端点、序列化、异步 future、上下文、状态码
FlatBuffers/Protobuf 适配X2/X3跨语言传递结构化数据Schema、宽整数、拷贝边界、兼容、大小限制
复制与属性同步X3保持多端对象状态一致权威、相关性、初始快照、增量版本、Dormancy
PlaySession 编排X3启动 DS/Client、切换 VM 并恢复编辑纯值上下文、进程管理、超时、统一退出事务
多关卡与 TeleportX3支持运行时跨世界和多实例目标身份、载荷、预检、handoff、失败回源
跨 World 状态X3在 World/VM 被销毁期间保留必要信息GameInstance 纯值、不得持有 Lua/World 引用

“三 VM”指三种角色,不代表三个 VM 同时存在于一个进程。编辑宿主加入试玩时,Edit VM 必须先释放,Client VM 才能创建;Server VM 位于独立 DS。这个边界是生命周期和安全模型,不只是目录拆分。

4.3 PixUI、页面与编辑器前端

模块层级业务价值实现与追问点
TypeScript/React 应用壳X1统一启动、依赖和页面装配bootstrap、错误边界、状态 owner、可测试入口
组件与平台边界X1隔离 PixUI 与标准浏览器差异adapter、受支持 DOM、输入、布局、降级
页面 Manifest/RegistryX1用逻辑名而非文件路径路由页面entry、mode、layer、恢复策略、路径安全
PageManagerX1管理 replace、push、overlay 和返回栈pageId、generation、顺序、覆盖、恢复
NativePageHostX1独占 PixUI View 的创建和销毁viewId、z-order、visible、interactive、幂等释放
页面上下文注入X1给每个 JS 上下文稳定身份PageId、PageGeneration、平台、模式、DPI
Bridge TransportX1为 TS 提供类型化 send/subscribe消息类型、payload、unsubscribe、兼容层
MessageRouterX1把消息路由到页面和领域页面过滤、订阅作用域、domain 映射、释放
PageRuntimeClientX1管理快照、增量和续订domain revision、旧消息拒绝、resume、dispose
帧调度与合并X1避免高频状态压垮 JS/渲染keyed scheduler、同帧合并、优先级、指标
PixUI CLI/PFBSX1标准化开发、构建和运行时页面dev/build、固定产物、转换器、缓存、可重复
浏览器预览X1缩短 UI 开发反馈周期mock transport、显式开发会话、环境隔离
输入与场景门控X1/X2防止点击 UI 同时操作 3D 视口hover、focus、modal、同步矩形、C++ 前置拦截
PixUI 兼容组件X1处理非标准 DOM/布局行为可控组件、重挂载、事件回退、焦点和文本刷新

4.4 数据、制品与资产

模块层级业务价值实现与追问点
作者态 JSONX2/X3保留可编辑、可诊断的源数据Canonical 输出、未知字段、格式版本、迁移
FlatBuffers SchemaX1/X2提供紧凑、可校验的运行格式typed fields、扩展字段、默认值、Schema 演进
QZBIN 容器X1/X2封装二进制条目和压缩entry、版本、压缩、完整性、回读校验
TypeHintX1在通用资产链路中选择正确解码器类型枚举、材质变体、旧数据兼容、错误提示
JSON 批量转换X1迁移已有资产并验证覆盖扫描、幂等、dry-run、失败清单、回滚
保存时机控制X1避免编辑阶段被发布格式污染作者保存与发布保存分离、能力开关、版本
冻结快照X1/X2给制品构建提供不可变输入generation、文件清单、hash、临时目录、锁
Artifact InventoryX1建立受信输入和逻辑路径真实长度/hash、角色、owner、provider、路径安全
Processor DAGX1让不同内容处理器可组合claim、优先级、依赖、并行、稳定错误
构建事务X1防止失败留下可误用半成品私有工作目录、整层提交、取消、清理
Manifest 与 digestX1让制品身份可复现、可验证Canonical 排序、文件摘要、工具指纹、版本
VerifyX1独立确认产物未损坏或被替换文件集、hash、容器结构、格式和能力验证
Bundle/云资产X2/X3分发模型、材质、纹理和其他依赖内容身份、版本、缓存、依赖闭包、平台变体
角色/纹理预加载X1/X2降低首见卡顿静态依赖、材质贴图闭包、关键/后台优先级

4.5 多端构建、试玩与质量

模块层级业务价值实现与追问点
PC 编辑与试玩X1/X2提供开发和创作主入口编辑/试玩切换、子进程、资源 staging、恢复
Android 构建与游玩X1验证移动端真实内容运行工程生成、包体、设备安装、启动参数、日志
Android 调试工具X1降低真机定位成本设备选择、推包、拉日志、端口、错误归类
Android 发布/试玩恢复X1打通创作内容到真机试玩发布版本、下载、入口参数、回退、清理
iOS 构建X1建立签名、编译和交付流水线证书、Provision、远程构建、产物、设备验证
其他平台裁剪X2/X3让同一内容在能力不同的平台运行模块准入、无编辑目标、H5/小游戏边界、降级
构建配置与 BuildCellX1把本地步骤变为可复用流水线输入参数、环境探测、缓存、超时、退出码
白盒编排X1跨进程运行可重复端到端验证场景、步骤、证据目录、超时、报告
GAutomator 接入X1使用统一自动化驱动游戏和 UIprovider、命令、稳定定位、Shipping 准入
PixUI DOM 暴露X1让自动化看到语义节点而非像素DOM 树、稳定 ID、可见性、坐标、动作
浏览器组件测试X1快速验证前端状态和交互Vitest、Chromium、mock bridge、可重复 fixture
UE 自动化门禁X1验证真实 PixUI/原生宿主集成页面加载、消息、DOM、截图、性能证据
性能门禁X1/X2防止框架重构引入首帧和交互退化固定场景、帧耗、启动阶段、基线、证据归档

4.6 运行时内容能力

模块层级业务价值实现与追问点
角色/HumanoidX3给创作者统一角色抽象控制器、属性、状态、外观、网络身份
角色预设与外观X2/X3降低角色配置成本预设、覆盖、资源依赖、平台预算
Animator/Track/ClipX3支持脚本化动画编排轨道混合、时序、事件、网络同步、IK
相机系统X3支持不同玩法视角模式、输入、遮挡、过渡、脚本 API
Ability/SkillX3提供可编程战斗能力组件、槽位、预设、冷却、效果、revision
Behavior 系统X3给 NPC 和对象可编排行为authoring transaction、黑板、调度、revision
NPC 与 AIX3支撑可创作角色和世界行为控制、感知、导航、行为、性能预算
物理与碰撞X3保证用户内容可运行形状、材质、约束、网络、平台差异
游戏规则与阵营X3支撑多人玩法基本结构玩家关系、出生点、胜负、服务端权威
UI/玩家界面X3让创作者定义运行时交互GUI 对象、布局、事件、输入、安全区域
多层地图X3支持公共层和多个关卡层层身份、合并、发布条目、运行时切换
云资产运行时X3按内容身份加载可复用资源请求、缓存、校验、依赖、失败降级

五、TS、Lua、C++ 到底怎么通信

“PixUI 封装”太模糊。准确回答要先区分四条链。

5.1 TypeScript -> Lua:页面命令

React/TypeScript
  -> typed command / transport.send(type, payload)
  -> window.bridge.send
  -> JSON envelope {type, seq, data}
  -> PixUI official sendMessage / postMessage
  -> C++ PixUI DelegateOnMessage / message forwarder
  -> Lua callback
  -> EditorService decode
  -> MessageHandlers[type]
  -> 编辑领域服务或 QZUGC C API

前端只依赖 EditorTransport,不直接引用 Lua 函数或 C++ 类。类型化协议负责消息名和 payload;兼容 transport 把调用落到 PixUI bridge。C++ forwarder 把原生回调转入对应 Lua VM,Lua 服务再做解析、校验和业务分发。

为兼容不同 PixUI 运行环境,JS 侧除官方通道外还保留 postMessage 和 outbox 兜底。多通道的代价是可能重复,因此消息带序号,消费端必须去重。

5.2 Lua -> TypeScript:状态快照与增量

Lua domain state changes
  -> PushToPixUI({type, data, meta})
  -> JSON encode + monotonic seq
  -> channel A: PixUIPostMessage
  -> channel B: _qzugc.MsgQueue + MsgVersion
  -> JS bridge dispatch + cross-channel seq dedupe
  -> transport.subscribe
  -> MessageRouter / PageRuntimeClient
  -> React controller/store

回程采用“原生消息 + 全局队列”双通道:原生通道低延迟,队列通道用于兼容和可靠兜底。JS 消费完整队列后回写 AckSeq,Lua 据此裁剪已确认消息;同一 seq 无论从哪条通道先到,只分发一次。高频属性更新还需要按帧合并,避免 JSON 编解码和 React 重绘放大。

5.3 Lua <-> C++:VM 内引擎绑定

C++ 在 QZUGC VM 的全局表注册 C 闭包。Lua 调用创建/销毁 PixUI View、切换可见和交互状态、发送消息、绑定回调、读写脚本全局等 API;C++ 实际持有原生 Widget、弱引用、delegate forwarder 和 Lua registry callback。

销毁时必须同时解除 Delegate、释放 registry reference、移除 UMG/Viewport 宿主并清理按 View 保存的对象。否则常见后果不是立刻崩溃,而是旧 View 回调写入新页面、Lua 关闭后异步回调重入,或 Widget 被错误保活。

5.4 Lua <-> Lua:Client/Server IRPC

UI bridge 和网络 RPC 是两套系统。Client/Server Luau 远程调用通过原生 IRPC 适配器、结构化序列化和异步客户端完成;每个主 Lua state 拥有独立的核心与序列化器。VM 关闭前先 detach 原生回调,异步完成也要经过 generation/owner gate,不能在 Lua heap 销毁后回调。

5.5 为什么还需要 pageId、generation、domain revision

仅有消息序号仍不够:

  • pageId 区分逻辑页面实例。
  • generation 区分同名页面的第几次创建,旧 JS 上下文的迟到消息会被拒绝。
  • domain 把选择、属性、网格等状态分开订阅。
  • revision 在每个领域内单调递增,旧增量被丢弃,发现缺口可重拉快照。

页面 suspend 时释放传输订阅,但保留已接收 revision;恢复时带 revision 请求快照,从而只补缺失状态。dispose 则彻底释放 handler 和原生 View。

六、本人可以主讲的四组工作

6.1 页面协议与原生宿主

  • 业务:编辑器页面从单个 HTML 演进为多页面、多层级、可恢复的工具应用。
  • 实现:抽出 Manifest/Registry、PageManager、NativePageHost、PageRuntimeClient 和类型化 protocol;用逻辑名路由,用 replace/push/overlay 管栈;注入页面身份;按 generation/revision 拒绝旧消息;将 PixUI 差异收敛到 platform adapter。
  • 难点:页面切换后原生 View、JS 上下文和 Lua 长生命周期服务不同步,最容易出现旧回调、错误恢复、重复订阅和输入穿透。
  • 反思:页面生命周期必须成为协议的一部分,而不是 React 组件自己的 useEffect 约定;native host 要成为唯一 View owner。

6.2 状态同步与 PixUI 性能

  • 业务:对象树、属性和 Gizmo 会产生高频状态,若逐条跨语言推送,编辑器会卡顿且出现乱序。
  • 实现:状态按 domain 切分,首次拉快照、后续接收 revisioned delta;按帧 key 合并高频更新;双通道共享序号并确认消费;页面卸载释放订阅。
  • 难点:性能问题横跨 Lua 编码、C++ 消息、JS 解析、React 更新和 PixUI 绘制,不能只看一层耗时。
  • 反思:先定义状态权威和一致性,再做批量、合并和增量;否则优化会把偶发错状态变成更难复现的问题。

6.3 ArtifactBuilder 与二进制化

  • 业务:让作者源稳定转换为可发布、可验证、跨端一致的运行制品。
  • 实现:冻结快照和文件清单;Builder 重读真实 size/hash;Processor 按角色 claim 文件并形成依赖 DAG;每个任务写私有事务目录,成功后稳定合并;最后生成 Manifest、ZIP 和独立 Verify 结果。材质等 JSON 通过 TypeHint、Schema 和批量工具迁移,且只在适当保存/发布阶段触发。
  • 难点:临时目录、路径大小写、换行、工具版本、缓存和并发都会破坏确定性;失败产物不能被误识别为成功。
  • 反思:构建系统最重要的不是“能打包”,而是输入可信、输出确定、失败无半成品、工具身份和产物都可验证。

6.4 多端构建与自动化

  • 业务:让 UGC2.0 不只在开发机可运行,而能在 Android、iOS 和交付环境稳定构建、试玩和回归。
  • 实现:把环境检测、工程准备、构建、签名、安装/启动和报告拆成可组合单元;接入 GAutomator 和白盒编排;PixUI 暴露 DOM 树和稳定 ID;测试从 TS 单测、Chromium 组件测试一直覆盖到 UE 和真机证据。
  • 难点:平台错误经常表现为同一个“构建失败”,但根因可能在依赖、证书、脚本、资源、安装或运行入口。
  • 反思:流水线要输出稳定 stage/errorCode 和保留局部证据,不能只回一个退出码;自动化定位符应表达业务语义,不依赖屏幕坐标和易变层级。

七、十二个必须能讲深的专题

7.1 Instance 对象模型

统一对象模型的价值是让编辑器、脚本、序列化和网络谈论同一个对象身份。类名说明能力,ObjectId 保证引用稳定,父子关系表达所有权,Property/Signal 提供行为接口。删除、复制和 Prefab 实例化都必须更新引用,不能把内存地址或页面节点当对象身份。

7.2 编辑态与试玩态隔离

作者数据可以转成运行输入,但 Edit VM、编辑 World、Lua 引用和回调不能直接带入试玩。宿主加入试玩时先保存纯值上下文并释放 Edit,再创建 Client;退出时销毁 Client 后重新构建 Edit。隔离的代价是恢复复杂,收益是生命周期清晰、运行环境可复现且不会把编辑权限带入游戏。

7.3 三 VM 与进程拓扑

VM role 和进程不是一一固定映射。Server 永远在 DS;Client 可以在宿主或独立客户端;某些测试模式下宿主保留 Edit、Client 全部在子进程。回答时先说明测试模式、宿主是否加入和是否跨关卡,再谈进程数量,不能死背“永远三个 VM”。

7.4 页面生命周期协议

逻辑页面有 created、active、suspended/covered、disposed;原生 View 由 host 独占。push 时旧页可以隐藏或只保留渲染但禁用交互,back 时恢复;replace 必须释放旧 View;overlay 不破坏主栈。每次创建分配新 generation,从根上拒绝迟到消息。

7.5 跨语言消息可靠性

消息协议至少需要类型、payload、序号、页面身份和状态版本。多通道提高兼容性,也带来去重和确认责任。大消息、高频消息和页面销毁是三个主要故障源;因此需要队列上限、Ack、按帧合并、旧代际过滤和统一 dispose。

7.6 快照与 revisioned domain

状态按领域拆分后,每个 domain 自己维护 revision。首次订阅请求快照,增量只接受更高版本;页面暂停时记住 revision,恢复后从该点续订。这样选择变化不会迫使属性和网格一起全量刷新,也能明确是哪一个领域发生了版本缺口。

7.7 作者源与发布制品

作者源追求可编辑、可诊断和向前兼容;发布制品追求紧凑、快速和不可变。二者不能互相覆盖。二进制化应位于明确的保存/发布边界,通过 Schema 和版本演进,而不是编辑时悄悄把 JSON 改成运行格式。

7.8 确定性构建

相同输入、工具版本和配置应产生相同 Manifest 与文件集。路径规范化、排序、hash、Processor DAG、稳定错误选择和事务合并都服务于确定性。并发只允许改变完成时间,不能改变输出顺序和根错误。

7.9 跨端能力裁剪

共享内容语义不等于每个平台装载相同模块。无编辑目标不应带作者运行时,Server 不需要 UI,移动和小游戏有自己的资源、进程和调试限制。应通过模块准入和 capability 描述裁剪,而不是到处用平台 if 修补。

7.10 UI 自动化语义树

PixUI 页面若只暴露像素,自动化只能靠坐标和截图,极易受分辨率和布局影响。正确做法是导出带稳定 ID、角色、状态、可见性和边界框的语义树,再由 provider 映射点击、输入和查询;Shipping 是否开放必须有显式准入和安全边界。

7.11 性能诊断

编辑器卡顿可能来自 Lua 状态生成、JSON 编码、原生传输、JS 解析、React diff 或 PixUI 绘制。诊断需要同一个消息或帧的跨层关联标识,并把启动、首帧、交互和高频拖拽分开测。没有固定场景和证据门禁的“体感变快”不能作为结论。

7.12 旧内容与协议演进

Schema 新增字段要有默认值,删除字段要保留读取窗口,未知字段尽量透传。协议可以忽略未知字段以向前兼容,但路径逃逸、类型错误、资源超限等安全条件必须拒绝。迁移工具要 dry-run、幂等、输出失败清单,并能定位源版本和目标版本。

八、面试回答模板

8.1 “请描述 UGC2.0 客户端架构”

我会从创作内容如何进入运行时来讲。最上层是 TypeScript/React 的创作界面;下面是页面协议和 PixUI 原生宿主,负责页面栈、生命周期和跨语言消息;编辑领域层负责选择、Gizmo、属性、事务、撤销和 Prefab;核心数据由 DataModel/Instance、Property、Signal 和 Service 组成,脚本通过 Luau VM 与 C++ binding 访问;试玩时 Edit、Client、Server 是独立角色和生命周期,服务端保持权威;保存发布侧把作者 JSON、脚本和资产冻结成快照,经 Processor DAG 转成带 Manifest 的可验证 Artifact;最后由多端构建、缓存、自动化和性能门禁保证交付。核心边界是对象身份、VM 隔离、页面代际和作者源/发布制品分离。

8.2 “你在 UGC2.0 做了什么”

我主要做了四块。第一是 PixUI 页面基础设施,把 TypeScript 页面、Lua 编辑服务和 C++ 原生 View 之间的协议、页面栈、生命周期和状态版本补齐;第二是 ArtifactBuilder 和 JSON/FlatBuffers/QZBIN 二进制化接入,解决冻结输入、处理器编排、校验和失败清理;第三是 Android、iOS 的构建、试玩恢复和调试工具;第四是 GAutomator、PixUI DOM、稳定 ID 和白盒流水线。对象模型、三 VM 和完整运行时不是都由我设计,但这些是我的上下游,我已经结合源码系统复盘。

8.3 “PixUI 封装里 TS、Lua、C++ 怎么通信”

前端不是直接调用 C++。TS 先调用类型化 transport,bridge 把命令编码成带 type、seq 和 data 的 JSON,通过 PixUI 官方消息通道送到 C++;C++ 的 message forwarder 再进入当前 Edit VM 的 Lua callback,由 EditorService 解码并分发到领域 handler。回程由 Lua 给消息加 seq、pageId、generation、domain 和 revision,优先走原生 PostMessage,同时写全局队列做兼容兜底;JS 对两条通道按 seq 去重,消费队列后回写 Ack。Lua 调 C++ 则是另一层:C++ 在 VM 注册 QZUGC C API,Lua 用它创建/销毁 View、绑定回调和读写 PixUI 全局。Client/Server 之间又是独立的 IRPC,不和 UI bridge 混用。

8.4 “为什么要做 page generation 和 revision”

generation 解决对象生命周期,revision 解决状态顺序。页面关闭再打开后,同名页面已经是新的 JS 上下文,旧异步消息必须按 generation 拒绝;同一页面里选择、属性、网格等领域各有 revision,只接受更高版本,暂停恢复时带上最后版本重新请求快照。二者缺一,都会出现旧页面覆盖新页面或乱序增量覆盖新状态。

8.5 “为什么不让 TS 直接调 C++”

直接绑定会把页面生命周期、引擎对象和业务接口耦在一起,也难以做浏览器预览和协议测试。现在 TS 只依赖稳定 transport,Lua 拥有编辑领域编排,C++ 拥有原生资源和引擎能力。代价是序列化和协议治理成本,因此需要类型定义、版本、批量、可观测和自动化测试来控制。

九、个人能力收口

UGC2.0 最能证明四种能力:

  1. 能把跨语言 UI 从“能发消息”提升为有身份、生命周期、版本和恢复能力的运行协议。
  2. 能设计作者源到发布制品的确定性流水线,处理并发、失败、路径和兼容边界。
  3. 能跨 TypeScript、Lua、C++、Python 和构建系统定位问题,而不是只守一层代码。
  4. 能把浏览器测试、UE 自动化和真机构建串成分层证据链。

暂时不能使用的说法:

  • 我主导了 UGC2.0 全部对象模型和三 VM 架构。
  • 所有运行时、网络、Prefab、云资产和玩法能力都是我做的。
  • PixUI bridge 保证 exactly-once;现有机制是多通道去重与确认,不是分布式意义的 exactly-once。
  • 没有基线报告时声称明确性能提升百分比。

后续专题文档应从本篇拆出:UGC2.0 架构背诵稿、跨语言通信追问卡、页面生命周期 STAR、ArtifactBuilder STAR、多端构建 STAR、UI 自动化 STAR 和三 VM 设计题。