This documentation is © by the Avlis Team and the APS/NWNX Linux Conversion Group
Visit us at Sourceforge project page and
http://avlis.blackdagger.com
APS is a set of scripts written for Neverwinter Nights that work with NWNX2 to produce reliable persistence in a module. At the heart of the APS is an include file that lists a number of custom made functions for governing persistence. These functions can be used as is in your module or changed to suit your needs.
NWNX2 is a program that loads the NWN server and injects the database functionality into the server. Setting special string variables using NWScript triggers the database requests. The resulting data can be read with the usual string functions. It uses no hakpaks, and the only in-game NWN modification necessary is the addition of either the script for APS, or your own custom modified Structured Query Language (SQL) statements. Whenever a script wants to generate a SQL query, it calls our APS functions and the Extender pulls the query out of the memory of the NWN server. It then passes it to the database, and writes the result of the query back into the memory of the server. The database has been tested with Microsoft Access and MySQL so far. Conceivably, any database with a decent ODBC driver will work. Also, because of the nature of ODBC logistics, multiple servers can be linked up to one database file to produce reliable cross-server persistence. A variable can be set on one server and checked on another.
After NWNX2 has loaded the server and rotated the log files, it takes over responsibility for restarting the server should it crash. It does not depend on a specific version of the server (1.29 as of this writing) and thus should work with upcoming releases, too. The current version has been tested with the following Linux distributions: Debian 3.0 (woody).
We have included a demo module that illustrates how to use APS/NWNX and makes creating the database tables easy, and a second module demonstrating how persistent containers can be implemented.
Licence NWNX2 has been extensively tested on Debian Linux 3.0 (woody).
Download the file, place it in a temporary directory and untar and unzip the
file (tar xvfz Now edit nwnx2.ini and nwnstartup.sh and put in relevant changes for your
local settings From your nwserver directory run nwnstartup.sh by itself or
in a while loop like the following to have it autorestart on crash
void SQLInit()
Setup placeholders for ODBC requests and responses. This functions reserves memory APS and NWNX
use for communication. Call this function once in the module load event.
SetPersistentString(object oObject, string sVarName, string sValue,
int iExpiration=0, string sTable="pwdata")
This sets a persistent string on an object. The object can be
any valid object in the game. The command works the same way the usual
SetLocalString function works, except you can optionally add a little more
information:
SetPersistentInt(object oObject, string sVarName, int iValue,
int iExpiration=0, string sTable="pwdata")
This sets a persistent integer value on an object. The object can be
any valid object in the game. The command works the same way the usual
SetLocalInt function works, except you can optionally add a little more
information:
SetPersistentFloat(object oObject, string sVarName, float fValue,
int iExpiration=0, string sTable="pwdata")
This sets a persistent float value on an object. The object can be
any valid object in the game. The command works the same way the usual
SetLocalFloat function works, except you can optionally add a little more
information:
SetPersistentLocation(object oObject, string sVarName, location lLocation,
int iExpiration=0, string sTable="pwdata")
This sets a persistent location on an object. The object can be
any valid object in the game. The command works the same way the usual
SetLocalLocation function works, except you can optionally add a little more
information:
SetPersistentVector(object oObject, string sVarName, vector vVector,
int iExpiration=0, string sTable="pwdata")
This sets a persistent vector on an object. The object can be
any valid object in the game. The command works the same way the usual
Set local variable functions work, except you can optionally add a little more
information:
GetPersistentString(object oObject, string sVarName, string sTable="pwdata")
This function works in the same manner as GetLocalString. It gets the
persistent string from object oObject.
GetPersistentInt(object oObject, string sVarName, string sTable="pwdata")
This function works in the same manner as GetLocalInt. It gets the
persistent integer value from object oObject.
GetPersistentFloat(object oObject, string sVarName, string sTable="pwdata")
This function works in the same manner as GetLocalFloat. It gets the
persistent float value from object oObject.
GetPersistentLocation(object oObject, string sVarName, string sTable="pwdata")
This function works in the same manner as GetLocalLocation. It gets the
persistent location value from object oObject.
GetPersistentVector(object oObject, string sVarName, string sTable="pwdata")
This function works in the same manner as the other get local variable functions. It gets the
persistent vector value from object oObject.
void DeletePersistentVariable(object oObject, string sVarName, string sTable="pwdata")
This function deletes a variable from the database.
void SQLExecDirect(string sSQL)
Executes a SQL statement. If the statement returns a result set, you can read the data
with the next two functions.
int SQLFetch()
Position cursor on next row of the resultset. Call this function before using SQLGetData(). int SQLFirstRow() (*deprecated*)
Function is deprecated but still there for backward compability. Simply calls SQLFetch().
int SQLNextRow() (*deprecated*)
Function is deprecated but still there for backward compability. Simply calls SQLFetch().
string SQLGetData(int iCol)
Return value of column iCol in the current row of result set sResultSetName.
Comments
A new window "ODBC Microsoft Access Setup" will appear where you have to make some settings.
The data source name has to be "nwn" (without the quotes). The description can contain any text you like. Next,
select "Create..." and browse to the location where you want your new database to be
stored. Type in a name (e.g. nwn.mdb) and hit OK. The new database has now been created and
all settings have been made. Click OK again to close the "ODBC Microsoft Access Setup" window.
Start NWNX/APS according to the instructions in Section V.1 (see below) and load "aps_demo" in the
server. Next connect to your server with the Neverwinter Nights client. You will see several different
signs in front of you (from left-to-right): Create Tables, Store variable in database,
and Load variable from database. Each sign performs an action when you click on it:
Now click every sign once, starting with the one on the left (Create Tables).
If the last sign sends you the message "Retrieved variable from database: testValue" your
setup is ok and you're ready to start using APS.
Note: This is the most basic setup. We encourage you to use more sophisticated databases
and data structures if you feel confident to do so (see below).
As there is an almost unlimited amount of different databases out there, we can't give
detailed instructions for all of them. If you want to use a database server like MySQL
or MSSQL, try to follow the steps described above accordingly:
Here is an example create statement for MySQL
(taken from aps_demo.mod, script demo_createtable):
After you have installed both the APS and NWNX, and you have written some test
scripts that use our functions, you are ready to begin running your server.
After you have built your module and saved it, you're ready to try it out. Go
to the directory where you installed the Linux nwserver run the command "./nwnx2".
You will see NWNX2 write some information to the terminal and shortly after that the
NWN server starts.
Right before NWNX2 loads the server, it rotates it's own and the server's log files. You
will find directories names "logs.0.1"..."logs.0.9" below your "logs.0" directory. The
directory "logs.0.1" always contains the newest logs, and "logs.0.9" contains the oldest logs.
The current logs are always found in the "logs.0" directory. All log files older than those
in "logs.0.9" are deleted to preserve disk space.
All SQL activity is logged to a file called "nwnx.txt". This file is created
in your "logs.0" (or .1, .2, etc.) directory and looks like that:
The NWN Extender will make sure your server is restarted should the module
crash. You can specify any commandline options Bioware's dedicated server
understands, e.g. you can automatically load a module on startup with:
"./nwnx2 -module MODULENAME"
Once you have NWNX2 and the APS running on your module it is very simple to add
updates to your world. Follow these steps:
The APS is merely a set of custom functions that were originally used for the Avlis
persistent world. The names of the functions and their parameters can be set to whatever
is convenient for your module. Below is a hypothetical example of how customization can be done.
The "PowerG I33t" persistent world maintains their persistence with the Joe Bloe Persistence
system (JBPS). In that system, a persistent string is set with the following JBPS function:
SetStickySring(string sVariableName, string sVariableValue, object oTarget)
All 5000 scripts in PowerG's elite world are written with the SetStickyString function, and they
wish to retrofit their world to use NWNX. They would follow these steps:
SetPersistentString(object oObject, string sVarName, string sVarValue, int iExpiration, string sTable = "pwdata") Once the module is restarted, all of PowerG I33t's old persistent string scripts should be running the
new persistence system. All it took was changing one script.
The above example is a simplified one, and the rest of the functions in the JBPS would need to be changed
in the same manner. In cases where the function parameters were completely not equivalent to those used
by the APS, they may have to be changed throughout every script in the module. Many but not all of the
persistence systems out there should be convertible by the above method. We encourage further modification
of aps_include to tailor the variable handling to your needs.
For persistence systems that use tokens, conversion will not be as easy. In these systems, token items
are used to represent information on a player character. These tokens are not lost because they are
actually in the inventory of the character. Because these systems work with tokens and not actual variables
it will be hard to convert them into a database format. The module will most likely have to be completely
re-fitted.
One possible idea to do this scriptomatically would be to write a module OnEnter script that strips the
character of their tokens and issues SetPersistent variable commands into the database before destroying
them. That would preserve the information that is there, but handling the actual scripts throughout the
module will have to be done separately.
APS and NWNX are distributed unter the terms of the GNU GENERAL PUBLIC LICENSE included in
licence.txt.
II. Installing NWNX 4 Linux and system requirements
while [ nwncheck != 1 ]
do
./nwnstartup.sh
done
III. Installing and updating APS
A. Importing the erf
The following scripts should now be imported: aps_onload, aps_include.
B. Updating from previous versions
C. Using the persistence functions
The functions below are now implemented. Here is a lexicon containing
information on their purpose and use:
OR
Open aps_onload in the script editor and paste the contents of it into your
pre-existing module's OnModuleLoad script. We only recommend doing this if you
are familiar with NWScript.
Returns
#include "aps_include"
at the top of your script.
IV. Setting up a database for NWNX
These are basic instructions on how to setup a database for APS/NWNX.
A. For Access
NWNX tries to connect to a so called ODBC DSN with the name "nwn" on startup.
Here is how to create this connection: Go to Windows control panel, choose Administrative Tools,
choose Data Sources (ODBC). In the window that pops up, go to the second tab (System DSN)
and click "Add". Choose "Microsoft Access Driver (*.mdb)" from the list and hit
"Finish".
You now have an empty database. In order to store data in it, you have to create some tables
in the database. The included module "aps_demo.mod" makes this easy.
B. For other databases
SQLExecDirect("CREATE TABLE pwdata (" +
"player varchar(64) default NULL," +
"tag varchar(64) default NULL," +
"name varchar(64) default NULL," +
"val text," +
"expire int(11) default NULL," +
"last timestamp(14) NOT NULL," +
"KEY idx (player,tag,name)" +
")" );
V. Running a module with APS/NWNX
1. Initializing the module
NWN Extender V.2.0.0.0
(c) 2003 by Ingmar Stieger (Papillon)
visit us at http://avlis.blackdagger.com
* Connecting to database
* NWNX2 activated.
o Got request: SELECT item, count, identified FROM containers WHERE container='PersistentChest1'
o Sent response (17 bytes): ARS_SKILLBOOK
o Sent response (17 bytes): NW_IT_BOOK018
o Sent response (18 bytes): NW_IT_TORCH001
o Empty set
* NWNX2 shutting down.
2. Restarting and publishing the module
VI. Customization
1. APS and persistence scripts
to:
SetStickyString(string VarName, string VarValue, object oObject, int iExpiration = 0, string sTable = "pwdata")