Limits
What is deliberate, what is not done yet, what the round trip cannot carry, and the 1.0.0 known issues — each with the way it surfaces.
This page states what DreamFX does not do. There is one principle behind all of it: every degradation is diagnosed, never silent. So each entry below comes with the way it surfaces.
Deliberate
| Why | |
|---|---|
| Scratch Pad | A scratch pad script is a graph embedded in the asset, with no stable name to address it by |
| Lowering a module body into a node graph | A .dfm body becomes one custom HLSL node. Lowering it is "tier two": the ~13k-line problem DreamShader already has, reproduced |
| A general expression compiler | Inline expressions are arithmetic plus a short whitelist (DFX4031). Anything more belongs in hlsl { } or a .dfm |
| True emitter inheritance | from is a copy. Editing a .dfe changes nothing in systems that already copied it until they rebuild |
MaterialParam | Reserved syntax, not implemented (DFX5093) |
[Group] / [SortPriority] reaching the asset | The external edit API's user variable struct has no metadata fields for them (DFX5099) |
#Region reaching the asset | The external edit API has no stack-note function (L5) |
Not done yet
| What happens now | |
|---|---|
| GPU/CPU branch conditions | not expressible |
| Scalability condition logic | not expressible (an emitter's QualityLevelMask is supported) |
Compile-time folding for a .dfm static switch | accepted, validated, then lowered as an ordinary input (DFX5102) |
| Full readable syntax for curve data interfaces | anything configured outside the keys falls back to verbatim JSON |
| The remaining stage properties (the state-iteration trio, …) | the header accepts five arguments (DFX2026) |
What the round trip cannot carry
Round-trip gap — DFX8014
Emitter inheritance is flattened. The merged stack is carried in full and the rebuilt emitter behaves like the original — what is lost is the link: later edits to the parent reach the original and never the mirror.
Round-trip gap — DFX8015
A second event handler on one emitter. One is representable; more are not. A standalone .dfe
export cannot carry a handler's Source either, because there is no sibling emitter to name.
Round-trip gap — DFX8016
Custom C++ stage classes. Ordinary stages export as Stage name(...); a stage whose class is not
the engine's generic one does not.
Two more that raise no code but are worth knowing:
- The other fields of a renderer list element.
Meshesis written as an array of paths, but each element is really a struct — a mesh's per-element pivot, scale and LOD range have no syntax. An export that would drop one says so in the file header. - Inline expressions do not come back as themselves. They return as an equivalent
hlsl { }block. The round trip is semantic, not textual.
1.0.0 known issues
- A linked declaration switch on a nested dynamic input node at depth > 1 is unguarded — an engine defect that is reachable but has zero hits in the corpus; the guard is planned to reach that depth in 1.0.x.
- Emitter-level
FixedBoundsis not carried (system-level is). bGpuAlwaysRunParticleUpdateScriptis not carried.- Data interface configuration rides as verbatim JSON (readable syntax pending); with a bare
DI<T>plus a link, the count of leftover default instances is unstable — that is judgment noise, not data loss. - A UE 5.8.1 refPath import regression — an engine bug, worked around with
NormalizeObjectReferences, to be removed after a 5.8.2 retest. - The L4 picture comparison is a manual, optional step (the OBS recipe is verified, not scripted).
- The long tail listed as not-done: custom C++ stage classes, parameter-driven iteration counts and so on — the gap header names them, and the corpus has no instances.
These are not defects — they are requirements
Host projects must enable the same content plugins as the authoring project (e.g.
NiagaraFluids). With the plugin unmounted the module probe has no baseline, and sources referencing
its modules surface as gaps or compile errors. A whole family of unresolvable names sharing one
prefix is a mount point, not a typo.
Package-writing commands need the editor closed (build, corpus, mirror-diff,
decompile-all). Two processes saving the same packages race silently.
Despawn a system's instances before rebuilding it. During a hot swap a live NiagaraActor can
see a half-built renderer layout and assert on a render worker. It is an engine race, not something
DreamFX can guard.
Measure your own coverage
Somebody else's number does not answer your question:
pwsh -File Plugins/DreamFX/.skill/dfx.ps1 coverageIt reports how much of a content tree is expressible, bucketed by feature. Unpacked in round trip and equivalence.