长什么样
一个文件,一条命令,一个 Niagara 系统
下面是一份完整的 .dfs —— 不是节选。六个栈里的模块调用、user 参数、renderer 属性,全部是文本;构建把它变成 /Game 下一个普通的 UNiagaraSystem。
System(Name="Effects/NS_Hello", Root="Game"){ Properties = { float Speed = 150.0; } Emitter Motes { Settings = { SimTarget = CPU; Determinism = true; } EmitterUpdate = { EmitterState(LifeCycleMode = Self); SpawnRate(SpawnRate = 20.0); } ParticleSpawn = { SystemLocation(); AddVelocityInCone(VelocityStrength = User.Speed); } ParticleUpdate = { ParticleState(); GravityForce(Gravity = (0, 0, -400)); SolveForcesAndVelocity(); } SpriteRenderer Core { FacingMode = FaceCamera; } }}生成 /Game/Effects/NS_Hello,全程不用打开编辑器
pwsh -File Plugins/DreamFX/.skill/dfx.ps1 build DFX/Effects/NS_Hello.dfs
工作流
文本进,Niagara 资产出 —— 也能倒着走
生成是 headless 的:一条命令,一个资产。编辑器开着时,存盘即重建,Niagara 预览窗口就是实时预览。反方向同样成立,反编译不是便利导出,是有契约的往返。
Source
.dfs 写系统,.dfe 写可复用 emitter,.dfm 写模块与动态输入。六个固定栈、事件处理器、simulation stage、renderer 属性与绑定,全在文本里。
Build
commandlet 解析源码、按模块 → emitter → 系统的顺序生成,跑完 Niagara 编译,并在资产上盖一枚溯源戳:源 hash + 生成器版本 + 模块版本 GUID。
Verify
lint → build → verify → corpus 四步 CI。verify 抓的是「改了源码没重建就提交」——只跑 build 永远发现不了,因为 build 会把它修好。
Round-trip
反编译回 .dfs 逐字节幂等;表达不了的东西逐条写进文件头缺口注释,绝不静默丢。Adopt 接管一个资产前先重导出比对,对不上就拒绝。
工具链
插件、命令行、编辑器扩展与 AI 技能
菜单是入口,不是第二套实现:编辑器里点的每个按钮,和命令行跑的是同一条管线,同一批诊断码。
DreamFX 插件
解析、生成、反编译、file watcher、Content Browser 右键、工具栏,以及 -NoDreamFXEditor 一键关闭。
dfx.ps1 / ci.ps1
build · verify · lint · decompile · mirror-diff · asset-diff · coverage · schema · index · corpus,关着编辑器全部跑得动。
四层往返验证
L1 文本逐行、L2 镜像编译、L3 SimCache 运行时等价、asset-diff 资产事实走查——绕开导出器自身的盲点。
AI 技能
插件自带四个 agent 技能:create / verify / diagnose / decompile,编码代理可以全程 headless 地做特效。
