DreamFXLang
生成与往返

Export 与 Adopt

两者都会反编译;区别在于之后发生的事 —— 镜像命名空间、接管流程,以及三条被拒绝的理由。

Export 与 Adopt 都会反编译。它们的区别在于之后会发生什么,而这个区别正是全部意义所在。

Export .dfsAdopt
写入位置DecompiledOutputDirectory(默认 DFX/Decompiled)真正的源码根 —— <Project>/DFX/… 或 <Plugin>/DFX/…
Name= 名称Decompiled/<original directory>/<asset> —— 一个镜像原始资产
是否被构建拾取是 —— 保存其中一个会重建它的镜像是
是否修改资产从不是:根据新源码重建它并打上来源标记
无法表示的特性警告,并在文件中列出它们拒绝
含义“让我把它当作文本来阅读和试验”“从今往后,这段文本是唯一的真相”

让两者分开的是结构,而非流程

一次导出无法命名它来自的资产:

/Game/FX/NS_X
   └─ export ─> DFX/Decompiled/Game/FX/NS_X.dfs
                Name="Decompiled/FX/NS_X"
                   └─ build ─> /Game/Decompiled/FX/NS_X      (the original is untouched)

所以整棵反编译树都是普通源码 —— 被监视、保存即构建、被 lint 并进入 CI —— 而无论文件如何被编辑,原始资产都保持不变。

在此约定之前写出的导出仍然会命名原始资产。它们会被以 DFX8013 拒绝,而不是被执行;重新导出即可替换它们。

对一个已经是镜像的资产执行导出同样会被拒绝 —— 那会留下两份源码争夺一个资产 —— 并且提示会链接到该镜像所基于的源码。

Adopt 的六个步骤

反编译

如果有任何无法表示的内容 → 拒绝,并列出是什么 (DFX8010)。

根据挂载点推导出源码路径

/Game/FX/NS_X → <Project>/DFX/FX/NS_X.dfs;/MoonToon/FX/NS_X → <MoonToon>/DFX/FX/NS_X.dfs。

检查是否已有其他东西声明了此资产

如果有 → 拒绝(DFX8011)。两份源码会在交替构建时互相覆盖。

确认

列出要写入的文件和要重建的资产。(在 Python 中,bSkipConfirmation 会抑制该模态框。)

写入文件、重建资产、打上来源标记

重新反编译并逐字节比较

不一致即为 DFX8012,并记录第一处不同的行。

第 1 步正是第 6 步有意义的原因:在没有已知缺口的情况下,不一致是真正的缺陷, 而不是预期内的丢失。

注意:

DFX8012 会保留源码文件 —— 资产已经根据它重建,所以文本无论如何都是权威的 —— 并记录第一处不同的行供你判断。

该用哪一个

目标使用
理解别人做的特效Export
将现有特效作为新特效的模板Export,然后把 Name= 改成你自己的命名空间
将特效迁移到文本工作流Adopt
扫描整棵树以查看覆盖了多少dfx decompile-all + mirror-diff

警告:

Adopt 之后,该资产就是构建产物:手动编辑会在下次重建时被抹掉。这正是你选择采用 Adopt 所要求的 —— 只要确保团队知晓即可。

从命令行做同一件事

# print it
pwsh -File Plugins/DreamFX/.skill/dfx.ps1 decompile /Game/VFX/NS_Explosion

# write it to a file
pwsh -File Plugins/DreamFX/.skill/dfx.ps1 decompile /Game/VFX/NS_Explosion -Out DFX/Decompiled/NS_Explosion.dfs

# a whole tree
pwsh -File Plugins/DreamFX/.skill/dfx.ps1 decompile-all -Path=/Game/VFX

-NoDefaults 会打印每一个输入,包括与全新模块默认值相等的那些。这仅用于诊断 —— 其结果并非旨在维护;它回答的是“基线隐藏了什么?”。

本页目录