Divine Skins
Divine Skins Wiki

Bin & Particle Dictionary

A reference for the properties inside a League of Legends VFX bin, organised by the class each one actually belongs to.

Written by DAKA

Every other page in this section teaches you to do something. This one is for the moment you are scrolling a .py dump, land on a property you have never seen, and just need to know what it is and where it belongs.

Entries are grouped by the class that owns them, because in a bin the same name can appear on more than one class, and knowing which one you are inside decides what the value does.

Read this next to Ruby

Most of these properties are quicker to understand by moving them than by reading about them. Ruby previews VFX on any champion and has a bin editor built in, so you can change a value and watch the viewport instead of packing a mod to find out what it did.

Where these names come from

Every class, property and type on this page was read from the engine's own registered class layout, checked against patch 16.16. Field names that no longer exist were removed, and the ones that live on a different class than you might expect are labelled with where they actually are. A handful of behaviours are noted where the runtime does something other than what the property name suggests.

You can find the structural data from here lol-meta-classes. You can also find documentation about the meta classes and properties at lol-meta-wiki.


How to read a bin

A VFX bin is a tree. The spine looks like this:

VfxSystemDefinitionData              one complete effect, e.g. a recall or a Q
└── complexEmitterDefinitionData     the list of emitters the system owns
    └── VfxEmitterDefinitionData     one emitter: a trail, a flash, some sparks
        ├── primitive                what each particle draws as
        └── *Definition pointers     erosion, palette, distortion, children, ...

VfxSystemDefinitionData is the container. A property that is not inside the system playing during an ability will not show up during that ability.

The emitter is where most of your time goes. It carries 135 registered fields on its own, and hangs a dozen optional sub-definition objects off pointers. A null pointer means that whole feature is off, which is why deleting a block is often the correct way to disable something.

Value wrappers

Numeric properties are usually wrapped so the engine can hold them constant or vary them:

rate: embed = ValueFloat {
    constantValue: f32 = 20
}

The wrappers are ValueFloat, ValueColor, ValueVector2 and ValueVector3. Each holds a constantValue plus an optional dynamics pointer. They are two separate fields, not two spellings of one field: the constant is always there, and dynamics is an extra object hanging off it.

KeyLives onWhat it is
constantValuethe wrapperThe authored value. Type matches the wrapper: f32, vec4, vec2, vec3
dynamicsthe wrapperPointer to an animated-variable object. Null means the constant is used as-is
timesthe dynamics objectPositions along the curve
valuesthe dynamics objectThe value at each matching entry in times
probabilityTablesthe dynamics objectPer-particle randomisation. See below
probabilityTables multiply, they do not select

A probability table is often read as "pick one of these values at random". It is not. Each table maps a uniform random draw through its own keyTimes to keyValues curve and returns a multiplier, which is then applied to constantValue. The draw happens once per particle, at birth.

So constantValue of 5 with a table returning the range 0.5 to 1 gives each particle a value between 2.5 and 5. A table whose keyValues cross zero, such as -1 to 1, will flip the sign on roughly half the particles. That is the usual explanation for an effect where some particles scroll or spin the opposite way to the rest.

Note that keyTimes on a probability table is the draw axis, not particle age.

Birth properties and their over-life partners

Many properties come in pairs. The birth* one is evaluated once, when the particle spawns. Its partner without the prefix keeps acting across the particle's life, and is multiplied with the birth value rather than replacing it.

At spawnAcross life
birthColorColor
birthScale0scale0
birthRotation0rotation0
birthVelocityvelocity
birthAccelerationacceleration
birthDragdrag

If a value looks wrong and only one half of a pair is authored, check the other half before changing anything.

Units

Rotations and rotational velocities are in degrees and degrees per second. Lifetimes, periods and delays are in seconds. UV scroll rates are in UVs per second, and UV rotation is in degrees. Colour channels run 0 to 1.

Randomisation, and the 0 suffix

Several birth properties end in 0, such as birthScale0 and birthRotation0. This is a naming leftover, not a minimum-maximum pair. There is no matching birthScale1 on the current emitter class. Per-particle variation comes from probabilityTables, as above.

Flag bytes

Many booleans are not separate fields. They are single bits packed into shared flag bytes on the emitter. Text tooling surfaces them individually as flag, so you will write them one at a time, but they live four or eight to a byte. The full list is in Emitter flags.


