- An effect (
fNNNNNNNNN.fxr, FXR3) is a tree of containers → effects → actions. Each action holds untyped fields and keyed, curve-able properties. - Effects start from four places: the map (SFX regions: mist), objects (ModelSfxParam: candles, torches), clips (TAE 96: the Estus Flask) and the floor (footsteps through FootSfxParam).
- Water ripples while wading are particles of the foot effect, drawn into a hidden ripple map that bends the water, not onto the screen.
- DS3's unlit particle shader squares the colour and premultiplies the texture by its alpha, so a particle adds light ∝ alpha³. Missing that made our heal glow 10-40× too bright.
1FXR3, the effect format
Effects live in sfx/frpg_sfxbnd_commoneffects_effect.ffxbnd and per-area bundles, with textures and model particles in
_resource bundles. Properties carry a type (1-4 components) and an interpolation (constant, stepped, linear, curves). A keyed property is
laid out as: the key count, a min and a max, the key times (0-1 of the life, or seconds of age), the values, then curve extras data.
EvenTorset's fxr library, the modders' reference, names each action's fields per game fxr. These are the actions our importer reads:
| Action | Name | What we take |
|---|---|---|
| 128 / 129 | NodeAttributes / ParticleAttributes | How long the emitter runs / a particle's life |
| 131 | ParticleModifier | Speed, scale, colour |
| 300 | PeriodicEmitter | Interval, per emission, total |
| 404 / 501 | BoxEmitterShape / CircularSpread | Spawn volume / cone angle |
| 55 / 60 | ParticleAcceleration / ParticleSpeed | Gravity (positive pulls down) and acceleration |
| 35 | StaticNodeTransform | Offset and rotation |
| 132 | SFXReference | Play another effect (121002 → 120002 → 120001) |
| 603 | BillboardEx | Texture, flipbook columns and frames, blend mode, size, colours over age, rotation and spin |
| 605 | Model | A FLVER drawn as a particle (the Estus Flask) |
| 609 | PointLight | Colour, intensity, radius, flicker |
Most of what the effects look like is in their sprite sheets: flipbooks of 8 × 8 frames, shown here as they add up (colour × alpha on black):

s11602: the droplet spray of a step in water
s11434: a ripple ring, drawn flat into the water's ripple map
s11630: the dust a step kicks up on dirt
s11629: torch fire, 3 at a time every 0.4 s
s11634: the ground mist, 10 s per particle
s11636: wispy puffs of the Estus heal (alpha 0.05-0.3)2From a footstep to a ripple
a000_020100 carries TAE 128 PlaySound with SoundType 8 "Floor Material Determined", sound 2001, at each footfall (0.233 s, 0.6 s)fields2[1] is 1, so they're added into a half-size height map instead of the screen; the water's surface reads its slope and bends its waves (Renderer). Only the spray is a spriteFootEffectHeightType0 is 1 on every water row: on the liquid's surface, at the lower of the two foot bones
DS3's chain and numbers. Until 2026-10-15 the importer scaled every emitter by eye, which hid two misread actions (131's speed taken as the life, 55's gravity as a launch speed). Read by name, the scale factors went away. Until 2026-10-16 the rings were drawn as glowing sprites; a capture of walking through water showed DS3 draws them into the ripple map. We only spawn the water rows; dry ground's dust looks too big at our reading of its size.
3Placed effects: the mist
The MSB places effects with SFX regions data. m40 has 18:
| Effect | Name (translated) | What |
|---|---|---|
840040 ×7 | 霧 室内 10×10 "fog, indoor, 10×10" | Ground mist along the Cemetery's start: one particle every 0.667 s in a 10 × 1 × 10 m box, 5 m wide, living 10 s |
833002 ×3 | 霧_遠景用 "fog for distant views" | A sparse bank in a 50 × 50 × 200 m box |
840031 ×3 | ライトシャフト "light shaft" | The shrine's shaft model (not read) and dust motes |
840060 ×5 | 蝋燭光源 "candle light source" | A point light only |

