Anvil is a C# framework for building behaviours and adding new functionalty to Neverwinter Nights: Enhanced Edition. The library allows server owners and builders to create simple behaviours, while giving plugin developers the option to implement complex systems or modify existing hardcoded rules.
Builders can add functionality like opening a store from a dialogue with a few lines of code, while plugin developers can leverage NuGet to add new functionality with external packages and the NWN.Native library to completely rewrite existing game systems and mechanics.
- Latest Release
- Changelog (Development)
- View Community Submitted Plugins
- Join the community:
Anvil uses NWNX's DotNET plugin and is 100% compatible with existing NWNX/NWN servers.
If you are using docker, you can simply swap the NWN/NWNX image with Anvil's image.
All of your existing code will work of out the box, while offering the C# framework for you to begin developing plugins.
Anvil has its own docker images that are automatically configured to start and run Anvil and NWNXEE. Similar to the parent images, Anvil is configured by environment variables passed during docker run
.
By default, Anvil will look in the /nwn/anvil/Plugins
directory in the container for managed plugins. A volume containing your plugins can be mounted here to automatically run on startup.
Running the image is exactly the same as running the beamdog/nwserver
or nwnxee/unified
images. See the NWNX and NWServer README's for configuring these images.
The following tags are supported:
Tag | Example |
---|---|
latest |
nwndotnet/anvil:latest |
<version> |
nwndotnet/anvil:8193.22.1 |
<commit-hash> |
nwndotnet/anvil:c09d2f6 |
- Download and extract the dedicated server package: Server packages
- Download and extract NWNX: https://github.com/nwnxee/unified/releases
- Download and extract the Anvil Release for your server/NWNX version.
- The directory structure should look like the following:
bin/
|----linux-x86
|----nwserver-linux
|----NWNX_DotNET.so
|----NWNX_SWIG_DotNET.so
modbin/
|----NWN.Anvil.deps.json
|----NWN.Anvil.dll
|----NWN.Anvil.runtimeconfig.dev.json
|----NWN.Anvil.runtimeconfig.json
|----NWN.Anvil.xml
|----(Other dlls)
- Configure NWNX options to the following:
NWNX_DOTNET_SKIP=n
NWNX_SWIG_DOTNET_SKIP=n
NWNX_DOTNET_ASSEMBLY=/your/path/to/NWN.Anvil # Where "NWN.Anvil.dll" was extracted in step 3, without the extension. E.g: NWNX_DOTNET_ASSEMBLY=/nwn/home/modbin/Anvil
# NWNX_DOTNET_ENTRYPOINT= # Make sure this option does not exist in your config
The DotNET and SWIG_DotNET plugins are required for the library to work. Make sure they are enabled!
The following options can be configured via environment variables:
Variable | Default | Options | Description |
---|---|---|---|
ANVIL_HOME |
<nwn_home>/anvil |
An absolute path, or relative path to <nwn_home> |
The main directory for Anvil's storage. Anvil will search for plugins in ANVIL_HOME/Plugins and store plugin data in ANVIL_HOME/PluginData , as well as search this directory for various configurations. |
ANVIL_RELOAD_ENABLED |
false |
true/false |
Enables support for plugin hot-reloading via AnvilCore.Reload() . Recommended for advanced users. |
ANVIL_PREVENT_START_NO_PLUGIN |
false |
true/false |
Prevents the server from starting if no plugins are detected/loaded. |
ANVIL_PRELINK_ENABLED |
true |
true/false |
Disables some initial startup checks when linking to the native NWN server binary. This is an advanced setting that should almost always be unset/set to true. |
ANVIL_LOG_MODE |
Off |
Off/Duplicate/Redirect |
Configures redirection of the NWN server log. Off disables redirection, Duplicate creates a copy of the log entries in Anvil/NLog, Redirect redirects the log entries to Anvil/NLog, and skips the original log entry. |
The recommended way to install plugins is to copy plugin binaries manually to your server's Plugins
folder.
This folder is located in your server's home directory. This is the directory containing the modules
folder, servervault
, etc.
After running anvil for the first time, you will see a new folder here called anvil
. You will want to copy the plugin to the anvil/Plugins
folder.
Once copied, your server home directory should look like the following:
anvil/
|----Plugins/
|----YourPlugin/
|----YourPlugin.dll
database/
development/
hak/
modules/
override/
portraits/
saves/
serverdata/
servervault/
tlk/
Anvil includes a plugin/package manager based on Paket that can automatically update plugins from authors who publish their work on NuGet.
To get started, first navigate to your server's home directory and find the anvil/Paket/paket.dependencies.orig
file.
Rename this file from paket.dependencies.orig
to paket.dependencies
, then open the file in your favourite text editor.
By default, the file should look like this:
// Rename this file to "paket.dependencies" to enable support for loading plugins from NuGet.
// See https://fsprojects.github.io/Paket/dependencies-file.html for more information.
framework: net5.0
strategy: min
source https://api.nuget.org/v3/index.json
// ---- Add plugins below this line ----
To install a plugin, first search and find the NuGet package page for the plugin.
Once you are on the package page, you will want to copy the install command listed at the top of the page. It should look something like:
Install-Package NWN.ExamplePlugin -Version 8193.33.0
Copy the name and version parts of the command into the paket.dependencies
file:
// Rename this file to "paket.dependencies" to enable support for loading plugins from NuGet.
// See https://fsprojects.github.io/Paket/dependencies-file.html for more information.
framework: net5.0
strategy: min
source https://api.nuget.org/v3/index.json
// ---- Add plugins below this line ----
nuget NWN.ExamplePlugin 8193.33.0
Save and close the file. The plugin should now download and run the next time you launch the server!
Adding module behaviours starts by creating your own plugin assembly (.dll).
To get started, it is recommended to start by making a copy of the sample project found HERE with the package dependencies already setup for you.
The core of Anvil is built around a dependency injection model, and the library expects you to implement features in your plugins a similar way.
Using a class attribute (ServiceBinding), the system will automatically wire up all of the dependencies for that class as defined in the parameters of its constructor:
using NLog;
using NWN.Services;
// The "ServiceBinding" attribute indicates this class will be created on start, and available to other classes as "ServiceA".
[ServiceBinding(typeof(ServiceA))]
public class ServiceA
{
// Gets the logger for this service. By default, this reports to "logs.0/anvil.log"
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
// As "ServiceA" has the ServiceBinding attribute, this constructor will be called during server startup.
public ServiceA()
{
Log.Info("Service A Loaded!");
}
}
// This class will be available to other classes as "ServiceB".
[ServiceBinding(typeof(ServiceB))]
public class ServiceB
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
// As "ServiceB" also has the ServiceBinding attribute, this constructor will also be called during server startup,
// but since "ServiceA" is specified as a parameter (dependency), it will only be started after "ServiceA" has loaded.
public ServiceB(ServiceA serviceA)
{
Log.Info("Service B Loaded!");
}
}
Checking in the console or server logs, you should get the following output:
[ServiceA] Service A Loaded!
[ServiceB] Service B Loaded!
Anvil is bundled with a core set of services that you can depend on in your own plugins and systems.
These services handle game events, task scheduling, and more! Examples of how to use these services can be found in the Anvil docs.
You can also find a full list of the services bundled by Anvil HERE.
The Anvil Framework builds heavily on the foundations of the NWNX:EE DotNET plugin that was written by Milos Tijanic, and derives several service implementations from plugins developed by the NWNX:EE team and its contributors.