Visual Effects using "programmed effects" can now be changed (outside of engine edits) using progfx.2da. This was added in patch 1.80.8193.14.
Note there is no "custom programming" this is a file of parameters for what the engine will understand when using a particular "type" of programmable FX (1 through 13).
You use the visualeffects.2da columns ProgFX_Impact, ProgFX_Duration and ProgFX_Cessation to reference lines in this 2da:
- ProgFX_Impact - Run once when the VFX is applied
- ProgFX_Duration - Run continuously while VFX is active
- ProgFX_Cessation - Run once when VFX is removed
Previously, all the values for these columns were hardcoded. With 8193.14, a new 2DA, progfx.2da is added which contains the definitions for these values.
The progfx effects are grouped by Type. Each progfx Type has different handling within the engine, and the meaning of the parameters depends on the type. Note the Type ID by default is tied to a row number (eg; Type 3 starts at 300) but that no longer has to be the case.
Some Beamdog documentation available here: https://gist.github.com/mtijanic/97f309b8d9262f0cf4f7dfba6618ea6a mostly translated here.
progfx.2da Exceptions
progfx.2da only applies to visualeffects.2da. The problem with this is that vfx_persistent.2da cannot make use of it (this also defines models to use for visuals). There is one line that has a programmed effect - line 7 - blade barrier - applies environmental mapping as per id 2 below. No other lines can have this added, or any other progfx.2da changes.
2DA Contents
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Label | BeamLightning | This is just a name for the effect for readability. No effect. | |
Type | 1 | 1-13 | Type ID. Generally the TypeID is tied to the hundreth position in the 2da file itself, eg; Type 3 starts at line 300. |
Param1 | See below | Varies | See below |
Param2 | See below | Varies | See below |
Param3 | See below | Varies | See below |
Param4 | See below | Varies | See below |
Param5 | See below | Varies | See below |
Param6 | See below | Varies | See below |
Param7 | See below | Varies | See below |
Param8 | See below | Varies | None seem to use this one for some reason. |
Types Documentation
1: Skin Overlay (barkskin, stoneskin, etc)
This will set the texture of the creature to the given model texture, along with some altering of impact effects.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 1 | 1 | Set to 1 for this type. |
Param1 | vdu_tex_stone | Model name | Model Name with overlay (vdu_*) |
Param2 | stone, wood | name of entry in appearancesndset.2da ArmorType column value IE: stone, wood, scale, ethereal, leather, chitin, plate, chain, crystal | Tied to appearancesndset.2da ArmorType column (and possibly the counterpart weaponsounds.2da) which controls what noises weapons make when hitting it. Needs testing to see what happens if left blank, or set to an odd value. |
Param3 | 354 | visualeffects.2da line | The visualeffects.2da line played when the creature under this visual effect is damaged replacing usual "chunk" effects (and is "Medium" sized or larger). VFX_COM_CHUNK_STONE_MEDIUM for petrify. |
Param4 | 353 | visualeffects.2da line | The visualeffects.2da line played when the creature under this visual effect is damaged replacing the usual "chunk" effects (and is "Small" sized or smaller). VFX_COM_CHUNK_STONE_SMALL for petrify. |
Example progfx.2da lines:
2: Used for environment mapping
Sets an environment map file to be used by the VFX. The default lines do not actually seem to be used by the default game visual effects, and there doesn't actually appear to be any vdu_envmap_XXX files in the game files. Presumably the default lines are there just in case/show what the game would do by default.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 2 | 2 | Set to 2 for this type. |
Param1 | vdu_envmap_000 | Model name | Envmap Name |
Example progfx.2da lines:
3: Static Glow effects.
Sets a static glow effect to the model affected.
Commonly used for VFX_DUR_AURA_XXX visualeffect lines as ProgFX_Duration, although can be used in ProgFX_Impact as well.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 3 | 3 | Set to 3 for this type. |
Param1 | 0.25 | 0.0 - 1.0 | Amount of Red |
Param2 | 0.35 | 0.0 - 1.0 | Amount of Green |
Param3 | 0.5 | 0.0 - 1.0 | Amount of Blue |
Example progfx.2da lines:
4: Lighting addition or removal
Lighting models to provide lighting (or remove it - like if blinded!). There are likely a lot of hardcoded relations to these lines used by the game feats like Darkvision or certain effects like Ultra Vision.
The normal ones appear to be used for ProgFX_Duration
The Fade ones appear to be used for ProgFX_Cessation
Note there are references to the default visions like Dark Vision here, therefore if you alter the progfx.2da or visualeffects.2da line references these effects can apparently be altered when loaded by the engine. May be worth testing.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 4 | 4 | Set to 4 for this type. |
Param1 | White_5m | Model animation name | Animation name of the Param7 model we are using. EG: "White_5M" is that animation node. Doesn't seem to be case sensitive (the model for fx_light_clr has it down as "white_5m") |
Param2 | 1 used for usual duration -0.31 used for the "cessation" (ie when a light source is removed) | Float | Animation speed. Fading is negative -0.31. |
Param3 | 0/1 | Boolean | Cast shadows or not (5M ones do not by default cast shadows). |
Param4 | 13 (Area Blackout / Blind Vision) - When blinded with EffectBlindness or EffectDarkness (which detects Trueseeing or Ultravision, which can skip the blindness), applied using VFX_DUR_BLACKOUT (5) 20 (Lights) - Usual lights (eg; Torches, magical light rings) - various VFX lines, VFX_DUR_LIGHT_* 49 (Ultra Vision) - For countering Darkness (thus is higher), using EffectUltravision, applied using VFX_DUR_ULTRAVISION (244) 50 (Darkness) - applied using VFX_DUR_DARKNESS (1) but we don't think this is used by EFfectDarkness itself. 51 (Darkvision) - The racial feat FEAT_DARKVISION or item property "Darkvision", applied using VFX_DUR_DARKVISION (182) 52 (Low Light Vision) - The racial feat FEAT_LOW_LIGHT_VISION, applied using VFX_DUR_LOWLIGHTVISION (243) 53 (Blind Vision) - Blind Vision appears to be for those without any of the above effects applied. So default "humans" in otherwise dark areas get this. By default actually lights up the area a bit. TODO: Write a proper "Vision" page to explain the above, with pictures, and how to make alterations to each type. | Integer | 20 for the normal lights. It is the Priority of the light. No idea how it relates to other in-game lights (what priority are they by default - eg; a placeable?) The priority is for what one will get applied if more than one exists on a player. EG: Equipping a torch turns off Darkvision, but a torch does not override Blindness. The special VFX for different "visions" probably are all used by hardcoded engine calls. |
Param5 | 1 for Darkness, Darkvision, Blindvision, Low Light Vision else 0 | Boolean | Presumably since these are, well, the things done in "the dark" it toggles if the area is dark == apply this. How "dark" is calculated by the game is a mystery! |
Param6 | 1 for LightAreaBlackout and FadeLAreaBlackout | Boolean | Presumably if it's "Area" blackout if 1 affect the area too? If so how? No idea! Beamdog documentation: "Attach to scene". Possibly does additional light removal to really make things super dark. |
Param7 | fx_light_clr | FX Model name | Model to load that relates to some of the above parameters, specifically Param1 and Param2. |
Example progfx.2da lines:
5: Alpha transparency modifiers.
These are used to apply VFX_DUR_INVISIBILITY, VFX_DUR_GHOSTLY_VISAGE, VFX_DUR_GLOW_ and a few others as ProgFX_Duration.
Since there is no model mentioned it's just a alpha and colour change.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 5 | 5 | Set to 5 for this type. |
Param1 | 0, 0.5, 0.001 | Float 0.0 - 1.0 | Amount of transparency (lower bound). Can be 0 as per cutscene invisibility or low values like 0.001 it seems |
Param2 | -1, 0.25, 0.5, 0, 1 etc. | Float -1 or 0.0 - 1.0 | Red value (if -1 then ignore colours and keep original?) |
Param3 | 0, 0.25, 0.4, 0.96 etc. | Float 0.0 - 1.0 | Green value |
Param4 | 1, 0.25, 0.5 etc. | Float 0.0 - 1.0 | Blue value |
Param5 | 0, 1000, 6000 | Milliseconds | Time between fades presumably |
Param6 | 0, 1, 0.80 | Float 0.0 - 1.0 | Amount of transparency (upper bound). If we're fading (Param5) we go towards this value, then presumably back to Param1 value. EG: VFX_DUR_GHOSTLY_PULSE does 0.001 transparency (nearly not there) to 1 (entirely there) over 6 seconds then would do 6 seconds back again. |
Example progfx.2da lines:
6: Pulsing Aura glows - fades between 2 colors
Pulses two colours on the given model. This is used for VFX_DUR_BLUR and VFX_DUR_AURA_PULSE_XXX_YYY visualeffects.2da lines.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 6 | 6 | Set to 6 for this type. |
Param1 | 1, 0.25, 0 | Float 0.0 - 1.0 | First colour; Amount of Red |
Param2 | 1, 0.5, 0 | Float 0.0 - 1.0 | First colour; Amount of Green |
Param3 | 1, 0.17, 0 | Float 0.0 - 1.0 | First colour; Amount of Blue |
Param4 | 1, 0.82, 0 | Float 0.0 - 1.0 | Second colour; Amount of Red |
Param5 | 1, 0.1, 0 | Float 0.0 - 1.0 | Second colour; Amount of Green |
Param6 | 1, 0.83, 0 | Float 0.0 - 1.0 | Second colour; Amount of Blue |
Param7 | 1000 | Milliseconds amount | Presumably the amount of seconds to go from the first colour to the second colour. Once reached the second colour it takes the same amount of time to fade back to the first. |
Example progfx.2da lines:
7: Beams
Within original content, beams are used solely for EffectBeam which adds nwscript parameters for the "source" and "target" (so you can do a penagram on the ground if you wanted).
What this actually does is more useful than it sounds. One type of emitter is a point-to-point emitter (P2P) which moves a visual effect along a track from source to target point. There are three types of P2P emitter available within NWN.
1) Bezier
2) Gravity
3) Lightning
Beams within original content use the lighting emitter type in which a series of lightning decal graphics is placed along a line from source to target. The number of decals placed is dependent upon the builder, but the number must be a binary number (2, 4, 8. 16, 32, 64, etc.). Each decal is overlapped slightly, and options within the lighting type allow you to kink the lightning by skewing each decal in the line. No kink produces a straight beam appearance.
The other two P2P effects toss out emitted decals or chunks at the source, and they migrate toward the target point. Normally, the target point is defined by an AuroraRef dummy within the MDL file (the position of the dummy is often backward from where the emitted particles will go). However, with the Beam progFx, what you're doing is having the engine detach the beam target from that AuroraRef and place it on the location of the target object. This allows you to now use both Bezier and Gravity "beams" in P2P ways with the target object being the actual target. You're no longer confined to lightning type emitters.
Note: the AuroraRef node is NOT being moved to the target object. If you parent parts of the mesh to the AuroraRef dummy, they will remain where they were in the original MDL layout. What is actually happening is the target point is being removed from the dummy and placed on the target object.
The main thing here is the model is now unhardcoded - go mad adding your own (by editing the existing even).
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 7 | 7 | Set to 7 for this type. |
Param1 | vdu_beam000 vim_rayfire | Model resref name | Visual effect model resref name |
Param2 | cast01 | Animation name | This may be a animation name to play (if the source is a creature) - still needs testing, does it function - and if so how long does the animation play (and does it play if other things are going on). Likely it does default to cast01 if nothing is specified/something invalid is used |
Example progfx.2da lines:
8: Stops models rendering
This would obviously remove the model from view, there appears to be no parameters so there is likely no reason to create duplicates of this line, but reference ID 700 to use it.
Used on visualeffects.2da line 120 - VFX_COM_UNLOAD_MODEL with the entry being tied to ProgFX_Impact. It's unknown if the game uses this VFX line or the 700 progfx.2da line at all (VFX_COM_ are instantly applied "combat" effects...but what would make a model disappear?).
Presumably a good one to use if you want another VFX to apply such as "blowing up a target" where if the model was still there it'd look weird.
The lexicon suggests this does nothing however. Possibly it only works in certain circumstances? Also how would you remove the fact the model is now gone? (possibly some SetAppearance calls may work but better be sure if using this!).
Example progfx.2da lines:
9: Chunk Model
VFX_COM_GIB uses this for it's ProgFX_Impact. This is likely the engines hardcoded high violence chunking - when like EffectDeath is used with bSpecacularDeath or similar (see notes here).
Since there are no parameters presumably we cannot force a particular chunk to be used. Using VFX_COM_GIB in EffectVisualEffect may also be buggy and it might be just only usable by theg game.
Example progfx.2da lines:
10: MIRV (projectiles like Magic Missile)
Magic Missiles and Acid Arrows! The models can now be changed/new ones be added and the speed and projectile type can be changed. The MIRVs are randomised in direction if using certain projectile types.
This allows you to have fireballs throw from the ImpactScript for instance instead of being part of the spells.2da line definition or using wonky ActionCastSpellAtObject parameters (which miss a lot of projectile types).
Note: After testing even the slowest speeds here (log) tends to be much too fast - especially for "Spiral" (used for Hellball) where it messes up entirely. Needs more speeds to be effective for longer duration projectile types.
log nwscript code (magic missile, the slowest):
float fDist = GetDistanceBetween(OBJECT_SELF, oTarget); float fDelay = fDist/(3.0 * log(fDist) + 2.0); eg: fDist = 20.0f: 3.38 seconds
llnear nwscript code (will do a linear distance calculation. This is modified from acid arrow twice but is twice as fast):
float fDist = GetDistanceToObject(oTarget); float fDelay = (fDist/50.0);
linear2 nwscript code (acid arrow, linear half speed):
float fDist = GetDistanceToObject(oTarget); float fDelay = (fDist/25.0);
Note these are used in the ProgFX_Impact (eg; VFX_IMP_MIRV) it is an "instant" effect but with a visual that goes on. So you have to delay each hit by a certain amount to get the right "impact time" to, say, do damage.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 10 | 10 | Set to 10 for this type. |
Param1 | vpr_magmisl | Model resref name | Visual effect model resref name |
Param2 | 340 | spells.2da line...for some reason | 340? It's line SHADES_Cone_of_Cold in spells.2da which is random. But confirmed by Beamdog it's the spells.2da line - which presumably is used to load spells.2da info of the projectile (although if EffectVisualEffect creates the projectile it probably already has that info loaded?) It is likely best to leave this as 340 to not have any issues, or set it to a line with no Projectile information (which 340 doesn't have). After testing setting it to a line with any projectile info doesn't do anything either. Probably unused by the game. |
Param3 | 0, 2 |
| Orientation - if needed. 0 if Magic Missile or Electric Magic Missile, 2 otherwise (arrows and darts). |
Param4 | 4, 1 |
| Seems to be PROJECTILE_PATH_HOMING (1) for Acid Arrow and PROJECTILE_PATH_ACCELERATING (4) for Magic Missiles. The values to the left are what the different options are. The travel time is controlled by Param5. |
Param5 | log, linear2 | log linear linear2 | The distance caluclation that you can then use in spell scripts to time impacts and damage. See above for nwscript info. "log" time to target scales logarithmically; "linear" scales linearly; "linear2" scales linearly, half speed; If left blank appears to use "log" as a default. |
Example progfx.2da lines:
11: Variant MIRV with sound and impact sound (Only used for moo cows / cheat)
Not sure how useful this is since it's used by the engine for the cheat command, and it doesn't have the same parameters as the MIRV options.
The most useful thing may be Param2 which is a one-off "source" sound (from when the projectile starts) so could be a crossbow going off or something for a bolt to appear.
I'm not sure what the distance / time calculations if using this is. Cows move in weird ways...!
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 11 | 11 | Set to 11 for this type. |
Param1 | vpr_kngpow | Model resref name | Visual effect model resref name |
Param2 | c_cow_atk1 | Sound resref name | One off sound when used, as an "Initial Sound". Sound itself doesn't repeat only fires once from source of VFX. |
Param3 | c_cow_dead | Sound resref name | Likely the same as "SoundImpact" column in visualeffects.2da entry. |
Param4 | 4 | Projectile Type:
| Since you can't specify a travel time this must be set, presumably to "log" but might be something slightly different - needs testing (cows are weird). |
Example progfx.2da lines:
12: Spell Casting Failures - model node attached VFX
Not sure where we can even make use of these. They are used in the VFX lines VFX_FNF_SPELL_FAIL_HEAD and VFX_FNF_SPELL_FAIL_HAND.
However the engine probably just calls these VFX lines and loads the approprite bits (so leave the default alone).
Possibly it allows some stuff with custom lines where a vfx model is tied, say, to a creatures head or arm or something similar, although it may not orientate it properly.
Column Name | Example | Valid Values | Description and Notes |
---|---|---|---|
Type | 12 | 12 | Set to 12 for this type. |
Param1 | headconjure handconjure | Model target node name | A model node since these are listed in .mdl files for creatures so the source of where the VFX will go |
Param2 | vimspellfail | FX Model resref | The vfx file to play |
Example progfx.2da lines:
13: Freeze Animations
This would obviously just freeze animations. There are no parameters so there is likely no reason to create duplicates of this line, but reference ID 1300 to use it. The VFX line used by default is VFX_DUR_FREEZE_ANIMATIONS.
Example progfx.2da lines: