I am glad to announce the NWNX4 project development has resumed, with new maintainers !
Currently only @scottmunday84 and me are working on NWNX4, but we would be happy to welcome new contributors !
You can contribute in a number of ways:
Open issues on GitHub, detailing bugs you encounters or asking for new features. We would love to get some feedback on the existing issues.
Improve the wiki pages to document how NWNX4 and its plugins works. Currently the wiki is almost empty.
Improve the NWScript files to provide new features or better documentation related to NWNX4 plugins.
Submit pull requests on GitHub to provide new features, plugins or fix bugs (require C++ knowledge). Don’t worry if your are not very experienced in C++, your PRs will be reviewed and you will receive help
Expect new features, plugins and improvements to come very soon
This NWNX4 release brings the same features and interfaces as the official (now abandoned) version from nwnx4.org, and should be a drop-in replacement.
Under the hood, a lot of work has been done to update the codebase to be easily built with modern compilers and libraries, and CI pipelines have been setup to help newcomers submit pull requests.
On the plugin-side, this release comes with a lot more plugins than the official one:
xp_bugfix
xp_fastboot
xp_funcs *
xp_mysql and xp_sqlite
xp_objectattributes *
xp_pickpocket *
xp_profiler *
xp_srvadmin
xp_time
Some of these plugins (those marked with a *) may not be on-par with versions posted on the vault (maybe older, maybe newer). Please open an issue here if you find any difference.
Currently, only the MySQL plugin has gained new features:
Fixed the SQL object storage (The abandoned nwnx4 release had broken SCORCO functions).
Now uses the latest MariaDB client connector. This allows the plugin to connect to the SQL server using more secure authentication methods.
Added a charset option to correctly set the charset on connection (and re-connections), instead of sending SET NAMES utf8 queries.
Huge thanks to @SkywingvL and @scottmunday84 for helping me and supporting me to resurrect this important project ! - Crom
Fixed the gamespy watchdog not receiving ping responses on some configurations
Fixed the restart command not being executed correctly
Plugin changes
New plugin: xp_rpc !
xp_rpc is a plugin that allows high performance RPC communication between an NWN2 server and any set of microservices. A microservice can be built in any supported language of both gRPC and Protocol Buffers.
See the wiki for more information !
xp_bugfix
Fix a bug where the server crashed when BootPC cas called twice on the same PC
Fix a server crash when a character with more than 255 spells connects to the server
Fix a server crash when a player initiates a rest while in transition between two areas
xp_mysql / xp_sqlite
Added the function SQLGetLastInsertedID() to return the ID of the last inserted row
Allow nwnx4 to detect the nwn2 install directory. Currently you must edit the nwnx4.ini file in order to set the game install directory. The solution would be to detect the install dir (like what the client extension is doing).
Implement SCORCO for xp_sqlite. This would allow single player module creators to store and retrieve in-game objects without requiring users to install and configure a SQL server
It’s more a launcher for nwn2server.exe (not the game client nwn2main.exe).
NWNX4 starts the nwn2server process and inject a DLL (some custom code) into the nwn2server process, in order to apply some patches to the nwn2server executable during startup.
These patches are provided by NWNX4 plugins and do a lot of different things, like fixing game bugs, performance and stability (xp_bugfix), give access to SQL databases (xp_sqlite, xp_mysql), allow the modification of character files (xp_objectattributes), …
It’s probably not well known by solo module developers, but I bet all PW servers out there are already using NWNX4 (at least the old version)
The DLL injection and patching rely on some static addresses in memory, and I would expect those addresses to be very different for nwn2main.exe.
The two are complementary. The ClientExtension improves player experience with nwn2main.exe and NWNX4 extends the capabilities and stability of nwn2server.
Yes, and to be honest this is beyond my skills… some smart people already found some useful pointers and created plugins with them. I only updated their code to build on modern compilers.
The location of plugin files have been modified in order to ease the process of upgrading nwnx4 and its plugins.
tl;dr: Move all your xp_*.dll files into the plugins/ folder before upgrading nwnx4, and you should be fine for this part.
Here’s how the new file tree works:
config.example\: Contains config templates for nwnx4 and its official plugins. On first installation, you must copy those config files into the root nwnx4 directory. Files under config.example\ will be updated with nwnx4, and you will need to compare them with your copies in order to support new features when nwnx4 will be updated in the future.
nwn2server-dll\: Contains all DLL files that the NWN2Server process will need (you don’t need to copy them into the nwn2 installation dir anymore). This directory is automatically added to the DLL search path for the NWN2Server process, so you can add your own DLL files to it this folder. Note that this folder is not searched by the .NET runtime, so it will not work with xp_AuroraServerNWScript DLLs.
nwscript\: Contains the include scripts to copy to your module (nothing changed here).
plugins\: Contains all nwnx4 plugin DLL files. By default, nwnx4 will search this directory when loading plugins (see “Plugins loading” below). In order to install additional plugins, you will need to copy their DLL files into this folder.
Note that .ini and .txt (logs) files are still stored in the nwnx4 root directory. This is on purpose, to be consistent with unofficial plugins that expect their config and log files to be located here. Only the plugin DLL files have been moved to a separate directory.
Plugins loading
The way plugins are loaded has been modified in order to explicitly chose which plugins must be loaded. This makes upgrading easier and prevents conflicts between some plugins like xp_mysql and xp_sqlite.
nwnx.ini now has the plugin_list option:
# List of all plugins to load when starting the NWN2Server process
# The list is comma-separated, and each element must be either:
# - A plugin name without the path extension. The associated DLL file must be
# located inside the plugins/ folder of nwnx4.
# - A plugin full path like 'C:\Program File\plugins\xp_yourplugin.dll' or
# 'dev_plugins\xp_yourplugin.dll'.
# Relative paths must be relative to the nwnx4 directory.
#
# default: load all plugins in the nwnx4 folder (legacy behavior, not recommended)
plugin_list = xp_bugfix, xp_sqlite, xp_funcs, xp_time, xp_srvadmin, xp_rpc, xp_objectattributes
By default if you don’t update your nwnx.ini file, nwnx will load all plugins inside the plugins/ folder. This is not recommended and will cause issues if you don’t manually remove plugins you don’t want to load, like xp_mysql / xp_sqlite.
New features
Packaging nwnx4 with your module
You can now assemble a package containing nwnx4 and your custom content and module(s), that players can quickly extract to start a NWN2 server and connect to it. The main idea is to enhance single-player experience by providing server-grade features, like game logic fixes, SQL storage, advanced scripting, …
xp_pickpocket was crashing the server when somebody tried to pickpocket somebody. This is no longer the case thanks to @ap5d !
xp_sqlite
Now supports SCORCO functions (store and retrieve objects) !
While SQLite is slower and less reliable than MySQL, it is very practical for making nwnx4 + module packages because it does not require to install any additional software.
This release fixes a bug where xp_ServerExts (not shipped with nwnx4) was unable to use some functions provided by xp_bugfix, causing error messages like Failed to resolve symbol SetPacketFilterCallouts. .
This bug affects all plugins that requires xp_bugfix to be installed (and now it is fixed).
If you are writing a C or C++ plugin, you can directly include this file in your C / C++ project. Most compiled languages can generate C-compatible ABIs, so if your plugin is written in another language, you will need to “translate” this file for your language.
Currently there are two plugins that use the new CPlugin ABI:
Separated user and install files & CPlugin GFF ABI
Separated config and install directories
NWNX4 now supports splitting files between two directories:
Install directory (e.g. C:\Program Files\NWNX4\)
This directory contains all nwnx4 files from the nwnx4 release zip. Those files should not be modified by the user when configuring NWNX4 for their server. This is very similar to the NWN2 install directory.
User directory (e.g. Documents\NWNX4-myserver\)
This directory contains all configuration files, custom plugins, log files, and other files created by nwnx4. This is very similar to the NWN2 home directory (that is located in Documents/Neverwinter Nights 2 by default).
This should help a lot for installing and updating nwnx4 while keeping track of files that have been added by the user.
A typical install would have a read-only NWNX4 install dir (placed by the admin or an installer inside Program Files), and a writable NWNX4 user dir placed in any handy location.
Multiple NWNX4 user dirs can share the same install dir. This is very practical if you need to run multiple nwn2 servers on the same machine.
When launching a nwnx4 executable (controller or gui), the current working directory is used as the user dir. The NWNX4_Controller has an additional parameter “-userdir” to set the user directory to something else. If the user directory is empty, it is populated with the example config files and useful sub-folders.
Here are two methods for launching NWNX4_Gui with a specific user directory:
Create a shortcut to NWNX4_Gui.exe, edit its properties and change the “Start in” field to set the path to your user directory.
Create a .bat file to launch “NWNX4_Gui.exe”, containing:
REM Moving to the user directory
cd %USERPROFILE%\Documents\NWNX4-myserver
REM Starting NWNX4
"C:\Program Files (x86)\nwnx4\NWNX4_Gui.exe"
Compatibility notes
Launching a nwnx4 executable with a shortcut or by double clicking the exe file, will set the user directory to be the same as the install directory, and everything will behave exactly like previous NWNX4 versions (the user and install directories are merged together).
Plugins only receives the nwnx4 user dir path when loaded (except for CPlugins), meaning they cannot reach files that are located in the nwnx4 install dir. This might cause some issues for some plugins, but I am not aware of any of such plugin.
However, if you encounter this issue, you can solve it by either copying the required files from the install dir into the user dir, or going back to the merged user+install dir setup.
If a plugin is present in both the install dir and user dir, the plugin from the user dir will be loaded. This can be useful if you need a custom xp_mysql plugin that is different from the official.
CPlugin ABI changes
You can now send and receive GFF data between the NWN2 server and a NWNX4 plugin using the CPlugin ABI.
New endpoints
NWNXCPlugin_GetGFFSize: Called by RetrieveCampaignObject, immediately before NWNXCPlugin_GetGFF, to get the size of the buffer that needs to be allocated for receiving GFF data.
NWNXCPlugin_GetGFF: Called by RetrieveCampaignObject to copy GFF data into the allocated buffer. This GFF data is then parsed and “instantiated” in-game.