Table of Contents

How to override core scripting functions


This article presents a technique that can be used to override NWN Built-In script functions. It does NOT give you any magic knowledge to circumvent hardcoded functionality in NWN, it merely shows how to globally replace core engine script functions in your module with your own versions.


Background Information

These things are useful to keep in mind before reading on further: All NWN script functions are defined in a file called nwscript.nss, which can be found in the game resources. NWScript.nss is used by the toolset to compile your scripts into ncs files. Scripting functions in nwscript.nss are mapped to the built in engine functions based on their position in the file. That means that deleting, adding or moving scripting commands around in the file is going to break every script in the game.

Example:

Swapping Random(int) and PrintString(string) in the file would cause the scripting command 
Random() to behave like PrintString(). 

However, since Random takes an integer as input parameter and PrintString takes a string, the toolset would now fail to compile any script that includes a function call to these functions. The game has the compiled .ncs version for all bioware scripts in the resources. That means that even if you change nwscript.nss, those scripts will not behave differently from how they worked before as they do not get recompiled unless overridden in a module.



A friendly warning…

This article assumes that you have some experience with advance scripting in NWN. Messing around with nwscript.nss (see below) is dangerous and can break every script in your module at once.

NEVER EVER release a modified nwscript with a hakpak or .erf. Don't do it.



Why do this ?

There are a number of good reasons on why you may want to override one of the core engine functions in your module.


Most of these effects could also be achieved by just creating and calling your own functions from one of your includes, but that means that any script you import into your module from other sources (i.e. the vault) needs to be updated with your function calls and that any additional person that works on your module will need to memorize your redefined function names and remember to use those instead of the real thing.



How to do this

Let's assume you want to Log every call to PrintString() in your module. You could do that by writing your own function MyPrintString(), putting it in an include file (i.e. myinclude.nss) and including this file into every single script you write. That works and is a fine approach for most cases.

But there is another option - universally mapping PrintString() to MyPrintString(), at the source.

Knowing that nwscript.nss holds the definition to PrintString, you can open nwscript.nss, find the definition for PrintString and change it to MyPrintString().

However that would only change the name of the command, it would not add whatever functionality changes you added to your version of MyPrintString.

But if you create a new include file, let's say “engine_include.nss” and add the following:


You bnow have created a wrapper function around PrintString() by redirecting it to your own function in the include file where you can add your own code.

All you have to do now is to add the #include “engine_include” statement to the top of each file in your module, which can be done easily by using an advanced text editor like EditPlus2, Ultra Edit, vi or a perl script over all .nss files in your nwn\modules\temp0 directory while the module is open in the toolset and saving the module afterwards (I did the same when inserting the spellhooks into every spellscript for the Hordes of the Underdark Expansion). Or, depending on your module setup, you may already have a custom include file included in all your scripts and just including your function redefinition into that file will work without additional steps required.

Once all that is done, you have a private hook into every engine function you have overridden, allowing you to insert debug or profiling code, making functionality changes and do all kinds of other interesting strings with these engine functions.



Caveats


Georg Zoeller dom@gulbsoft.de, 2006-01-31