NWN2

NWN2 specific content.

ALFA Peer to Peer Server Network Protocol

Overview

Starting with ACR 1.87, ALFA servers have the ability to perform direct, peer-to-peer communication between eachother, bypassing the database.

Presently, this communication is only used for unreliable, datagram-oriented messages (which can be lost or reordered along the way), so it is only used for non-critical activities like advising a server that it should immediately retrieve an IPC message from the central database.  Datagram protocol messages are also unauthenticated, so drastic action shouldn't be taken on receiving them.

Network protocol

The protocol operates as multiplexed over the same data port as game data traffic, and thus requires no additional firewall configuration.

Each protocol message starts out with a standard header.  All fields are in little endian.  Code to operate on parsing and building network protocol messages lives in CLRScript\ALFANetworkMessages.cs, whereas code for sending and receiving actual messages with payloads lives in alfa2_acr.hak\ACR_ServerCommunicator\ServerNetworkManager.cs.

UInt32: Magic number.  This is used to distinguish ALFA protocol messages from standard game network traffic.  The magic number always has the value 0x414C4641 (the ASCII string "ALFA").

UInt8: Protocol type.  There only ALFA protocol type currently defined is PROTOCOL_DATAGRAM, with the value 0x00.  The datagram protocol provides unreliable message delivery (messages can be discarded or reordered along the way, so it can't be used for data that must arrive in one piece).  A future connection-oriented protocol that provided reliable semantics might have a different protocol id to allow the messages to be distinguished.

UInt16: Command.  This represents one of the protocol-specific command codes.

UInt32: Message length (includes the header described here).  This represents the length of the entire message.

Datagram protocol message commands

The datagram protocol defines several message command codes, which are listed below.

CMD_IPC_WAKE (0x0000)

This message is sent to a server in order to cause it to immediately query the database for IPC messages.  The purpose of the message is to work around the lack of a LISTEN / NOTIFY mechanism in MySQL for reliable IPC messages.  The actual IPC message(s) to process are stored in the server_ipc_messages table, whereas the IPC wake datagram simply causes the target server to check the table immediately.  This reduces the latency required for a server to respond to a message (servers normally periodically poll, so the IPC wake message eliminates the added latency from the polling interval if it was successfully delivered).

(Int32) Source server id.  The database id of the server that sent the message; the message should be discarded if the sending address doesn't match that server id in the servers table.

(Int32) Destination server id.  This should match the database id of the local server, otherwise the message should be discarded.

CMD_SHUTDOWN_NOTIFY (0x0001)

This message is sent from a server, to all online servers, when a server begins a clean shutdown (as started by the Restart Server tool).  The purpose of the message is to allow any future, connection-oriented protocol targetted at the server to be shut down.  Currently, no action is taken when the message is received.

(Int32) Source server id.  The database id of the server that sent the message; the message should be discarded if the sending address doesn't match that server id in the servers table.

CMD_NOTIFY_DATABASE_STATUS (0x0002)

This message is sent to inform one server of what the other server's view of the central database's health is.  In the future, it might be used to form a quorum that might try to diagnose whether a failure in connectivity to the central database is likely to be the result of a server-local failure, or a failure actually on the central database.

The #showstate debug command can be used to dump the database online status of each known server.  This can be used to try and manually diagnose whether a database connectivity failure is local or global.

Servers rebroadcast this message every 10 minutes.  In addition, if a server's connectivity state to the central database changes state, the message is immediately broadcast at that time.

(Int32) Source server id.  The database id of the server that sent the message; the message should be discarded if the sending address doesn't match that server id in the servers table.

(UInt8) Database online disposition.  This value is 1 if the sending server has a good connection to the database, else 0 if the sending server cannot connect to the database.

 

Creating a Content Patch

Overview

ACR 1.87 supports the creation and deployment of content patches, which are server-side hotfixes that are automatically deployed to live servers on startup.  The content patch system is intended to make it easier to deploy important bugfixes to an already released ACR version.

Content patches can be used to perform the following tasks:

  • Place a file in the Override directory for the server.  Note that module and hak resources supersede "Override" resources (but Override supersedes in-box .zip files and can be used to deploy a new script that could be called by a hak, etc.).  Override-targetted content patch files go in "override\ACR_ContentPatches" on each live server.
  • Place an updated hak in the Hak directory for the server (for example, alfa2_acr.hak).

Content patches cannot be used to make client-side content changes (those must go through the standard release process).  As of ACR 1.90, the content patch system can recompile all module scripts (if the RecompileModule database column is set for a content_patch_files row that required updating), if necessary.  This facility can be used to update includes in the ACR hak and recompile scripts in a module that reference the include.

Content patches do not update the downloader XML for a server.  Server admins must be careful to not restage haks that have been hotfixed by the content patch system (typically, alfa2_acr.hak).

Content Patch Components

A content patch contains several distinct components which must be assembled:

  • The content files to patch (e.g. alfa2_acr.hak, or a free-standing file to place in the Override directory).  Any number of files can theoretically be content patched, but you're encouraged to keep the set of file small.  The content files must be placed on the central server vault, in a special directory, for them to be downloadable by the content patch system.
  • A set of database entries in the content_patch_files table that describe what ACR hak version the patch applies to (e.g. 1.87), and what file is associated with the patch.  You need a database record for each file that is contained within the content patch.
  • An optional initialization script, called "acr_patch_initialize".  If present, this script is run during module startup, to provide opportunity for a content patch to hook script callbacks or set things up.  The script is never located in the ACR hak or the module, but should only be distributed as a content_patch_files record.

Creating a Content Patch

The following is a checklist of the steps necessary to build and deploy a content patch.  Once deployed, it will be automatically picked up by live servers on their next restart.  (If necessary, you can remotely restart a server using the Restart Server tool.)

  1. First, create the content files to patch.  For example, the fixed script or the patched ACR hak.  Typically this would be done by checking out the ACR branch for the released ACR version to be patched, making the necessary changes and checking them in to the repository, and then rebuilding the hak from that branch.
  2. Next, copy the patched content files to the central vault.  They should go under ACR_ContentPatches\Global\<ACR_Version> on the central vault (for example ACR_ContentPatches\Global\1.87 for an ACR 1.87 patch).
  3. Generate a md5 checksum of each of the patched content files.  The md5sum utility (included with msysgit - http://code.google.com/p/msysgit/ - or cygwin, can do this).  You'll need these checksums to insert into the database in the next step.
  4. Create a database record in content_patch_files for each file present in the content patch.
    1. Set the FileName column to the name of the file to patch (with extension, no spaces, for example "alfa2_acr.hak").
    2. Set the HakVersion column based on the ACR version that is matched when deciding whether the content patch is applicable (for example, "1.87").
    3. Set the Location column to either "override" or "hak", depending on where the content file should be stored on live servers.
    4. Set the Checksum column to the md5sum value (32 hex characters) for the file that is being patched.
    5. Set the RecompileModule column to true if the module needs to have all scripts recompiled, else false if a recompile is not required.  A recompile is generally only necessary if an include in the ACR HAK has been changed and the include is referenced by a script distributed with the module.  This option is only supported in ACR 1.90 or higher (otherwise the module is never recompiled).
  5. Connect a test server to the database and central server vault, and restart it.  Check the log to make sure that the content patch applied successfully; the server should restart a second time after applying the patches.  There will be server log entries containing "ModuleContentPatcher" updating you with the status of content patches as they're applied.

It is highly recommended that you test the content patch on a test server before copying the patch data to the live server.  You should still verify that the patch applied correctly to a live server, however, once the patch has been deployed to production.

Content Patches and the Standard Release Process

The content patch system ensures that patches are tagged with a specific ACR version that they apply to.  When a server upgrades to a new ACR version, using the standard release process, previous content patches will no longer be applicable and won't be applied anymore.

For content patch files located in the "hak" directory, no action is taken.  It's expected that if the administrator did an ACR upgrade, that they have manually upgraded the haks anyway.  (No new haks can be added with the content patch system, only hotfixes to existing haks.)

For content patch files located in the "override" directory, the content patch system automatically removes any patch files not applicable to the ACR version the server starts up with at startup time.  Thus it's not necessary to manually clean the content patch override directory out.

Content Patch Server Log Messages

Messages in the NWN2 server log file track the progress of the content patch system. When a content patch has been successfully applied, a log message of the form "ModuleContentPatcher.ProcessContentPatches: Successfully updated content patch file <filename>." will be written to the server log. Log messages related to the content patcher can be easily identified by searching for ModuleContentPatcher in the log file. To verify that a content patch was deployed successfully, examine the server log after a server restart. Be sure to check the log message timestamp; it is usually best to start searching from the end of the server log file.

If a content patch requests a module script recompile, then the console output of the script compiler is printed to the server log file.  An error message prefixed with the standard ModuleContentPatcher prefix is printed to the server log if any scripts failed to compile.

Building Server Portals

To set up a Server Portal:

Triggers, Doors, and Usable Placeables are the customary objects used for inter-server travel in ALFA. 

 

Scripts:

In the OnClick or OnUsed script of the object, set the script = acr_trg_portalstart

Remaining scripts should be the default acr_* scripts for the portal object type.

 

Portal Waypoints:

Create a Waypoint with a Tag of the form <SourceServerId>_PortalTo_<DestinationServerId>_<PortalNumber>, where the ServerIds are 3 digit integers, and the PortalNumber is a 2 digit integer, i.e. for the Arrival Waypoint of a portal from Baldur's Gate (Server ID 010) to The Silver Marches (Server ID 003), the first such arrival WP is given the Tag: 010_PortalTo_003_01

 

Portal Variables:

int ACR_PORTAL_DEST_SERVER = (1 - 999 ) should be set to the Destination Server ID#

 

int ACR_PORTAL_NUM =  (1 - 99) the destination waypoint Portal Number

 

int ACR_PORTAL_ADJACENT =  If set to 1, the portal doesn't use a 24-hour cooldown, otherwise it uses the cooldown.

 

-Thanks to the ALFA Tech Dept.

ACR Area Instancing System

ACR Area Instancing Overview

The ACR supports an "Instanced Area" system that allows multiple copies of an area to be instantiated at runtime, based on a "template" area that you design in the toolset.  The template can be any standard area, except its content and associated scripting logic should be aware that there might be multiple instances of the area.

Area instances are useful if you want to provide multiple, isolated copies of an area.  One use might be to instance an area based on player party, for example, so multiple parties get their own private "copy" of an area.  Other uses might be for player housing, player "travel areas" (like a caravan or a vehicle interior), certain special spells like "Rope Trick", or anywhere else that creating multiple copies of the same area might be valuable.

Anything that happens in one instance doesn't directly impact other instances.

There isn't any hard limit on how many instances of an area can be created, although there is some memory overhead.  The overhead on the server is much less than creating static copies of an area in the toolset, though, because the server just re-uses the walkmesh information from the template area when the instancing system is used.

Script code is needed to manage the creation of area instances and moving players into an area instance (as a static transition will only go to one instance).  There are a series of script functions in the acr_area_instance_i header that are used to create and manage area instances.

Area instance lifetimes

It is currently not possible to delete an area instance once it has been created.  As a result, the area instancing system keeps a "cache" of instances that have been created for a given template area.  When a new instance is requested with ACR_CreateAreaInstance, the instancing system first checks whether there was a previously created instance; if so, it is used.  Otherwise, a brand new area instance is set up.

The first time a brand new area instance is created, all of the statically placed objects are spawned (if you had any).  Subsequently, if the area instance is cleaned up and reused, then statically placed objects are assumed to be in the right state.  It's a good idea to use the spawn system and not statically place objects that are destroyable by the player.

In order to deal with this, areas that are instanceable should be designed to be "resettable", that is, returned to their default state by script code.  There is a local variable attached to the template area, ACR_AREA_INSTANCE_ON_DELETE_SCRIPT, which names a script to run when an area is eligible to be cleaned up. The job of this script is to determine whether the instance should be cleaned up or not, and if so, to "reset" the area to a pristine state.  For example, the script might delete all spawned creatures or treasure on the area so that the next player using the area gets a pristine state.  Once the on delete script has cleaned up an area instance, a future call to ACR_CreateAreaInstance can return that same area object.  It's your responsibility to delete any unwanted objects that might be lingering in the instance from the area cleanup script.

Areas have an associated on create script that is designated with a local variable on the area template, ACR_AREA_INSTANCE_ON_CREATE_SCRIPT.  This script is called every time ACR_CreateAreaInstance secures an area to return.  The area might be a previously reused cached instance, or a brand new instance.  The on create script gives you a chance to set up any state that needs to be created when an area is going to be used.

Instanced area cleanup can be handled either automatically or by script code.  By default, area instances are automatically cleaned up after 60 seconds   To enable automatic cleanup, set the ACR_AREA_INSTANCE_CLEANUP_DELAY variable to something other than -1 (or leave it at the default of zero to trigger the default time of 60 seconds).  This variable specifies a delay (whole or fractional count of second) after which an area instance that is empty of all players will be automatically cleaned up.

When an area is going to be cleaned up, either automatically or by an explicit call to ACR_ReleaseAreaInstance, the on delete script is called.  If the on delete script returns FALSE, then the area isn't cleaned up (and if automatic cleanup was enabled, the cleanup script will be called again after the cleanup delay to check if the area should be kept alive).  Otherwise, the area is made available for future use once the cleanup script returns.

Getting into (and out of) an area instance

Normal areas often have static connection points in the form of area transitions that link to an area.  This doesn't work as normal for an instanced area, though, as there might be multiple copies of an area instance active at a given time.

You will need to write some script code to transfer the player into an appropriate area instance (possibly creating one if necessary), when an instance is called for.  This code might run as a part of a dialog or transition onuse script; it would typically find an appropriate already existing area instance (say the one used by the party leader), or create a new area instance with ACR_CreateAreaInstance.  Then, this script code would jump the player into an appropriate location within the area. 

Another option might be to have an area OnClientEnter script that checks if the entering player is supposed to be in a particular instance of an area (maybe with a local variable set on the PC object to designate this), if the current area is not an instance as returned by ACR_IsInstancedArea.  If the player had an instance, the script could move the PC into the instance, otherwise it could create an instance for the PC and move the PC into that instance.  That would let you continue to use a conventional static transition into the area (but you'll area transition twice, which is a bit slower, when entering it).

Remember that waypoints are relative to an area instance, so if you want to move a player into an area by jumping to a waypoint, you'll have to find a way to get the waypoint for the right area instance.  One way to do this would be to have the area on create script find the waypoint in the newly created area instance, and store it as a local object variable on the area instance object.  Then, you could use GetLocalObject() to find the appropriate entry waypoint for a given area instance.

Area linkages outside of an area instance will work like normal (as long as they don't link to another area instance, in which case the above rules apply).  You might find it useful to provide dynamic linkages in some cases, though, like in an instance travel caravan.  These linkages could be customized by the area on create script.

It's a good idea to turn on automatic area cleanup for your area instances.  This allows them to be deleted after a "cool down" time once nobody is in the area.  A "cool down" time enables automatic area cleanup, and is optional (specified by ACR_AREA_INSTANCE_CLEANUP_DELAY).  If enabled, the area instancing system will keep track of when nobody is in the area and after the "cool down" time elapses, the area will be automatically cleaned up.  This frees you from having to worry about manually getting rid of your area instances when they aren't in use.

It can sometimes be useful to keep an empty area instance around for a short time, like several minutes.  For example, you might want to let a player return to a previously created instance in case they had forgotten something on the ground, if they remember soon enough.  It's up to you to design how this should work for your area (and how the player gets back into their old instance).

Instanced area local variables

There are a series of controlling local variables that you can set on an area object that will be used as an instanced area template.  Make sure to use the correct case (and variable type) for these variables when you set them in the toolset!

string ACR_AREA_INSTANCE_ON_CREATE_SCRIPT  : This variable gives the name of a script that runs when the area instance is being "created" and will be returned from ACR_CreateAreaInstance().  The script name shouldn't have an extension.  It's optional to specify an on create script, but if you need to do some work when the area is going to be used, then the on create script may come in handy.

string ACR_AREA_INSTANCE_ON_DELETE_SCRIPT  : This variable gives the name of a script that runs when the area instance is being "cleaned up".  The script name shouldn't have an extension.  It's optional to specify an on delete script, but if the area can at all have dynamically created objects spawned or removed from it, then you should provide an on delete script that resets the area to a clean state.

float ACR_AREA_INSTANCE_CLEANUP_DELAY  : This variable expresses the time after which an area instance with no players is automatically cleaned up (unless vetoed by the on delete script).  The time is expressed as a count of seconds (fractional values permitted), just like you would use for a DelayCommand time.  If the variable is zero or isn't set, then automatic cleanup isn't enabled for the area.  If you want to enable automatic cleanup and clean up an instanced area right away, just set the cleanup delay to 1 second.

Area instance on create script

An area on create script (optional) should looks like this:

void main()
{
   object Area = OBJECT_SELF; // The area being created
   // Set up the new area instance as desired.  This
   // example finds the entry waypoint for the area and
   // saves it on the instanced area object so that it can
   // be referred to for jumping players into the area.
   //
   // It is up to you to decide how this should work for
   // your area.  This example uses a waypoint with the
   // tag of "wp_instance_start" that is intended to be
   // placed in the toolset, but you can do that however
   // you would prefer.
   object Obj = GetFirstObjectInArea(Area);
   while (Obj != OBJECT_INVALID)
   {
      int Type = GetObjectType(Obj);
      if (Type == OBJECT_TYPE_WAYPOINT &&
          GetTag(Obj) == "wp_instance_start")
      {
         SetLocalObject(Area, "AREA_START_WP", Obj);
         break;
      }
      Obj = GetNextObjectInArea(Area);
   }
   if (Obj == OBJECT_INVALID)
      WriteTimestampedLogEntry("No start WP for area!");
}

The script is called when ACR_CreateAreaInstance is called.  The job of this script is to perform any instance setup tasks that your area instance needs.  For example, spawning objects that should be statically spawned, setting up transition links for exit transitions (if they are dynamic), etc.

The example script looks for a waypoint object that is intended to be statically placed in the area template, with the tag "wp_instance_start".  It then stores this object as a local variable on the area instance object (which will be returned by GetArea() for objects in the instance).  If you wanted to jump a player into the area, to find the right waypoint, you'd call GetLocalObject(AreaInstance, "AREA_START_WP").  You can't just use a tag lookup as the object might be in a different area instance.

Area instance on delete script

An area on delete script (optional) should look like this:

int StartingConditional()
{
   object Area = OBJECT_SELF; // The area being created

   // Clean up spawned objects in the area and remove treasure, etc.
   // It is up to you to decide how what to do here.  This example
   // script just looks for any freestanding items or creatures in
   // the area and deletes them.  You're guaranteed that there are
   // no PCs in the area when the on delete script runs.

   object Obj = GetFirstObjectInArea(Area);
   while (Obj != OBJECT_INVALID)
   {
      int Type = GetObjectType(Obj);

      if (Type == OBJECT_TYPE_CREATURE || Type == OBJECT_TYPE_ITEM)
         DestroyObject(Obj);

      Obj = GetNextObjectInArea(Area);
   }

   // The script can now return TRUE to allow the area to be considered
   // cleaned up (and available for re-use).  Otherwise, the script can
   // return FALSE and the cleanup attempt is dismissed.  If automatic
   // cleanup was enabled, cleanup may run again if the area remains
   // empty, once the cleanup timer elapses next time.

   return TRUE;
}

The example script scans for any loose creature or item objects in the area, and deletes them.  You can perform other cleanup tasks here as appropriate.  The general idea is that after the on delete script runs, the area is in the same state as if it were just loaded on module startup (so that it is "fresh" the next time the that instance is used).  Don't forget to clean up any local variables on the instanced area object itself that you used to maintain state, if those need to be reset.

Area instance management script functions

These functions are used to manage the creation or deletion of an area.  Typically, script code uses these functions to acquire a new area instance to transport a player into, or to remove an area instance that isn't needed anymore.

//! Create an instanced area.  If an available instance in the free pool can be
//  found, it will be reused.
//!  - TemplateArea: Supplies the area that serves as the template for the new
//                   instanced area.
//!  - CleanupDelay: Supplies the area cleanup delay.  If < 0.1f, then the
//                   value from the design time configuration setting on the
//                   template area is used instead.  If the design time
//                   setting did not specify a value then cleanup is not
//                   enabled for this instance.
//!  - Returns: The area instance, else OBJECT_INVALID on failure.
object ACR_CreateAreaInstance(object TemplateArea, float CleanupDelay = 0.0f);

//! Release an instanced area.  It will be put back onto the free list of the
//  area supports free list pooling, otherwise the area is deleted.
//!  - InstancedArea: Supplies the area instance to release.
void ACR_ReleaseAreaInstance(object InstancedArea);

Area instance utility script functions

These functions are most useful for scripts that are called in response to events within an area instance.  They can be used anywhere, as long as the "InstancedArea" parameter is actually an area instance (for functions that operate on an area instance).

//! Check whether an area is an instanced area or not.  It can be used for the
//  client enter script of a template area, for example, to create an instance
//  of the area and move the entering player to the instance.
//!  - Area: Supplies the area object to query.
//!  - Returns: TRUE if the area is an instance, else FALSE if it is a static
//              created area (which might be the template for an instance, or
//              might be any other static area).
int ACR_IsInstancedArea(object Area);

//! Return the template instance for an instanced area.  This is the area
//  object that had been created from.  Returns OBJECT_INVALID if the area was
//  not really an instanced area.
//!  - InstancedArea: Supplies the instanced area object to query.
//!  - Returns: The template (parent) area, else OBJECT_INVALID if the area
//     was not a valid instanced area.
object ACR_GetInstancedAreaTemplate(object Area);

//! Check whether an area has any player controlled objects in it.  The area
//  can be a normal or instanced area.
//!  - Area: Supplies the area to inquire about.
//!  - ExcludeObject: Optionally supplies an object to exclude from checking.
//!  - Returns: TRUE if the area has no player controlled objects.
int ACR_IsAreaEmptyOfPlayers(object Area, object ExcludeObject = OBJECT_INVALID);

 

ACR configuration settings

There are several configuration settings that alter the behavior of the ACR on a global or per-module basis.

Global settings are stored in the "config" table in the database, whereas per-module settings are stored as module local variables that are intended to be configured in the toolset.

 

Module local variable configuration settings

These settings are stored as local variables on the module.  They can be set by the toolset.

 

int ACR_PLAYER_LOCATIONS  : If set to 1, the PC Tools button that allows a player to see what areas their party members are in is enabled.  This feature is defunct and doesn't do anything right now.

int ACR_DISABLE_STATISTICS:  If set to 1, then the ACR doesn't update the stat_counters table in the database.  This feature is primarily in place to allow statistics to be disabled if they proved to be a performance problem.  This setting can be globally configured via the database config table.

int ACR_HEALTHMONITOR_GAMEOBJUPDATE_BACKOFF  : If set to 1, then the server will detect when responsiveness is poor due to excessive server load.  If the server appears to be overloaded, then the ACR (ACR_HealthMonitor) will increase the time between game world updates sent to game clients.  This frees up a significant amount of CPU time for other tasks on the server, preserving responsiveness (but players will see course corrections or other movement changes less frequently).  If the server is performing well, the game world update timer is reduced to its default value.  This setting can be globally configured via the database config table.

int ACR_SERVER_IPC_DISABLE_LATENCY_CHECK  : If set to 1, then the server won't periodically, about every 30 seconds, refresh the player to server ping times of connected players (players can check their ping with #ping if this feature isn't enabled).

int ACR_MODULERESOURCEFILES  : If set to 1, then the server will record each resource file present within the module proper in the server_resource_files table.  This setting can be globally configured via the database config table.

Recommended module default settings

int ACR_PLAYER_LOCATIONS = 1

int ACR_HEALTHMONITOR_GAMEOBJUPDATE_BACKOFF = 1

 

Global (database config table) configuration settings

These settings are stored in the "config" table in the database, which is a key/value pair mapping.  They change the behavior of all modules connected to the database.

PlayerPassword  : This setting contains the player password that is used when portaling a player between servers.  It must match the configured player password value on all servers.  Changing this setting doesn't actually change the player password required to connect to a server (which has to be done separately), just what password is used for outbound portals.  This setting is updated every 5 minutes while a server is running.

ACR_DISABLE_STATISTICS  : If set to 1, this setting turns off stat_counters table updates on all servers by setting the ACR_DISABLE_STATISTICS module local variable to 1 during server startup.  This setting is only updated at module startup time.

GameObjUpdateBackoff  : If set to 1, this setting enables game world update timer management by setting the ACR_HEALTHMONITOR_GAMEOBJUPDATE_BACKOFF module local variable to 1 during server startup.  This setting is only updated at module startup time.

RestartWatchdogTimeout  : The number of second after which a remote server restart request, from the Restart Server tool, forcibly terminates the server if a clean shutdown hasn't happened yet.  This setting is designed to allow a server that is deadlocked or hung to be forcibly restarted remotely (as the remote restart mechanism uses a dedicated thread that is more likely to be responsive even if the main server thread is stuck).  If not set or set to zero, then the restart watchdog feature isn't used on remote restart requests.  This setting is updated every 5 minutes while a server is running.

AccountAssociationSecret  : The shared secret string used to generate the URL to send the user to for linking their in-game community account with their ALFA forum account.  The value can be any string (hopefully a relatively random one).  The forum system uses the shared secret to validate that URLs containing account linking information were only generated by an authorized source, like a live server.  More details on the account association system can be found here. This setting is updated every 5 minutes while a server is running.

ModuleResourceFiles  : If set to 1, this setting enables module resource file logging by setting the ACR_MODULERESOURCEFILES module local variable to 1 during server startup.  This setting is only updated at module startup time.

AccountAssociationUrl  : The base URL of the ALFA account association web service.  This setting is updated every 5 minutes while a server is running.

GetHostnameUrl  : The base URL of the ALFA get hostname web service.  This setting is updated every 5 minutes while a server is running.

ContentPatchPath  : The path relative to the sshfs mount point to use as the base location for content patch files.  Content patch files are stored under <sshfs_mount>\ContentPatchPath\<HakVersion>\.  This setting is only updated at module startup time.

DefaultIrcGatewayId  : The default IRC gateway to use for server-to-IRC messages.  Typically, this should be zero, which is the IRC gateway ID customarily used by the production ALFA IRC bot.  The setting is paired with an ALFA IRC Bot instance's IRCGateway config.xml entry.  This setting is updated every 5 minutes while a server is running.

DefaultIrcRecipient  : The default IRC recipient (i.e. channel) to use for server-to-IRC messages.  Typically, this should be #alfa-players.  This setting is updated every 5 minutes while a server is running.

WerDisabled  : If set to 1, Windows Error Reporting is disabled for nwn2server.exe.  This setting is only updated at module startup time.

DisableSaveInQuarantine  : If set to 1, character files are not saved by a player in quarantine (preventing a pending save from an offline server from accidentally being overwritten by logging in to the wrong server).  This is updated every 5 minutes while a server is running.

CompilerOptions  : Compiler options that the content patcher system uses when a module recompile is required by a content hotfix.  This is usually set to "-e -o -v1.70 -y", to match the option set used by the ACR build system (in NWScript.mk) and to continue past scripts that fail to compile, as some modules have non-compileable scripts checked in.

NotifyServiceCid  : The character ID of the dummy character that is used to send notification messages from infrastructure to the IRC gateway.  Typically, this should be the dedicated NotifyService character (CID 3905).  This is used, for example, by the content patcher, so as to send notifications as to server restarts due to the content patch system.  If set to zero, messages are not sent to the IRC gateway.  Infrastructure messages are sent to the default IRC recipient as configured by the DefaultIrcRecipient config table variable.

ErrorNotifyIrcRecipient  : The default IRC recipient (i.e. channel) to use for diagnostic and error reports sent via server-to-IRC messages.  Typically, this should be #alfa-tech.  This setting is updated every 5 minutes while a server is running.

GameDifficultyLevel  : The game difficulty level that all servers will be configured to. This is an integer value that should match the value of one of the GAME_DIFFICULTY_* nwscript.nss constants, and should generally be set to 3 (meaning GAME_DIFFICULTY_CORE_RULES). If a server has an incorrect difficulty level, the ACR system will automatically adjust it to the target, global difficulty level specified with this variable.

ProtectionLevel  : The anti-abuse protection level that all servers adhere to (an integer).  Each protection level represents an incremental anti-abuse defense over the previous level.  Protection levels can be applied in the case of an abuse event, but generally the system should run at ProtectionLevel 0 (the default, no special restrictions).  Valid values correspond to the following table (the value should be set to the integer on the left, the symbolic constant in script source code is supplied in parenthesis):

  • 0   (MEMBER_PROTECTION_LEVEL_OPEN):  The default, no special anti-abuse provisions for non-member accounts.
  • 1   (MEMBER_PROTECTION_LEVEL_QUARANTINE):  Non-member accounts are immediately quarantined on login.
  • 2   (MEMBER_PROTECTION_LEVEL_QUARANTINE_DM_ONLY_TELLS):  Non-member accounts are immediately quarantined on login and the only function permitted in-game is to send a tell to a DM (no cross-server tells, no IRC gateway use, no (non-DM) player tells, etc.).
  • 3   (MEMBER_PROTECTION_LEVEL_BOOT_5S_DELAY):  Non-member accounts are quarantined, can't use tells (even to a DM), and are booted after 5 seconds.  A short message explaining that the player should fill out the application form at http://www.alandfaraway.org is displayed before the player is booted.
  • 4  (MEMBER_PROTECTION_LEVEL_BOOT_IMMEDIATELY):  Non-member accounts are immediately booted on log in and can't perform any function in-game whatsoever.  No appreciable delay even to send an explanation as to what happened is allowed for, for use in extreme abuse events only.

This setting is updated every 5 minutes while a server is running.

 

New gameserver VM setup

This document describes in rough detail the recommended checklist for setting up a new game server host VM in the standard configuration.

Details can also be found on this forum thread: http://www.alandfaraway.org/forums/viewtopic.php?f=95&t=47550

OS configuration:

- Install Windows Server
- Copy standard tools over
- Create SG "NWN2 Servers"
- Create SG "NWN2 Admins"
- Create user "NWN2Server"
○ Add to "NWN2 Servers" SG
- Create C:\NWN2, xcopy NWN2 install over
○ Grant "NWN2 Servers" create files, create folders to "This folder only"
○ Grant "NWn2 Admins" modify to folder, subfolders, and files
○ Import NWN2.reg
- Create C:\NWN2User
○ Grant full control to "NWN2 Servers"
○ Grant modify/execute/list/read/write to "NWN2 Admins"
- Runas /profile /user:NWN2Server cmd.exe
○ cd /d "%userprofile%\Documents"
○ mklink /j "Neverwinter Nights 2" C:\NWN2User
- Create C:\NWNX4, xcopy NWNX4 installation over
○ Grant modify/execute/list/read/write to "NWN2 Admins"
○ Grant modify/execute/list/read/write to "NWN2 Servers" for:
§ AuroraServerNWScript.log
§ AuroraServerVault.log
§ nwnx.txt
§ nwnx_controller.txt
§ xp_mysql.txt
§ xp_bugfix.txt
§ xp_objectattributes.txt
§ xp_srvadmin.txt
§ xp_system.txt
§ xp_time.txt
- Create C:\Users\Public\Desktop\Credentials.txt
- Copy standard links to C:\Users\Public\Desktop
- Copy standard links to C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Tools
- Copy standard scripts to C:\Scripts
- Copy standard NWN2 tools to C:\Tools
- Copy NWNServerConsole to C:\NWN2\Console
- Fix PowerShell signing
○ Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy Unrestricted -Force
- Install Git
- Install FileZilla
- Install Win8 Performance Toolkit http://msdn.microsoft.com/en-us/windows/apps/br229516
- Install 7-zip
- Install gvim
- Install WinDbg
- Set _NT_SYMBOL_PATH to SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols

Prerequisites installation:

• VC2010 SP1 CRT http://www.microsoft.com/download/en/de ... x?id=26999
• VC2005 SP1 CRT http://www.microsoft.com/download/en/de ... x?id=26347
• .NET Framework v4.0 http://www.microsoft.com/download/en/de ... x?id=17851
• DirectX 9.0c http://www.microsoft.com/download/en/details.aspx?id=35

NWNX4 installation:

• nwnx4_controller.exe -installservice
• Get SID for NWN2Server user with PowerShell:
○ ([wmi]"win32_Group.Domain='$env:ComputerName',Name='NWN2 Admins'").sid
• Set SD on nwnx4-1 service to allow NWN2 Admins to start/stop:
○ sc sdset nwnx4-1 D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWP;;;<>)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
• Set configuration in C:\NWNX4\nwnx.ini
• Set configuration in C:\NWNX4\AuroraServerNWScript.ini
• Set configuration in C:\NWNX4\xp_mysql.ini

Syndicate content