System level

VfxSystemDefinitionData, the outermost container. 33 registered fields as of patch 16.16.

PropertyTypeWhat it does
particleNamestringReadable name of the whole system. Safe to rename, and the most reliable thing to search for when the container's hash is unresolved
particlePathstringPath grouping the engine uses to organise systems
complexEmitterDefinitionDatalist[embed]The emitters this system owns. The body of the effect
simpleEmitterDefinitionDatalist[embed]The older emitter list. Still present on legacy systems
materialOverrideDefinitionslist[embed]System-wide material overrides. The emitter has its own list of the same name
transformmtx44Applied to the entire system, for scaling, moving and rotating it as one unit. See Matrix Scaling
flagsu16System-level bit flags. Two are known: 0x100 switches velocity and drag to a closed-form solve, and 0x800 is an aggressive low-spec mode. Default 212
mEyeCandyboolMarks the system as eye candy, so it disappears when a player turns on Hide Eye Candy
buildUpTimef32Warm-up period for the system
visibilityRadiusf32Culling radius
overrideScaleCapoption[f32]Caps how far the system can be scaled
scaleDynamicallyWithAttachedBoneboolSystem scale follows the bone it is attached to
objectPathhashObject path identifier. Added in patch 16.16
drawingLayeru8Which layer the system draws into
ClockToUseu8Which clock drives the system's time
selfIlluminationf32Self-illumination amount
assetRemappingTablelist[embed]Asset remaps applied within the system
soundOnCreateDefaultstringSound fired when the system is created
voiceOverOnCreateDefaultstringVoice-over fired on creation
soundPersistentDefaultstringLooping sound for the system's lifetime
mEyeCandy is a system property

It sits on VfxSystemDefinitionData, not on the emitter, which is why it belongs at the system level of the block rather than beside the emitter's render settings.


Emitter: identity and lifetime

VfxEmitterDefinitionData. Everything from here to Emitter flags is on this class unless a row says otherwise.

PropertyTypeWhat it does
emitterNamestringReadable name for one emitter. Safe to rename and worth doing
disabledboolTurns the emitter off without deleting it
importanceu8Quality-culling priority, checked against the Effects Quality video setting. See the table below. Default 2
particleLifetimeValueFloatHow long each particle lives after being emitted. Defaults to 3.0 when absent. -1 is a sentinel, see the warning below
lifetimeoption[f32]How long the emitter itself runs
particleLingeroption[f32]Extra seconds particles stay visible after the emitter finishes. When absent it defaults to particleLifetime + 10, not to zero
emitterLingeroption[f32]Extra seconds the emitter itself lingers
particleLingerTypeu8Which lingering behaviour is used
LingerpointerA VfxLingerDefinitionData, for lingering that changes the particle rather than just delaying it
flexParticleLifetimepointerFlex override for particle lifetime
particleLifetime -1 means two opposite things

-1 does not mean "infinite particle". It means "live until the emitter stops", and what that gives you depends entirely on isSingleParticle.

With isSingleParticle set, the emission-window clamp is skipped, so the window stays uncapped, the emitter never completes, and the particle persists indefinitely. This is how a permanently attached prop is built.

Without isSingleParticle, the clamp branch never runs and the emission window stays at the authored lifetime. The emitter stops there and takes its particles with it, so a continuous -1 despawns rather than persisting.

An authored 9999 behaves the same as -1.

How importance culls

importance is checked against the player's Effects Quality setting when the system builds its emitters. It is a category, not a scale, and two of the values behave in ways the name does not suggest.

Effects QualityImportance values skipped
0 to 1, Very Low and Low0, 1, 5
2, Medium0, 1
3, High0, 4
4, Very High4

So 0 through 3 ascend in priority, and 3 is gameplay-critical and never culled. 4 is a low-quality substitute shown only on low settings, and 5 is the reverse, shown only on Medium and above. Pairing a 4 emitter with a 5 emitter is how one effect ships two versions of itself.

Four other things gate whether an emitter exists at all: disabled, colorblindVisibility, ChanceToNotExist, and system flags bit 0x800, which strips everything except importance 3 and 4.

rate, lifetime, particleLifetime and particleLinger are shown with screenshots on the Emitter Library page.


Emitter: emission and timing

PropertyTypeWhat it does
rateValueFloatParticles spawned per second. On an isSingleParticle emitter it sets the particle count instead
flexRatepointerFlex override for rate
rateByVelocityFunctionValueVector2Scales rate with how fast the emitter is moving
MaximumRateByVelocityoption[f32]Upper bound for the above
timeBeforeFirstEmissionf32Delay before anything spawns. Useful for staggering a system into stages
periodoption[f32]Length of one emission cycle
timeActiveDuringPeriodoption[f32]How much of each period the emitter actually emits for
ChanceToNotExistf32Probability the emitter is skipped entirely on spawn
SpawnShapepointerAn IVfxShape giving the volume particles spawn inside
FlexShapeDefinitionpointerFlex variant of the spawn shape
emissionSurfaceDefinitionpointerSpawn across a surface instead of a volume
emissionMeshNamestringA mesh used as the emission shape
emissionMeshScalef32Scales that emission mesh
period and timeActiveDuringPeriod are how bursts are made

Set period to the cycle length and timeActiveDuringPeriod to a shorter value, and the emitter pulses instead of running continuously. Leaving both unset gives a steady stream.


Emitter: placement and orientation

PropertyTypeWhat it does
EmitterPositionValueVector3Where particles spawn relative to the emitter's origin. Positive Y is up
translationOverridevec3Offsets the emitter as a whole
rotationOverridevec3Rotates the emitter as a whole
scaleOverridevec3Scales the emitter as a whole
FlexInstanceScalepointerFlex override for instance scale
bindWeightValueFloatHow much the particle follows what it is bound to. 1 follows fully, 0 leaves it behind in world space
postRotateOrientationAxisvec3Axis used when hasPostRotateOrientation is set
offsetLifetimeScalingvec3Scales particle lifetime by how far the particle spawned from the emitter, per axis
offsetLifeScalingSymmetryModeu8Symmetry mode for the above
EmitterPosition or translationOverride?

EmitterPosition moves where particles spawn inside the emitter. translationOverride shifts the emitter as a whole. If one emitter is out of place use the second, if particles are misplaced within an otherwise correct emitter use the first.


Emitter: birth properties

The state a particle is handed the instant it spawns. Anything named birth* is an initial condition, not an ongoing one.

PropertyTypeWhat it does
birthColorValueColorStarting colour, RGBA
birthScale0ValueVector3Starting size
birthRotation0ValueVector3Starting rotation
birthRotationalVelocity0ValueVector3Starting spin speed
birthRotationalAccelerationValueVector3Starting rotational acceleration
birthVelocityValueVector3Starting velocity
birthAccelerationValueVector3Starting acceleration
birthDragValueVector3Starting drag
birthOrbitalVelocityValueVector3Orbital rotation. See the warning below
birthFrameRateValueFloatStarting playback rate for an animated texture
birthUVOffsetValueVector2Starting offset into the texture. Useful for desynchronising particles that share a sheet
birthUvScrollRateValueVector2Starting UV scroll rate
birthUvRotateRateValueFloatStarting UV rotation rate

Each of these has a flex* sibling (flexBirthVelocity, flexBirthUVOffset, flexScaleBirthScale and so on) that overrides it when a flex value is supplied.

birthOrbitalVelocity adds no velocity

Despite the name, this contributes nothing to the particle's velocity. It is transform-only: it rotates the particle's own matrix while its stored position continues to advance on birthVelocity and forces alone.

This matters if you are reasoning about how far a particle travels. Treating it as a tangential velocity on top of the rotation double-counts the motion and gives exactly twice the path length.


Emitter: motion over life

Where birth* sets the starting state, these keep acting.

PropertyTypeWhat it does
velocityValueVector3Velocity across the particle's life
accelerationValueVector3Acceleration across the life
worldAccelerationIntegratedValueVector3Acceleration in world space regardless of particle orientation. Gravity lives here, as negative Y
dragValueVector3Drag across the life
scale0ValueVector3Scale across the life, multiplied with birthScale0
rotation0IntegratedValueVector3Rotation across the life
directionVelocityScalef32How much the particle stretches along its travel direction with speed. Used with isDirectionOriented
directionVelocityMinScalef32Floor for that stretch
fieldCollectionDefinitionpointerForce fields. See Force fields

