Patch Version1.80.8193.14
Patch release date (PC)Dev - 2020-08-07
Patch release date (Others)
Patch release notes


Hello Neverwinter friends!

Today is the day for a new development patch, and it is a big one. Please test it thoroughly, as we intend this to hit stable in the coming weeks!

This patch is compatible with the current stable (8193.13), so you can play on servers with it that have not yet upgraded. However, some of the new features will not work on servers. To get the full experience, you will have to update both server and clients to this patch.

Patch Notes

New Lighting Engine

This patch includes a new enhanced lighting engine, that is governed by the same principles as you would see in other modern games that aim for realistic lighting. The aim is both to allow much higher quality future content, but also in large to enhance the visual quality of existing content.

Pictures say more than a thousand words:

The blue dot in the middle can slide left and right to compare before/after. The left side is the old/current render; the right side is the new lighting engine.

These are the main elements of this new lighting engine:

  • Physically based rendering (PBR), with emulation of specular reflection, surface “roughness”, Fresnel-effects and gamma correction. All in all, this gives a more realistic and “natural” look.
  • Tone mapping that prevents color distortion of bright lights and enables overbright.
  • Per-pixel lighting rather than per-vertex of the old setup, yielding much more precise light illumination levels relative to distance.
  • Full dynamic lighting, supporting up to 32 dynamic lights (previously NWN effectively only supported 6).

The lighting engine is by default on, but optional, as it is heavier on the GPU than the previous lighting model (especially if you run with 32 lights, but a minimum of 16 lights is recommended). You can turn it off in the Options menu. You can also tweak various parameters of the new lighting engine, such as attenuation and falloff. We would suggest leaving them at the defaults though, to ensure uniform content presentation.

Note that since the new lighting engine constitutes a significantly different way of computing light interaction and behavior, it is inevitable that overall illumination levels in some areas will change, which can result in certain areas becoming too bright or too dark. We have been carefully tuning the various parameters to minimize this effect, but ultimately, moving toward more realistic and sophisticated lighting will always come with this trade-off. If you find that the game has become too dark or too bright, we recommend that you adjust the brightness level by using the gamma slider accessible in the graphics options.

New Water Rendering

Water presentation has also been improved significantly. It now renders full dynamic light reflections, including sun and moon. It also shows wave displacement based on area wide and local wind sources (such as explosions) much more realistically than the previous water did.

As with the other lighting changes, some areas may appear differently, and builders using tile lights will now see them in the reflections, and may wish to edit an area’s lights so that both the area and the reflections appear as desired.

There are configuration options in the UI to turn this feature off.

Again, please visit this link to see the improvements to water in action:

Grass Rendering

Grass is now rendered sorted by distance, fixing transparency issues and making it look denser and more natural.

The comparison link posted above has visual examples of this.

Grass rendering also has been heavily optimised and should no longer pose a performance consideration, even in scenes with lots of it.

Other miscellaneous graphical improvements

Models spawned by visual effects now have fog properly applied and are not self-illuminated with a bright light anymore. This makes content spawned as visual effect render identical to other in game content, making things such as VFX spawned tiles and character equipment appear more natural.

Content import from Ossian premium modules

This patch includes all content from Darkness over Daggerford and Tyrants of the Moonsea, except the Rural Forest and Winter tileset facelifts by Zwerkules.

  • Medieval City, Medieval Rural, and Mountain Snow sets, by Zwerkules
  • Lizardfolk Interior microset
  • Seaships microset
  • Additions to several tilesets:
  • Several new docking ships groups, and a thatched-roof building, in Castle Exterior, Rural
  • New doorway tiles for Crypts and City Interior
  • 476 assorted placeables
  • 13 creature models
  • 3 shields, the Wand of Orcus, and a brass candlestick 'torch'
  • A complete "time of day" skybox texture set for the “Icy, Clear sky” skybox
  • 42 ambient Music tracks
  • 54 load screens
  • 25 assorted ambient sounds
  • 5 sound sets (for specific new creatures)
  • Palettes and blueprints for all imported Ossian content: Items, Creatures, and Placeables

Player Dungeon Master Mode

Players can now acquire and relinquish DM privileges during normal play, assuming they know the DM password. A player DM will have all of the normal dungeon master ruleset amenities: Their player character will turn invincible; they will be able to cast any spell they wish, and their skill checks will always be made against max.

However, player DMs will not gain features specific to DM characters: Their feat list will not include all the DM abilities, and they will not walk any faster. They will also not join the DM party/faction, so they will not be able to see all player parties.

Dedicated servers can turn this off in configuration.

To enter player DM mode, you can use the console commands (`dm_login <pw>` and `dm_logout`), or you can use the debug UI.

There is a new script command that can be used to distinguish between player DMs and “real” DMs:

// Returns TRUE if the given player-controlled creature has DM privileges
// gained through a player login (as opposed to the DM client).
// Note: GetIsDM() also returns TRUE for player creature DMs.
int GetIsPlayerDM(object oCreature);

As a consequence, GetIsDM() will now return TRUE for player DMs. Previously, you could rely on this being static per-connection, as true DMs could not drop their privileges.

Pathfinding improvements

Pathfinding quality in placeable and creature-heavy areas has been significantly improved, beyond the optimisations already done in 8193.13.

Your character should no longer get stuck on random placeables, or not find their way around other creatures.

Conversation script parameters

You can now specify script parameters in the toolset conversation editor, and these parameters can be queried via new the new script command:

// Returns the script parameter value for a given parameter name.
// Script parameters can be set for conversation scripts in the toolset's
// Conversation Editor, or for any script with SetScriptParam().
// * Will return "" if a parameter with the given name does not exist.
string GetScriptParam(string sParamName);

There is also a script command to set parameters when invoking other scripts via ExecuteScript.

// Set a script parameter value for the next script to be run.
// Call this function to set parameters right before calling ExecuteScript().
void SetScriptParam(string sParamName, string sParamValue);

Scripted access to SQLite databases

Full access to the sqlite API has been added.

You can access the following databases:

  • Campaign: Databases spanning modules and savegames, living in database/.
  • Module: A database attached to the running module, persisted to savegames.
  • Player: Each player character has a database attached that gets saved to the character .bic file when saving to a vault (local/server), or exporting the character in singleplayer. It also gets saved to savegames.

To get you started, please check INSTALLDIR/lang/en/docs/SQLite.txt for a short introduction and further documentation on the newly-added script commands.

Please note: This is an advanced feature, and requires a solid understanding of SQL to make robust and effective use of.

Scripted mouse targeting mode

You can now trigger cursor targeting mode from scripting:

// Makes oPC enter a targeting mode, letting them select an object as a target
// If a PC selects a target, it will trigger the module OnPlayerTarget event.
void EnterTargetingMode(object oPC, int nValidObjectTypes = OBJECT_TYPE_ALL, int nMouseCursorId = MOUSECURSOR_MAGIC);

// Gets the target object in the module OnPlayerTarget event.
// Returns the area object when the target is the ground.
object GetTargetingModeSelectedObject();

// Gets the target position in the module OnPlayerTarget event.
vector GetTargetingModeSelectedPosition();

// Gets the player object that triggered the OnPlayerTarget event.
object GetLastPlayerToSelectTarget();

A new module event has been added to support this.

Caveat: The toolset cannot currently configure this module event. You need to set it via SetEventScript() at module load.

New script actions related to item property usage

These script commands allow NWScript to properly trigger item property usage, circumventing the Talent system.

// Returns the number of uses per day remaining of the given item and item property.
// * Will return 0 if the given item does not have the requested item property,
// or the item property is not uses/day.
int GetItemPropertyUsesPerDayRemaining(object oItem, itemproperty ip);

// Sets the number of uses per day remaining of the given item and item property.
// * Will do nothing if the given item and item property is not uses/day.
// * Will constrain nUsesPerDay to the maximum allowed as the cost table defines.
void SetItemPropertyUsesPerDayRemaining(object oItem, itemproperty ip, int nUsesPerDay);

// Queue an action to use an active item property.
// * oItem - item that has the item property to use
// * ip - item property to use
// * object oTarget - target
// * nSubPropertyIndex - specify if your itemproperty has subproperties (such as subradial spells)
// * bDecrementCharges - decrement charges if item property is limited
void ActionUseItemOnObject(object oItem, itemproperty ip, object oTarget, int nSubPropertyIndex = 0, int bDecrementCharges = TRUE);

// Queue an action to use an active item property.
// * oItem - item that has the item property to use
// * ip - item property to use
// * location lTarget - target location (must be in the same area as item possessor)
// * nSubPropertyIndex - specify if your itemproperty has subproperties (such as subradial spells)
// * bDecrementCharges - decrement charges if item property is limited
void ActionUseItemAtLocation(object oItem, itemproperty ip, location lTarget, int nSubPropertyIndex = 0, int bDecrementCharges = TRUE);

Override hilite colour on objects

You can now override the mouse-over (“hilite”) colour on objects.

// Sets oObject's hilite color to nColor
// The nColor format is 0xRRGGBB; -1 clears the color override.
void SetObjectHiliteColor(object oObject, int nColor = -1);

Custom mouse cursors

You can now override the mouse cursor a ingame object presents. Additionally, mouse cursors have been unhardcoded, so you can add more via custom content (see MOUSECURSOR_CUSTOM_00).

// Sets the cursor (MOUSECURSOR_*) to use when hovering over oObject
void SetObjectMouseCursor(object oObject, int nCursor = -1);

ProgFX have been unhardcoded

A new 2da, progfx.2da has been added, that links visualeffect.2da columns. This allows for adding additional custom skin effects, beams, MIRVs, etc.

Texture replacements

You can now replace individual textures on objects at runtime

// Replace's oObject's texture sOld with sNew.
// Specifying sNew = "" will restore the original texture.
// If sNew cannot be found, the original texture will be restored.
// sNew must refer to a simple texture, not PLT
void ReplaceObjectTexture(object oObject, string sOld, string sNew = "");

This can only replace basic textures, not PLT or materials (MTR). If sOld is a tga, and sNew has a material file associated with a tga or dds of that name, then the material file will be ignored and only the basic texture will be swapped. If sOld is a material, or a texture name within a material file, this function will do nothing. (as of 12/2/2021 -Merricksdad)

Walk animations have been unhardcoded

You can add new walk anims by naming them `walk_002`, `walk_003`, etc. (001 is walkdead, 002 is hardcoded to walkinj)

Scripted wind management

The game now allows much finer-grained scripted control over the wind data.

// Sets the detailed wind data for oArea
// The predefined values in the toolset are:
// NONE: vDirection=(1.0, 1.0, 0.0), fMagnitude=0.0, fYaw=0.0, fPitch=0.0
// LIGHT: vDirection=(1.0, 1.0, 0.0), fMagnitude=1.0, fYaw=100.0, fPitch=3.0
// HEAVY: vDirection=(1.0, 1.0, 0.0), fMagnitude=2.0, fYaw=150.0, fPitch=5.0
void SetAreaWind(object oArea, vector vDirection, float fMagnitude, float fYaw, float fPitch);

Visual effects can now use PLT textures

Visual effects can now refer to PLT textures. The layer colours/indices are inherited from the object the effect is applied to (such as creatures).

Visual effects can now be scaled, rotated, and translated

When applying a visual effect, you can now scale, rotate and translate it, in relation to the parented object. The script commands have been extended to support this:

effect EffectVisualEffect(int nVisualEffectId, int nMissEffect=FALSE, float fScale=1.0f, vector vTranslate=[0.0,0.0,0.0], vector vRotate=[0.0,0.0,0.0]);

effect EffectBeam(int nBeamVisualEffect, object oEffector, int nBodyPart, int bMissEffect=FALSE, float fScale=1.0f, vector vTranslate=[0.0,0.0,0.0], vector vRotate=[0.0,0.0,0.0]);

Modules and HAKs can now contain more than 16k items

The game can now load more than 16356 resources from ERF containers (modules and haks).

New Configuration UI

The game options UI has been replaced with a new implementation that now allows access to all of the new configuration options. The “Debug UI” configuration tab has been removed as a consequence.

This UI is still work in progress, but it is useful enough to include now in the development patch.

Debug UI has been revamped, including a new NWScript evaluation helper

The debug UI has been rewritten to be leaner and expose more useful features. You can now toggle DebugMode, renderaab, rendertilepathnodes via checkboxes.

A new widget has been added that allows evaluating NWScript snippets on the running server (assuming you have DM privileges, or are in DebugMode).

Local variable access has been sped up significantly

Local variable access on objects is now O(n) in the worst case, but usually significantly faster than that. This is especially noticeable when you have thousands of variables on a single object. Previously, this could take up to 500ms to read a single variable; now access is below 10ms in these scenarios.

Art Changes

  • TDT01_G02_01,TDT01_G02_01,TDT01_G08_01: Repaired walkmeshes, #46
  • Repaired DAG01.set file to NOT offer unsupported height transitions #70
  • Eliminated a SQRT Domain error in a couple Treehouse Side Log Tiles (TTF02_B01_02,TTF02_B01_12) #76
  • TTF01_G04_05: Fixed bad texture assignment, tweaked alpha for better blending #77
  • TTF01_C01_02: Replaced wintery leaf texture from Winter tileset w/ proper Forest texture #77
  • TTF01_G01_01: Fixed a typo in TTF01.set which kept minimap from showing up #77
  • TCN01_Water01.tga: Increased size to 256x256, cleaned up tiling seams
  • TRM02: Recompiled a few tiles throwing SQRT domain errors #72
  • TDE01_H07_01: Fixed a bad texture assignment and UV's, added lava spouts to either side of bridge (w/ animloop01 toggle) #122
  • TDE01_A08_01: Adjusted lava mesh 0.382cm to eliminate a visible seam with neighboring tiles #117
  • PTM_CardTable1: Fixed Bounding Box #109
  • TDS01_D07_01: Fixed a SQRT domain error
  • Reworked a few creature blueprints to more closely match 3E #95
  • Fixed bad collisions in tn_sdoor_04 and tn_sdoor_16
  • Repaired city exterior tcn_a11_01
  • Compiled 165 more models in tno01
  • TNO01_V02_03: Fixed splash VFX on waterfall (back onto its own animloop, waterfall animation still intermittent)
  • TWC03_A04_07: Fixed broken/blinking chandelier candle animations
  • Repaired bounding box on Candlestick torch; changed light to yellow 5m; repaired mesh and fixed smoke placement #95
  • Removed erroneous palette entry from Birds category #107
  • Compiled ~200 models (mostly for DODEE)

Miscellaneous Script Commands

The StringToObject() script command can be used as the reverse of ObjectToString().

// Convert sHex, a string containing a hexadecimal object id,
// into a object reference. Counterpart to StringToObject().
object StringToObject(string sHex);

Miscellaneous Improvements

  • Texture pack support has been removed. All texture pack content has been merged into nwn_base.key.
  • GUI: The bright ambient light has been disabled in UI scenes. This results in a more natural look in chargen and the compass.
  • Nui: Windows now store position, size and collapse state in tml
  • Nui: Modal windows now autosize to parent
  • nwsync: increased check batch size for verifying existing data, dramatically speeding up process
  • nwsync: increased local recv buffer size, speeding up transfers on low framerates
  • WriteTimestampedLogEntry() now gets sent to all players as a console/debug message, if the server is in DebugMode. This is mostly useful for singleplayer module testing, when the module author uses the game log for debugging.
  • ExoConfig: Trap and highlight colors are now stored as hex codes.
  • DDS textures now support BC4 and BC5 encodings, to provide higher quality DDS options for greyscale and two-channel textures, such as height or specularity.
  • The data build now includes a, containing all 2da files from the build.


  • Fixed large creatures intruding into your personal space. #124
  • Config: The experimental “Aggressive Texture Caching” option has been removed (it is now on for everyone).
  • Sending WriteTimestampedLogEntry messages to clients in DebugMode can now be toggled off with a setting.
  • NUI expand/minimize chevrons have been inverted.
  • Chat Panes: When in split mode, second chat pane now shows CONSOLE-level messages (debug messages, etc) #18
  • Character generation: Spell school strrefs are now actually read from the 2da
  • VM: Script situations now always keep a hold of the actual bytecode they are spawned from. This fixes the game doing funny things when the underlying compiled script file is swapped out. This also fixes code closures from within ExecuteScriptChunk (and the Debug UI).
  • Store and load TemplateResRef from gff for door object types (so that GetResRef() does not return “”). #100
  • Dead players now call CNWSArea::DecrementPlayersInArea() #105
  • VM::AdjustAlignment(): fixed ALIGNMENT_ALL echoing wrong axis labels #55
  • VM::AdjustAlignment(): Game will now render the actual alignment shift that has happened, instead of the requested one: AdjustAlignment(-100) when at 50 will now say "You have shifted by -35" (to get you to 15, where the good/evil notchiness is) instead of "You have shifted by -100" but still putting you to 15.
  • VM::AdjustAlignment(): Game will now not render any feedback if no alignment shift occurred (previously, it would render "Your alignment has shifted by -100" if you requested -100, even if you were already at rock bottom).
  • Object hilite state is now properly persisted to GFF.
  • Fixed the game crashing or reading invalid memory when quickslotting spells as a DM.
  • Fixed a crash happening with drag & drop of inventory icons.
  • Area transition screens on the client no longer partially render a grey overlay.
  • Drag selection rendering in DM client was fixed.
  • The nwhak.exe binary has moved into bin/, out of util/.
  • Fixed heap overflow in ExoString::Insert (VM::Insert, dm_dumplocals)
  • DestroyArea(): no longer skip the last object; this used to leave things in object space attached to nothing
  • Movies: search path now prefers userdirectory over install, allowing users to override base movies.
  • GUI: Nuklear-based UI now emits sounds when clicking buttons. #5
  • GUI: The button “Remove Server from Favorites” in MP ui has been made to work once again.
  • GPU vendor optimisations are now detected automatically; the config key optimize-buffer-updates has been removed.
  • ambientmusic.2da: Fixed ids #80
  • Fixed a off-by-one issue when adding journal entries.
  • VM: A memleak in PostString has been fixed.


  • Toolset: Fixed bearing not being saved for placeables and doors
  • Toolset: texture pack selector was removed.
  • Toolset: Removed errant “OK” label in Area Properties #59
  • Toolset: Portrait backgrounds in object properties have been fixed.
  • Toolset: Update static lighting after changing tile light properties.
  • Toolset: The Bearing float should no longer flap sign when saving out the area gff.
  • Toolset: Improved script editor responsiveness as well as save/load module performance.
  • Toolset: Area view settings are now applied to all open tabs.
  • Toolset: A menu option to toggle AABB rendering was added.
  • Toolset: No longer select last-opened module in save UI.
  • Toolset: The UI for caching scripts has been removed, as the underlying system has been disabled for a while. It was pointless and counterproductive from a performance standpoint.
  • Toolset is now linked to 32bit oal-soft. Hopefully no more sound woes.

Campaigns and Premiums

  • Campaign SoU: Fixed the Baby Achievement
  • TotM: Small fix for floating placeables in Elmwood