The file model
The shape every DreamFXLang file shares — header, blocks, statements, comments, attributes — and an index of the eight L rules.
DreamFXLang has one file shape. The three extensions differ in what the top-level declaration is, not in the grammar.
<Kind>(Name = <string>[, Root = <string>])
{
<block> …
}| Notation | Meaning | Example |
|---|---|---|
<x> | Placeholder — substitute a real value; the angle brackets are not typed. | Name = <string> |
[ x ] | Optional — the whole group may be left out. | [, Root = <string>] |
{ a | b } | Choice — take exactly one of the alternatives separated by |. | { Node( … ) | Comment( … ) } |
… | Repetition — the preceding item may appear any number of times. | <property-declaration> … |
Kind | Extension | Produces |
|---|---|---|
System | .dfs | a UNiagaraSystem |
Emitter | .dfe | nothing (copied into a .dfs by from) |
Module / DynamicInput | .dfm | a UNiagaraScript |
A Kind that disagrees with the extension is
DFX2021; one file holds exactly one top-level object, and
anything after it is DFX2022. What Root accepts is in
layout and naming.
Blocks, statements, attributes
Settings = { // a block: Name = { … }
WarmupTime = 0.0; // statements end in ;
}
Properties = {
int SparkCount = 24 [ Group="Burst"; SortPriority=10 ]; // attributes hang off a declaration
}
// line comment
/* block comment */- a block is
Name = { ... }; - a statement ends in
;; - attributes are
Key=Valuepairs in brackets after a declaration, separated by;; - comments are
//and/* */.
#Region is only a comment
ParticleUpdate = {
#Region "Forces"
GravityForce(Gravity = (0, 0, -680));
#EndRegion
}#Region / #EndRegion exist for humans and editors to fold on. They do not reach the asset
(that is L5): the external edit API has no stack-note function. An unclosed one warns
(DFX2010); a stray #EndRegion is an error
(DFX2005).
Names that are not identifiers
Niagara names come from a UI with no restrictions. Real content in this project has a user parameter
called PillarPower(0~1) and a module input called Ring/DiscDistributionMode; neither is an
identifier in any language. Back-quotes hold one:
Properties = {
float `PillarPower(0~1)`;
}
ParticleSpawn = {
SphereLocation(
`Ring/DiscDistributionMode` = Direct,
Alpha = `User.PillarPower(0~1)`,
);
}A back-quoted name is one token, dots included — `User.PillarPower(0~1)`, not
User.`PillarPower(0~1)` . Only quote what needs it: `Speed` is legal but reads worse than
Speed, and the decompiler applies exactly that rule. A name containing a back-quote has no written
form at all — rename the parameter. An unterminated one is
DFX1005.
The eight L* rules
The language's skeleton is eight rules, and the docs refer to them by name:
| Rule | |
|---|---|
| L1 | A stack is an ordered statement block. Six of them: SystemSpawn, SystemUpdate, EmitterSpawn, EmitterUpdate, ParticleSpawn, ParticleUpdate. Writing order is module order. |
| L2 | Two statement forms: a module call, and an assignment. Consecutive assignments fold into one Set Parameters module; a module call breaks the run. A new attribute is declared by its first write. |
| L3 | Four value modes: literal, linked, dynamic input, HLSL. |
| L4 | Module names resolve through Settings.ModulePaths; write a longer path only when a short name is ambiguous. |
| L5 | #Region is a comment. It does not reach the asset. |
| L6 | Inline expressions lower to one HLSL expression, and only whitelisted functions are allowed. |
| L7 | Numeric conversion widens, never narrows. int -> float is implicit; float -> int needs int(...). |
| L8 | Renderer properties are schema-driven generic assignment; every renderer type is supported without per-type syntax. |
L2, L3, L6 and L7 are unpacked in values and rules, L1 in
.dfs, and L8 in
the renderer section of .dfs.
A page per file kind
`.dfs` — a system
Settings, Properties, the six stacks, renderers, from, Defaults.
`.dfe` — a reusable emitter
One Emitter block, and what the from merge replaces.
`.dfm` — modules and dynamic inputs
Usage, Inputs, the HLSL Body, and which engines can generate one.
Values, types and the `L*` rules
The four value modes, curve { }, inline expressions, the type table.
Events and simulation stages
OnEvent and Stage, and the hard limits on each.
What is deliberately not here
What DreamFX is
What it does and does not do, and the stances that run through all of it — the text is the truth, a gap must be visible, a menu is not a second implementation.
.dfs — a system
System settings, user parameters, module calls and assignments in the six stacks, Defaults, renderers and bindings, and referencing a .dfe.