Emitter: colour

PropertyTypeWhat it does
birthColorValueColorColour at spawn
ColorValueColorColour across the particle's life, multiplied with birthColor. Default white
colorLookUpTypeX / colorLookUpTypeYu8What drives each axis of the particleColorTexture lookup, for example particle age
colorLookUpScalesvec2Scale applied to those lookup coordinates. Default 1, 1
colorLookUpOffsetsvec2Offset applied to those lookup coordinates
colorRenderFlagsu8Bit flags affecting how colour is applied at render time
modulationFactorvec4Modulation applied to the final colour
censorModulateValuevec4Colour used when content is censored for a region
paletteDefinitionpointerA VfxPaletteDefinitionData. See Palette
colorblindVisibilityu80 always visible, 1 only in normal mode, 2 only in colourblind mode

Reading an RGBA value

birthColor: embed = ValueColor {
    constantValue: vec4 = { 1, 0.7059, 0, 1 }
}

Channels run 0 to 1 rather than 0 to 255. To convert, divide by 255. The green channel above is 180, and 180 / 255 gives 0.7059.

The fourth value is alpha, where 0 is fully transparent and 1 is fully opaque.

For recolouring in practice, Quartz does the maths for you.


Emitter: texture and UV

PropertyTypeWhat it does
texturestringThe .dds or .tex the emitter draws. See File Formats
particleColorTexturestringGradient sampled to colour particles, usually across their life. Aimed by the colorLookUp* fields
falloffTexturestringFalloff ramp texture
textureMultpointerA VfxTextureMultDefinitionData, not a plain string. See Texture mult
texDivvec2Divides the texture into a grid, for sheet animation
startFrameu16First frame of an animated sheet
numFramesu16How many frames the sheet holds
frameRatef32How fast those frames play
uvModeu8How UV coordinates are interpreted
texAddressModeBaseu8Wrap, clamp or mirror for the base texture
uvRotationValueFloatRotates the texture
uvScaleValueVector2Scales the texture
uvTransformCentervec2Pivot for UV rotation and scale
uvParallaxScalef32Parallax amount on the UVs
emitterUvScrollRatevec2Scroll rate applied per emitter
particleUVScrollRateIntegratedValueVector2Scroll rate applied per particle
particleUVRotateRateIntegratedValueFloatRotation rate applied per particle
isTexturePixelatedboolPoint sampling instead of smooth filtering
There is no plain scrollRate

Scrolling is always scoped to what it affects. On the modern emitter the fields are birthUvScrollRate, emitterUvScrollRate and particleUVScrollRate. A bare uvScrollRate exists only on the legacy class described in The legacy component model.


Emitter: render state

PropertyTypeWhat it does
blendModeu8How the particle blends with what is behind it. Full table below
miscRenderFlagsu8Depth and blend state bits. See the warning below
meshRenderFlagsu8Render flags for mesh primitives
colorRenderFlagsu8Render flags affecting colour
passi16Draw order. Lower draws first and sits underneath
renderPhaseOverrideu8Forces the emitter into a specific render phase. Default 7, meaning no override
depthBiasFactorsvec2Nudges depth to stop coplanar surfaces fighting
DepthPushPullf32Pushes or pulls the particle along depth. Default 0. The shader calls this one PARTICLE_DEPTH_PUSH_PULL
alphaRefu8Alpha-test threshold, 0 to 255. Pixels below it are discarded. Default 5
stencilModeu8Stencil behaviour
stencilRefu8Stencil reference value
StencilReferenceIdhashNamed stencil reference
disableBackfaceCullboolDraws both sides of every face
softParticleParamspointerA VfxSoftParticleDefinitionData. See Soft particles
sliceTechniqueRangef32Range for the slice technique
CustomMaterialpointerA VfxMaterialDefinitionData replacing the default material
materialOverrideDefinitionslist[embed]Per-material overrides for this emitter
FilteringpointerA VfxEmitterFiltering, controlling where the emitter is allowed to show
AudiopointerA VfxEmitterAudio

blendMode values

These are fixed, and the same for every primitive. Each mode selects a source and destination blend factor and a blend operation.

