# 高级 I 导览 高级教程写给已经能独立使用中级接口、现在想按自己的规则扩展数据端的人。到了这一层,问题不再是「这个接口怎么调」,而是「这个需求该放在哪一层、该由谁在什么时机执行」。弄错这一层,效果可能当下能跑,却会在存档、读档或录像回放时对不上。 这一页说明高级教程分几层、高级 I 包含哪些篇目、先读什么、以及一条贯穿全层的取舍原则:新增系统优先用插件,少改内置。 ## 高级教程是给谁的 高级教程面向有高度定制需求的作者: - 你要新增一套有自己状态、生命周期和存档内容的系统,而不只是改一个数值; - 你要理解扩展机制本身,知道声明式接口、插件、存档与录像之间怎么配合; - 你愿意读一点源码,但不需要成为引擎的编写者。 它不要求你改造引擎内部。高级教程同时覆盖数据端与渲染端;渲染端尚未完工,暂时只能写数据端的内容,所以高级 I 的例子都落在数据端:你写的内容、你注册的对象、你声明的规则。 ## 高级教程的三层 高级教程按难度与主题分成三层。层与顶层的中级教程不是同一套划分:中级讲「怎么用」,高级讲「怎么扩展」。 | 层级 | 定位 | 主要主题 | | --------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------- | | 高级 I · 扩展基础 | 以插件系统为核心,后续内容都是它的拓展 | 声明式接口、插件系统、可存档内容、录像一致性、data-common 的 Store、钩子深入 | | 高级 II · 系统实现 | 系统级实现 | 战斗上下文、光环 / 查询 / 优先级、伤害与地图伤害、渲染层与布局、加载与插件生命周期、自定义录像行为 | | 高级 III · 原理与架构 | 原理与架构 | 双端分离约束、数据端 L0–L3、编辑器识别协议、录像深层原理、性能与调试 | 当前站点的「高级教程」只收录高级 I 的内容。高级 II 与高级 III 的专题在正文里用 `高级 II · <专题>`、`高级 III · <专题>` 这样的占位标记指出归属,不提供页面入口。 ## 高级 I 包含什么 高级 I 一共七篇,包含本导览与六篇正文。 | 序 | 篇目 | 它能让你做什么 | | --- | -------------------- | ------------------------------------------------------------ | | 1 | 高级 I 导览 | 看清分层、阅读路径与取舍原则,决定先读哪篇 | | 2 | 声明式 vs 命令式接口 | 分清两种思路,知道持续生效的规则与一次性动作各该写在哪 | | 3 | 插件系统 | 独立写出插件,分清数据端与渲染端的依赖和生命周期 | | 4 | 可存档内容 | 让自定义状态正确进入存档,并在读档后恢复到存档时的样子 | | 5 | 录像一致性 | 判断数据端哪些方法该登记、哪些路径不该记,以及检查能保证什么 | | 6 | data-common 的 Store | 知道五个 Store 各存什么、能做什么,以及为什么运行时只读 | | 7 | 钩子深入 | 把钩子限定到一个对象上,建议一个对象一个钩子实例 | 推荐阅读顺序:声明式 vs 命令式 → 插件系统 → 可存档内容 → 录像一致性 → data-common 的 Store → 钩子深入。 插件系统是这一层的核心,后四篇都建立在它提供的扩展位置上。也可以按需求跳读,但建议至少先读前两篇:它们决定你是在「声明一条规则」,还是在「写一段一次性脚本」。 ## 阅读路径与前置 高级 I 假设你已经读完中级教程,尤其是数据端与渲染端、代码基础、数据插件这三篇;数据端总览、钩子、录像指令也会在具体页面里被直接引用。前置篇目的链接放在本页末尾。 按目标不同,可以走两条路径: - 做扩展系统:声明式 → 插件 → 可存档内容 → 录像一致性。适合新增任务、商店、计数器这类有自己状态与生命周期的功能。读完能独立装配一个插件,并让它的数据跟着存档走。 - 改内容或机制:声明式 → data-common 的 Store → 钩子深入。适合在现有机制上加行为、按接口读取内容定义。读完能分清哪些只需要读、哪些由数据端登记,也能把钩子限定到目标对象上。 两条路径都建议先读声明式篇。它决定你后面是在「加一条规则」,还是「写一段一次性脚本」;这个判断错了,插件、存档与录像都会跟着别扭。 ## 优先用插件,少改内置 新增系统优先通过插件系统实现;只有不得不修改内置系统时,才去改内部。理由很现实:版本迁移时 `src` 基本不会改,而内置包(`packages` / `packages-user`)有可能会改。直接改内置,升级时就要跟着差异走,维护成本更高;把改动留在自己的 `src` 里,升级时要对照的地方少得多。 | 需求类型 | 优先做法 | 什么情况下才改内置 | | -------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------- | | 新增一套有自己状态、生命周期与存档内容的系统 | 写成插件,在插件里装配对象 | 现有插件已覆盖大部分能力,只差一个接口或默认值时 | | 给已有系统补一点行为 | 改内置类的方法体,或加一条分支 | 需要替换整套策略、或改动会破坏内置行为时,才独立成类 | | 读取内容定义(图块、道具、地图、怪物、事件) | 通过 `state.*Store` 的接口读,不新建 Store | 现有 Store 装不下,且确实需要新的系统级数据表时 | | 给会改状态的方法补录像标记 | 在内置方法上加一行装饰器 | 需要新的录像入口或自定义录像行为时(属于 `高级 II · 自定义录像行为`) | 判断标准不是改动多少行,而是改动落在谁的代码里:能由插件或内容定义完成的,就留在 `src`;必须动内置包时,尽量把差异收敛在一个方法或一条分支上,方便升级时对照。 ## 本层不覆盖什么 - 渲染端内容:渲染端尚未完工,高级教程当前只收录数据端内容,渲染端专题待完工后补上。 - 高级 II 的系统级实现:战斗上下文、光环 / 查询 / 优先级、伤害与地图伤害、渲染层与布局、加载与插件生命周期、自定义录像行为。 - 高级 III 的原理与架构:双端分离约束、数据端 L0–L3、编辑器识别协议、录像深层原理、性能与调试。 - API 参考:接口签名与类型清单不属于教程正文。 ## 读完这一层应该能做什么 - 能用自己的话解释声明式与命令式的区别,并说出一个「仍然该用命令式」的场景。 - 能拿到一个需求,判断它该做成插件,还是按现有接口读取即可。 - 能说出一个可存档对象必须满足的三个约束:只存重建必需的数据、`saveState` 返回独立对象(引擎不替你深拷贝)、`loadState` 先清空再重建。 - 能说明为什么建议一个对象一个钩子实例,并在回调拿到多个对象时用对象引用筛出目标。 ## 继续阅读 高级 I 正文: - [声明式 vs 命令式接口](./declarative-vs-imperative.md) - [插件系统](./plugin-system.md) - [可存档内容](./saveable-content.md) - [录像一致性](./replay-consistency.md) - [data-common 的 Store](./data-stores.md) - [钩子深入](./hooks-in-depth.md) 前置回顾(中级教程): - [数据端与渲染端](../intermediate/data-vs-render.md) - [代码基础](../intermediate/code-basics.md) - [数据插件](../intermediate/data-plugins.md)