The Grim Dawn .PFX file-format is the binary file-format that the game uses for storing its particle effects.
File Header
PFX files have a single header at the start of the file <65 00 00 00>, which is then followed by a list of its emitters one after each other.
Emitters
Overview
Each emitter section has 5 parts:
- A string containing the emitter-name (see the data-types section regarding the string format)
- A static emitter-type: 'PFX1' <50 46 58 31>
- A terminator?: <00 00 00 00> (Always seems to be empty)
- The length of the rest of the data in this emitter (e.g. 909 <8D 03 00 00>)
- The 5 different sections for each data-type (strings, booleans, ints, floats, and graph-lines)
There are no terminators to delineate between each data-type section, it seems to rely on each section-header to determine how many values the following section has, and when you've read that many values you will have reached the next section.
Data Sections
Each of the 5 data-type sections start with a header containing an integer that indicates how many values are within that section (which always seem to be the same):
- Strings := 3 <30 00 00 00>
- Booleans/Flags := 14 <0E 00 00 00>
- Integers := 2 <02 00 00 00>
- Floats := 4 <04 00 00 00>
- Graph-Lines := 26 <1A 00 00 00>
Then after that section-header, it lists each value one after each other until it reaches the next data-type section, or the end of the emitter (after the final graph-lines section).
Variable Mapping
Strings/Filepaths (x3)
- Particle Texture (e.g. 'Effects/Default/particletest.tex')
- Shader (e.g. 'Shaders/Particle/ParticleAdditive.ssh')
- Drop Decal (e.g. 'FX/decals/defaultdecal.tex')
- Looping
- Emit Locally
- Motion Orient
- Implode
- Random Orientation
- Flatten Motion
- Light Enabled
- Light Shadows
- Light Off-During-Day
- unknown_9 ??? (Always seems to be False <00 00 00 00>)
- Orient Vertically
- Light Simple
- unknown_12 ??? (Always seems to be False <00 00 00 00>)
- Light Important
- Emitter Shape (ENUM: [0]Sphere, [1]Plane, [2]Circle, [3]Line, [4]Shell, [5]Skeleton)
- Emitter FPS
- Particle Lifetime
- Initial Rotation X
- Initial Rotation Y
- Initial Rotation Z
- Particle Color - Alpha
- Particle Color - Red
- Particle Color - Green
- Particle Color - Blue
- Particle Rotation
- Particle Size
- Emit Rate
- Emit Velocity
- Particle Gravity
- Emitter Offset X
- Emitter Offset Y
- Emitter Offset Z
- unknown_12 ???
- unknown_13 ???
- Emit Angle
- Emitter Size
- Particle Twirl
- Particle Stretch
- Emitter Rotation X
- Emitter Rotation Y
- Emitter Rotation Z
- Particle Friction
- Light Color - Red
- Light Color - Green
- Light Color - Blue
- Light Radius
Strings
Editable strings start with a header containing an integer with the length of the string:
e.g. 'New Emitter' := 11 <0B 00 00 00> New Emitter <4E 65 77 20 45 6D 69 74 74 65 72>
If the string is empty, there's just a header with a length of 0:
e.g. "" := 0 <00 00 00 00>
The exception to this seems to be the static emitter-type that is immediately after the emitter-name, which has no length header:
e.g. PFX1 <50 46 58 31>
Booleans/Flags
Booleans are just integers with values of either 1 or 0.
e.g. True <01 00 00 00>, or False <00 00 00 00>
Integers
Integers are little-endian integers of a 4-byte length:
e.g. 0 <00 00 00 00>, 15 <0F 00 00 00>, 30 <1E 00 00 00>
Floats
Floats are big-endian single-precision floating-points of a 4-byte length:
e.g. 1.0 <00 00 80 3F>, 0.5 <00 00 00 3F>, 5.5 <00 00 B0 40>, 10.0 <00 00 20 41>
Graph-Lines
Each graph-line consist of 4 different parts:
- A float containing the X-Scale (time)
e.g. 10.0 <00 00 20 41> - A float containing the Y-Scale (value)
e.g. 1.0 <00 00 80 3F> - An integer containing the number of points in the proceeding list
e.g. 2 <02 00 00 00> - A list of graph-points
e.g. <00 00 00 00 00 00 80 3F> <00 00 20 41 00 00 80 3F>
Each graph-point consist of 2 floats representing the [x,y] coordinates:
e.g. a static line with 2 points (that stays at 1.0 for 10 seconds): [ [0.0, 1.0], [10.0, 1.0] ]
0.0 <00 00 00 00> 1.0 <00 00 80 3F> 10.0 <00 00 20 41> 1.0 <00 00 80 3F>
0 comments