ModeSrcDestOpWrites depthBlending
0ONEONEADDnoyes
1SRC_ALPHAINV_SRC_ALPHAADDnoyes
2ZEROINV_SRC_COLORADDnoyes
3yesno
4SRC_ALPHAONEADDnoyes
5ONEINV_SRC_ALPHAADDnoyes
6ONEONEMINnoyes
7ONEONEMAXnoyes
8INV_DEST_ALPHADEST_ALPHAADDnoyes

Reading that table in practice:

  • 0 and 4 are the additive modes. Black contributes nothing, so they are the safe ones to recolour towards black.
  • 1 is standard alpha blending, the closest thing to "normal".
  • 2 darkens, since it multiplies by the inverse of the source colour.
  • 3 is the opaque mode. It is the only one that writes depth and the only one that does not blend at all.
  • 6 and 7 take the minimum or maximum of source and destination instead of adding.
miscRenderFlags bit 0 disables the depth test, inverted

Bit 0 maps to the depth-stencil state's DepthEnable, and it is inverted: when the bit is set, the depth test is off. Setting miscRenderFlags to 1 is what makes a particle draw through geometry.

It is not a face-inversion flag, and the reading that a value of 4 turns depth writing off while leaving the test on does not hold. Depth writing is decided by blendMode instead, and only mode 3 enables it.

The comparison used is LESS_EQUAL rather than LESS, which is what lets a coplanar ground decal draw at all.


Emitter flags

Four bytes on the emitter, each carrying up to eight named bits. Text tooling exposes them one at a time as flag.

FlagWhat it does
TextureFlipU / TextureFlipVMirror the texture on each axis
particleIsLocalOrientationParticle orientation is read in local space
isLocalOrientationEmitter orientation is read in local space
isDirectionOrientedParticles orient along their direction of travel
isUniformScaleScale is locked to one value on all axes
hasPostRotateOrientationApplies postRotateOrientationAxis after rotation
isRandomStartFrameEach particle starts on a random sheet frame
doesCastShadowThe emitter contributes to shadows
isRotationEnabledEnables rotation at all
uvScrollClampClamps UV scroll instead of wrapping
isFollowingTerrainParticles follow terrain height
isGroundLayerDraws as a ground layer
useEmissionMeshNormalForBirthParticles launch along the emission mesh's normals
useNavmeshMaskMasks the effect against terrain so it does not spill over walls
ParticlesShareRandomValueAll particles draw the same random value
SortEmittersByPosSorts emitters by position
IsEmitterSpaceParticles are simulated in emitter space rather than world space
HasVariableStartTimeStart time varies per particle
isSingleParticleExactly one particle instead of a stream
doesParticleLifetimeScaleParticle lifetime scales with the system
doesLifetimeScaleEmitter lifetime scales with the system
WriteAlphaOnlyWrites only the alpha channel

Primitives

primitive is a pointer that decides what each particle draws as. Leaving it unset gives the default camera-facing billboard quad.

ClassWhat it draws
VfxPrimitiveCameraQuadA flat quad that always faces the camera. The default, and most particles you meet
VfxPrimitiveCameraUnitQuadA camera-facing quad at unit size
VfxPrimitiveArbitraryQuadA quad with a fixed orientation that does not face the camera
VfxPrimitiveMeshA mesh
VfxPrimitiveAttachedMeshA mesh attached to a bone. Adds UseAvatarSpecificSubmeshMask
VfxPrimitiveCameraTrailA trail that faces the camera
VfxPrimitiveArbitraryTrailA trail with a fixed orientation
VfxPrimitiveRibbonA ribbon
VfxPrimitiveBeamA beam between two points
VfxPrimitiveCameraSegmentBeamA segmented, camera-facing beam
VfxPrimitiveCameraSegmentSeriesBeamA series of segmented beams
VfxPrimitiveLaserA laser
VfxPrimitivePlanarProjectionProjects the texture onto a plane. Ground decals
VfxPrimitiveRayA ray
VfxPrimitiveNonRenderableDraws nothing. Used for emitters that exist only to spawn children or drive logic

Mesh fields

Mesh primitives carry a VfxMeshDefinitionData in mMesh. Note the m prefixes: these are not spelled the way the emitter's own fields are.