4Effects on objects: candles and torches
An object's effects come from ModelSfxParam, row = model number × 1000 + the part's relative id, which lists up to ten (effect, dummy poly) pairs.
Candles · o391000
409 placed, 210 lit. Row 391000000 "Candle One" → effect 839010 on dummy 200: one 0.135 m pulsing billboard per wick, anchored at its bottom, plus a point light. The wick offsets only land on the wicks with X mirrored (DS3 is left-handed).
Torches · o004665
12 placed, 10 lit. Effect 800022: the fire flipbook, and a 609 light of radius 5 m that fades in over 5 s and flickers every 0.25-0.5 s between 0.875 and full.
Bonfires · o000100
No ModelSfxParam row. Effects 1010-1014 are the same flames with more emitters each. Which one a lit bonfire burns isn't traced; we use 1011 guess.
Light from an effect = colour² × alpha × 10, squared like the gparam's colours, and drawn as DS3 draws map lights.


5Effects from clips
TAE event 96 SpawnOneShotFFX: effect id, dummy poly, slot, then flags for ignoring the dummy's angle, following it and so on. The imported clips use 38 effects. The Estus Flask shows the parts:
| Clip | Span | Effect | Dummy | Slot |
|---|---|---|---|---|
| 50110 start | 0.2-0.83 s | 301000 the flask (a model particle, s07002.flver) | 901 right hand | 1 |
| 50111 gulp | 0-1.0 s | 301000 | 901 | 1 |
| 50111 gulp | 0.27-1.0 s | 301002 the heal's glow | 8 (Spine2) | −1 |
| 50112 end | 0-0.5 s | 301000 | 901 | 1 |
The flask carries across three clips without a break because they share slot 1 guess. The effect's frame was settled from a capture of DS3 drinking: in dummy 901's matrix the flask sits at Rz(90°)·Rx(180°), so DS3's effect frame is the dummy turned half round its up, Z forward, Y up. Our first two tries held the bottle upside down. In that capture the flask is tinted (1, 0.27, 0.01) × 5: the liquid glows orange not done.


6DS3's particle shader
DS3 draws each emitter as one tessellated draw of its particles as points. The pixel shader, read from DXVK's SPIR-V of a capture of the heal capture:
C = vertex colour (colour 1 × colour 3); L = |C|; n = C / L
t = texture; a = clamp(t.a + TEXCOORD5, 0, 1)
if premultiplyAlpha: t.rgb *= a
rgb = L × cb0[9].rgb × (t.rgb × n)² the colour's direction and the texture squared, its length kept
alpha = C.a × a × cb0[9].w × soft-depth fade blend: src × srcAlpha + dst
A colour of (2.5, 1.56, 0.63) comes out (2.07, 0.81, 0.13) × t²: deep orange, not near-white. cb0[9].rgb is the emitter's multiplier × 0.65217
(where that constant comes from isn't known). One constant read 0 through the bindings but was on: RenderDoc's pixel history settled it.
Getting the heal glow right
At first ours looked like a flame with a flat bottom, and far too bright. There were four faults: (1) a "floor" fade meant for splashes cut off every puff's lower half; (2) misread actions made the puffs 1 m instead of 0.56 m and ran their flipbook in 0.28 s instead of 1 s; (3) the colour wasn't squared; (4) no premultiply, so they were 10-40× too bright. Measured against DS3's frame (the light the particle draws add to the HDR target), it was 40,000+ against DS3's 3,667; now it's 2,300-2,800.
Unlit particles (fire, the heal) use DS3's shader. Lit ones (mist, splashes) keep ours. Not done: DS3's depth blend (particles pulled up to w = size/2 toward the camera, so the glow stays on the body), random frame and scale, and frame blending.
7Hit effects: read, not done
victim material (NpcParam.materialSfx: hollows 110 "Flesh _ Weakness")
→ HitEffectSfxConceptParam[material].SfxConceptId[attack material] → 210 "Blood (dead) _ Front"
→ HitEffectSfxParam row: concept + attack direction → HitSfxId[attack power]
→ effect 221401 in the common bundle
The blood effects play child effects of six dark red flipbook billboards. Spawned at the hit point, they sat inside the victim's body. The spray must come from actions we don't read yet. Blood and sparks aren't done.