PropertyTypeWhat it does
mMeshNamestringThe mesh to draw
mMeshSkeletonNamestringSkeleton for an animated mesh
mSimpleMeshNamestringAn .scb or .sco simple mesh
mSubmeshesToDrawlist[string]Which submeshes render
mSubmeshesToDrawAlwayslist[string]Submeshes that always render
mLockMeshToAttachmentboolLocks the mesh to its attachment point
mAnimationNamestringAnimation to play on the mesh
mAnimationVariantslist[string]Alternative animations

Mesh primitives also carry AlignPitchToCamera and AlignYawToCamera on VfxPrimitiveMeshBase.

Mesh file types

ExtensionWhat it is
.scbStatic mesh, binary
.scoStatic mesh, ASCII text, carries joints and materials
.sknRigged mesh, the standard for champion models
.sklSkeleton paired with an .skn

An .skn and .skl pair inside a particle folder means an animated mesh. See Meshes as Particles.

Trail and ribbon

VfxPrimitiveTrailBase carries a VfxTrailDefinitionData in mTrail:

PropertyTypeWhat it does
mBirthTilingSizeValueVector3Tiling size at birth
mCutofff32Arc length at which the trail stops being extended
mMaxAddedPerFramei32Cap on points added per frame
mSmoothingModeu8Smoothing applied along the trail
mModeu8Trail mode

VfxRibbonDefinitionData carries birthTilingSize as a ValueVector2.


Sub-definition classes

Each of these hangs off a pointer on the emitter. Null means the feature is off entirely.

Texture mult

VfxTextureMultDefinitionData. A second texture multiplied over the base, the same idea as Multiply in an image editor. The emitter's textureMult field points at this object, and the actual filename is the textureMult string inside it.

PropertyTypeWhat it does
textureMultstringThe multiply texture
texDivMultvec2Grid division for the multiply texture
texAddressModeMultu8Wrap mode
uvScaleMultValueVector2Scale on the multiply UVs
UvRotationMultValueFloatRotation on the multiply UVs
uvTransformCenterMultvec2Pivot for that rotation and scale
birthUvScrollRateMultValueVector2Scroll rate at birth
emitterUvScrollRateMultvec2Scroll rate per emitter
birthUVOffsetMultValueVector2Starting UV offset
birthUvRotateRateMultValueFloatStarting UV rotation rate
ParticleIntegratedUvScrollMultIntegratedValueVector2Per-particle scroll
ParticleIntegratedUvRotateMultIntegratedValueFloatPer-particle rotation

Its flag byte carries uvScrollAlphaMult, uvScrollClampMult, TextureMultFilpU, TextureMultFilpV and isRandomStartFrameMult. Those last two really are spelled that way in the engine, so search for "Filp" rather than "Flip" when you go looking for them.

Palette

VfxPaletteDefinitionData. Colours particles by sampling a gradient texture instead of using a flat value.

PropertyTypeWhat it does
paletteTexturestringThe gradient image
PaletteTextureAddressModeu8Wrap mode for the gradient
paletteSelectorValueVector3Where in the palette to sample
palleteSrcMixColorValueColorColour mixed with the sampled result
PaletteUAnimationCurveValueFloatAnimates the U coordinate
PaletteVAnimationCurveValueFloatAnimates the V coordinate
paletteCounti32Number of palettes in the texture
Palette or Pallete?

The class and most fields use the correct spelling. The engine's own misspelling survives in exactly one field, palleteSrcMixColor, so searching a bin for "pallete" will miss nearly everything. Search for "palette".

Alpha erosion

VfxAlphaErosionDefinitionData. Dissolves the particle using a map. This is how nearly every burning-away or wipe effect is built.

PropertyTypeWhat it does
erosionMapNamestringThe erosion texture
erosionMapAddressModeu8Wrap mode for the map
erosionMapChannelMixerValueColorWhich channels of the map are used, and how much of each
erosionDriveCurveValueFloatHow the erosion progresses
erosionDriveSourceu8What drives it, for example particle age
erosionFeatherIn / erosionFeatherOutf32Softness at each edge of the boundary
erosionSliceWidthf32Width of the eroding band
LingerErosionDriveCurveValueFloatA separate curve used during linger
UseLingerErosionDriveCurveboolEnables that separate curve

An erosion map is usually greyscale, where white erodes first and black last. Multi-channel maps carry an independent pattern per colour channel, and erosionMapChannelMixer picks between them.

Distortion

VfxDistortionDefinitionData. Warps whatever is drawn behind the particle. Shockwaves and heat haze.

PropertyTypeWhat it does
normalMapTexturestringNormal map driving the distortion
distortionf32Strength
distortionModeu8Which distortion mode is used

Reflection and fresnel

VfxReflectionDefinitionData. The rim-highlight and reflection block. fresnel lives here, not on the emitter.

PropertyTypeWhat it does
reflectionMapTexturestringThe reflection map
reflectionOpacityDirectf32Reflection strength head-on
reflectionOpacityGlancingf32Reflection strength at grazing angles
reflectionFresnelf32Fresnel term for the reflection
reflectionFresnelColorvec4Colour of that term
fresnelf32Fresnel strength, the rim highlight at grazing angles
fresnelColorvec4Colour of the rim highlight

Soft particles

VfxSoftParticleDefinitionData. Softens the hard seam where a particle intersects geometry.

PropertyTypeWhat it does
beginInf32Offset before the inward fade starts
beginOutf32Offset before the outward fade starts
deltaInf32Distance the inward fade covers
deltaOutf32Distance the outward fade covers

There is a fifth mode byte selecting which of the two fades apply. A null softParticleParams pointer disables the feature outright, and there is no separate on-off field.

Linger

VfxLingerDefinitionData. Changes the particle during the linger phase rather than just delaying its removal.

PropertyTypeWhat it does
LingerRotationValueVector3Rotation applied while lingering
LingerScaleValueVector3Scale applied while lingering
KeyedLingerVelocityValueVector3Velocity during linger
KeyedLingerAccelerationValueVector3Acceleration during linger
KeyedLingerDragValueVector3Drag during linger
SeparateLingerColorValueColorA different colour while lingering

Each has a matching Use* flag: UseLingerRotation, UseLingerScale, UseKeyedLingerVelocity, UseKeyedLingerAcceleration, UseKeyedLingerDrag and UseSeparateLingerColor. Setting the value without its flag does nothing.

Materials and drivers

VfxMaterialDefinitionData holds a Material link and a materialDrivers map. Drivers animate a material parameter instead of holding it constant.

ClassWhat it does
VfxColorOverLifeMaterialDriverDrives a colour across the particle's lifetime
VfxFloatOverLifeMaterialDriverDrives a single float across the lifetime
VfxSineMaterialDriverOscillates a value on a sine wave, for pulsing

For glow and toon shader work, see Static Materials.


Force fields

VfxFieldCollectionDefinitionData, reached through the emitter's fieldCollectionDefinition. Where birthVelocity sets a particle moving, a field keeps acting on it.

PropertyTypeWhat it does
fieldAccelerationDefinitionslist[embed]Constant acceleration, for example gravity
fieldAttractionDefinitionslist[embed]Pulls particles toward a point
fieldDragDefinitionslist[embed]Slows particles down
fieldNoiseDefinitionslist[embed]Adds turbulence
fieldOrbitalDefinitionslist[embed]Spins particles around an axis

Emission shapes

SpawnShape points at an IVfxShape.

ClassWhat it does
VfxShapeSphereSpawn inside a sphere, with a radius
VfxShapeBoxSpawn inside a box
VfxShapeCylinderSpawn inside a cylinder
VfxShapeVolumeShared volume behaviour, carries its own flags
VfxShapeLegacyThe older shape system, still present on many effects

VfxEmissionMeshData handles spawning from a mesh, with meshName, skeletonName, AnimationName, meshScale, maxJointWeights, Submeshes and useSurfaceNormalForBirthPhysics.


Child particles

VfxChildParticleSetDefinitionData, reached through the emitter's childParticleSetDefinition. This is how a trail sheds sparks or an explosion throws debris.

PropertyTypeWhat it does
childrenIdentifierslist[embed]The child systems to spawn, as VfxChildIdentifier entries
boneToSpawnAtlist[string]Bones the children spawn on
childrenProbabilityValueFloatChance a child spawns at all
childEmitOnDeathboolSpawn the child when the parent particle dies rather than when it is born
ParentInheritanceDefinitionpointerA VfxParentInheritanceParams deciding what the child inherits

VfxChildIdentifier holds effect (a link), effectKey (a hash) and effectName (a string).

VfxParentInheritanceParams holds Mode and RelativeOffset. The offset is a first-class parent-relative channel, separate from the child's own EmitterPosition.

Children spawn once, at birth

There is no continuous feed from parent to child. A child system is created exactly once, at the moment its carrier particle is born, and from then on runs as an independent system on its own clock. The only teardown is the carrier particle dying.

A consequence worth knowing: for an isSingleParticle carrier there is exactly one particle and therefore exactly one child creation, and the parent emitter's emission window closing cannot stop it.

Inheritance is a mode, not a fixed chain

What a child inherits from its parent is decided by the Mode value on VfxParentInheritanceParams. When no ParentInheritanceDefinition is authored the child runs under the default mode. Any mental model that assumes one fixed set of inherited terms will be right for the default and wrong for the rest.

Child systems nest, and the engine walks them depth-first, so a three-deep nest composes at every level.

A common pattern is a parent emitter using VfxPrimitiveNonRenderable: it draws nothing and exists only to place its children.


The legacy component model

Older effects use a second, component-based emitter model that still ships in the engine. You will meet it on long-standing champions. It is documented here so you can recognise it, not because you should author new work with it.

ClassSizeRole
VfxEmitterLegacySimple13 fieldsThe simple legacy emitter, reached through the emitter's LegacySimple pointer
VfxLegacyRenderComponent66 fieldsLegacy render state
VfxLegacyPhysicsComponent37 fieldsLegacy motion and placement
VfxLegacyLifetimeComponent17 fieldsLegacy timing
VfxLegacyGeometryComponent1 fieldLegacy geometry

Many names appear on both models. blendMode, texture, bindWeight, birthVelocity, particleLifetime and others exist on the modern emitter and on a legacy component, at different offsets. When a value seems to have no effect, check which of the two you are actually editing.

Three names exist only on the legacy model:

PropertyTypeLives on
uvScrollRatevec2VfxEmitterLegacySimple
particleBindvec2VfxEmitterLegacySimple
lockedToEmitterboolVfxEmitterLegacySimple

VfxEmitterLegacySimple also carries birthScale, scale, birthRotation, birthRotationalVelocity, rotation, scaleBias, orientation, fixedOrbitType, hasFixedOrbit and scaleUpFromOrigin. Note the unsuffixed birthScale and birthRotation here, against birthScale0 and birthRotation0 on the modern emitter.

The LegacySimple pointer is what emitters in the system's simpleEmitterDefinitionData list use. If a system populates that list rather than complexEmitterDefinitionData, this is the block its emitters read.

Properties the emitter has lost

Four emitter properties were retired and will only turn up in old bins or old documentation.

PropertyRemoved inReplaced by
shape14.1SpawnShape
Material14.1CustomMaterial and materialOverrideDefinitions
materialDrivers14.1The materialDrivers map on VfxMaterialDefinitionData
flexOffset15.11Nothing directly

assetCategory was removed from VfxSystemDefinitionData in 14.15.


Things that are easy to get wrong

A short list of the misreadings that cost the most time.

AssumptionWhat is actually true
birthScale0 and birthScale1 are a min-max pairThere is no birthScale1. The 0 is a naming leftover, and randomisation comes from probabilityTables
probabilityTables picks one value from a setIt multiplies constantValue by a random draw, once per particle
birthOrbitalVelocity adds orbital motionIt is transform-only and contributes no velocity
miscRenderFlags inverts facesBit 0 disables the depth test, inverted, so 1 means the test is off
blendMode meanings depend on the primitiveThe blend state is the same for every primitive. Only mode 3 writes depth
textureMult is a filenameIt is a pointer to a whole definition class. The filename is a field inside it
mEyeCandy is an emitter settingIt is on the system
A plain scrollRate existsOnly scoped variants exist, plus a legacy-only uvScrollRate
A soft-particle on-off field existsA null softParticleParams pointer is the off switch
particleLifetime of -1 means an infinite particleIt means "live until the emitter stops". Only persistent when paired with isSingleParticle
An absent particleLinger is zeroIt defaults to particleLifetime + 10
A child dies when its parent emitter's window closesA child is an independent system. It ends when its own emitters run out or its carrier particle is removed

Names and types on this page were read from the engine's registered class layout for patch 16.16. If a property is missing or a description is wrong, it is worth fixing: see How to contribute.