Resources for Builders

Here you can find a number of resources for builders that I am posting as I come across them. To a certain extent, this is my own personal development journal, but I'm posting it with the idea that others may find it useful.

If you have suggestions, requests, questions, etc. please let me know.

Registration is open to all and only requires a verified email address. If you are an authenticated user, you can contribute to the resource book by clicking the "Add child page" link. These contributions will go into the moderation queue for review.

Authenticated users can post comments, but all comments must first be reviewed for approval. Comments may be promoted into the body of the page, then cleaned up for legibility, or incorporated as child pages.

Please remember that the goal is to create a concise and easy-to-use reference that brings together as much of the knowledge-base from the community as possible. And thanks in advance for your contribution!

Getting Started

Here you will find resources and tutorials for getting started.

Official documentation

The official nwn2 documentation can be found in the "Documentation" folder of your Neverwinter Nights 2 folder. So if you installed it in the default location, you would find it at:

C:\Program Files\Atari\Neverwinter Nights 2\Documentation\nwn2toolsethelp.html

NWN2 Toolset: Getting Started

NWNmaster over at nwn2toolset.com has a great set of tutorials for getting to know the toolset. His current list of topics include:

Navigate around the Toolset
Toolset Controls
Create an Area
Interiors
All about Terrain
Texturing
Grass
About Water
How to add a Start Location
Create Door Transitions
Add Placeables
Walkmesh
Baking
How to link up areas

Head on over to nwn2toolset.com to check it out:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/gettingstarted.html

DMFI Base Module

Carlo has created a great tool for creating DM-friendly modules. The DMFI Base Mod for Builders comes complete with several commonly used tools that will keep builders from burning time on the systems needed for a good DM-run module. Here's the excerpt from the page on nwvault:

The base mod includes as custom content (hak files with accompanying scripts) the DMFI Tools for NWN2 and Heed’s PC Tools, which are widely considered within the NWN2 community to be essential DM and player client enhancements. A few individual scripted DM tools are also included as well as some small but useful other community scripted content. The mod includes several easily selectable and extensible death, bleeding, respawn, and rest systems. All content is documented and appropriately credited in the included Builder's Guide.

The mod is designed to be a foundation that can be adapted and modified as desired by builders. It is also designed to be accessible for novice builders, being extensively commented and with only one script necessary to edit to select the desired rulesets from the toolset. Furthermore, DMs (and players if you wish) can select among the rulesets in-game by using the included module control book item.

The mod is structured so that builders who wish to take advantage of existing features may do so, while those who wish to make extensive additions and modifications should find it easy to change or remove included elements.

Most builders will want to use the full version with Heed’s PC Tools included, but for flexibility’s sake a lite version without them is also included in the download package.

I'm proud to say that a few of the things I created for A Stop Along the Way made it in there!

 

The Don't Panic guide

Another great resource you should check out is Gilthonym's Don't Panic: The Hitchhiker's Guide to First Opening the NWN2 Toolset.

Here's his intro:

Overwhelmed by the toolset?

Don't Panic: read this guide and get to grips with the basics of the toolset.

The guide assumes no knowledge, and is written for anyone, whether they have experience with the Neverwinter Nights 1 Toolset or not.

The guide currently covers:
The general interface
Creating external and internal areas
Placing trees, buildings and doors
Camera controls
Day/Night lighting
Editing properties
Selecting music for an area
Tinting objects
Rotating objects
Laying down interior tiles
Creating transitions between areas
Installing plugins
The external terrain tools
Baking and walkmeshes
Chests and inventories
Creating custom characters
And more...

There are plenty of screenshots so you can easily follow the tutorial.

I hope this guide helps people to create the adventures they want to share. I encourage you to leave feedback for me so I can keep improving it.

Head over to the vault to grab the Don't Panic guide:
http://nwvault.ign.com/View.php?view=NWN2Tutorials.Detail&id=14

The Tome of Building

Another great tutorial is Stebby Surehand's Tome of Building.

The NWN2 Tome of Building (ToB) is an on-line help compilation of existing NWN2 documentation. It contains the Obsidian documentation for the Pre-Release Toolset as well as tutorials and tips developed by the Community. I converted their documents into on-line help. Please read the 'Welcome' topic in the Tome for information about how the documents in the Tome differ from the originals. I did not write any of the toolset-related content and I provided full credit to the original authors. Where possible, I also included links to the original document files so you can easily vote for them and leave comments for the authors.

While the Tome of Building is an on-line help file, I did not have time to add hyperlinks to every cross referenece. This first edition of the ToB does contain some hyperlinks within the text, but mostly it is a convenient compilation of existing documentation. It is also easily navigable, thanks to the hyperlinked table of contents and powerful search feature.

The Tome is divided into two main sections, Obsidian Documentation and Community Documentation. There is also a Welcome section that introduces you to the Tome and explains how the Tome differs from the individual documents and how to navigate through the help file.

Recently, several new tutorials have appeared on the Vault. I decided to release this version of the Tome so people would have what it contains now, if they wanted it, and I will update the Tome with the new tutorials for the "Second Edition".

Head over to the Vault and get it:
http://nwvault.ign.com/View.php?view=NWN2Other.Detail&id=10

Folders and formats

The number of file formats, and where those files go, can be a bit confusing. Here is some basic information.

Files

A great place to start on what each type of file format is for is the File Formats page at nwn2wiki.

Some additional information about a few types can be found under this page.

Folders: The Basics

My Documents

All user data is meant to go in your My Documents folder. The default place for this is "C:\Documents and Settings\Sean\My Documents\Neverwinter Nights 2". This is where you put all files for modules and custom content that you download from the Vault. This is a big change from NWN1 and it has confused some people. Generally all this content come with instructions for how to install, but here is some additional information:

  • ambient - Custom ambient .wav files.
  • ambient_X1 - Custom ambient .wav files for the first Expansion (Mask of the Betrayer). I have no idea why this folder exists.
  • Campaigns - This folder contains a folder for each custom campaign that you are creating or have downloaded to play. This folder contains content that the modules of that campaign will use throughout the game, most notably world maps, NPCs and items.
  • Data - unkown
  • database - In NWN1 they introduced what is known as a "Campaign Database." These are three files (.cdx, .dbf and .fpt) that allow you to store data between modules or outside of the context of a saved game. This was mostly used for Persistent Worlds. This has nothing to do the Campaign folders that were introduced in NWN2. Examples: The FRW Persistent Companion System uses these so you can save your companion information from one module to another.
  • dmvault - I think these where DM characters are saved.
  • erf - Erf files can be placed here. Erf files are used to export things (areas, characters, conversations) from one modlue and import them into another.
  • hak - There is where hak files should be located for modules that use them to be able to find them. Hak Files are libraries of content used to override or extent the game and include custom content. Examples are the BCKII construction kit and the DMFI tools.
  • localvault - Local characters are saved here. Character information is saved as a .bic file.
  • modules - This folder holds .mod files, which are the actual modules.
  • movies - A folder to place custom movies.
  • music - A folder to place custom music, usually .bmu files
  • music_X1 - Like the ambient music folder, I don't know why there is a custom folder marked for the first expansion.
  • nwm - unknown
  • Override - The override directory can "override" content in a module. It's a powerful way to add custom content, but developers are generally encouraged to use .hak files and campaign folders instead as the Override directory will affect all modules. In the wrong hands, this can have unforseen results. On the plus side, however, you don't need to compile the module to use the contents of the override directory.
  • patch - I believe this folder is used when patching the game.
  • portraits - Custom portraits can be placed here.
  • prefabs - Prefabs are a collection of placeables and effects that have been packaged together, usually to make placing them easier. Lit candles and Dining tables are good examples.
  • pwc - PWC files contain a module's walkmesh and pathing information for players. When you choose the "Create PWC" option from the Files menu in the Toolset, these files will end up here. They allow you to distribute this information to the players without requiring them to download the whole module. This is especially important for Persistent Worlds and DM run modules where you don't want the players to be able to open the module in the Toolset and cheat.
  • Saves - This folder contains save game information.
  • servervault - Players that have created characters in multi-player games that you host will have their players created here. Note that this only happens if you have the "Allow localvault characters" turned off when you set up the game.
  • texturepacks - unknown
  • tlk - All tlk files go here. They control the strings used in a module and are often used to translate a module into multiple languages. As I understand it, a module can only use one master tlk file. Most modules use the default. Most custom tlk files are edits to the default. Example: All spell names and descriptions are pulled from the tlk file, so custom spell packs need to get in there to add and edit the descriptions and names.
  • ui - A folder for custom user interface files.

Program Files

All game data is meant to go in your Program Files folder. The default place for this is "C:\Documents and Settings\Sean\My Documents\Neverwinter Nights 2." All the files for the Official Campaign (OC) are also in your Program Files folder. Generally, you don't have to get into this directory, but the BIG exception is the plugins folder in the NWN2Toolset folder.  Here's the rundown:

  • The Ambient folder - This folder holds the wav files for background noises. These elements are available across all modules. Note that when trying to decide what background sounds you want, you can play these directly from your preferred multimedia device, although I cannot say if there are any permissions issues when doing so with the Toolset open.
  • The Campaigns folder - The supporting campaign files (scripts, images, etc.) are in the campaigns folder. These are files that are available across all the modules in the OC. These resources are only available to the OC.
  • The Data folder - This folder consists of .zip files that hold data that can be used by the OC, and any other module, including those created by you. The 2da files, voice over wave, and many other resources are held here. These elements are available across all modules.
  • The dmvault folder - Unknown.
  • The Documentation folder - You should read this.
  • The Effects folder - Unknown, but at a guess these seem to be basic effects that the Toolset uses.
  • The hak folder - This contains your hak files. At this time, I am unclear if hak files go here or in the My Documents area.
  • The Localvault folder - This contains the basic characters that come with the game.
  • The Miles folder - Unknown.
  • The Miles folder - Unknown.
  • The Modules folder - The actual modules for the OC are in the modules folder. They are numbered and also have a descriptive name. These resources are only available to the OC.
  • The Movies folder - Contains the .bik files that use present the movies (The logos and the into, etc.)
  • The Music folder - This hold the bmu files for background music and combat music. These elements are available across all modules.
  • The NWN2Toolset folder - Contains the source for the Toolset. Note that this also contains the "Plugins" folder. This is where you put community created plugins so that they are available in the Toolset.
  • The Override folder - Will allow you to override some files, most probably in the OC. At this time, I am unsure what resources can be overridden.
  • The patch folder - I'm assuming this is used during the patching process.
  • The Servervault folder - Unknown.
  • The temp folder - Definitely used during the patching process. Unknown if it is also used during gameplay.
  • The UI folder - I think this is where you place your custom UI files, but I am not sure, as there is also one in the My Documents folder.
  • The Utils folder - Unknown what these are for.

Discussion

There is currently a thread going on over at the Citadel about custom content and files.

BMU

BMU stands for BioWare Music Unit. This is the file format for background music files. AFAIK, essentially, it's an .mp3 file with some tinkering done on the first few bits of the file and the extension changed.

Here are some tools to convert bmu files:

MP3toBMU 0.35
http://nwvault.ign.com/View.php?view=Other.Detail&id=225

Prince Rouse's Mp3toBMU and WinMP3Converter
http://nwvault.ign.com/View.php?view=Other.Detail&id=821

Using the tools above, you can convert all the music in the Music folder under Program Files to an mp3 and listen to them.

You can find information on the BMU format in this NWN1 tutorial on custom music. (Note that a good deal of this has changed for NWN2).
http://nwn.bioware.com/builders/sounds_bmu.html

At the time of this writing, there are still some complications with bringing your custom music into your module, and I remember seeing a post talking about improvements that will be coming soon. If anyone has any resources along these lines, please let me know.

ERF

ERF stands for Encapsulate Resource File. It is used when importing and exporting resources from one module to another.

Most people keep .erf files in a folder in their My Documents folder called erf. Note that you don't get an erf folder by default, so feel free to created one when you need it.

PFX

The .pfx file extension is for particle-based effects. As I understand it, these are used as resouces when creating .sef files. You can find some of them in C:\Program Files\Atari\Neverwinter Nights 2\Data\NWN2_VFX.zip.

SEF

The .sef files are special effects files for NWN2. Most of the ones that come with the game are located in C:\Program Files\Atari\Neverwinter Nights 2\Data\NWN2_VFX.zip

From the official documentation:

"Visual effects are composed of effect files, which are individual components of an effect (a particle system, a trail, a billboard, etc.), and SEF files, which point to the effect files and organize them into a more complex visual effect."

As I understand it, .sef files are what you create when you save a visual effect from the visual effects editor.

WMP

A .wmp file is created by the world map editor plugin.

The power of 32 characters

Before you do anything, save yourself a lot of time and make sure all your modules, areas, object tags, variable names etc. are less than 32 characters. Failure to do so will result in missing data, crashes and other unexpected behavior.

For example:

While I was working on the PRR scripts, some data was not being saved because my global variable names were more than 32 characters. Anything beyond character 32 was getting dropped. I ended up using a hash to store my variables, something that I'm still not quite sure is the right answer. (Hopefully, I'll work this out soon.)

Another example, is that recently Markus "Wayne" Schlegel, the builder behind the Pool of Radiance Remastered series, was having problems loading the next module in the series. After some testing, it came out that his modules were named with 39 characters, and would sometimes (usually when loading the third module) crash to the desktop.

So there you go. Keep the all-powerful 32-character limit in mind. When it doubt, it's better to stay below 32 characters then go over. You'll potentially save yourself hours of troubleshooting.

FRW Base Module

Lord Niah of the Forgotten Realms Weave has a great base module to help get people started. Not only is it a great way to get a head start on your module, it also serves as a clean example of the proper way to perform a lot of common tasks.

This module includes base scripts and items for the Forgotten Realms Weave (FRW) project, including a player starting area with a trainer and basic merchant.

Other features Include:

-- Wandering Monster and Rest tag system
-- Hardcore bleeding or OC death system
-- Chest-based Random Loot system w/ breakable items
-- Flavor text, ability, and skill check triggers
-- Demonstration companion and "Sunken Flagon" style Inn
-- Demonstration OOC (Out of Character) Start Area
-- Patcha's Sitable chairs

Note: This is currently tested for singleplayer only, but should work for non-persistent multiplayer.

Be sure to read through the documentation file, as well. It has a lot of useful information.

Go grab it here:
http://nwvault.ign.com/View.php?view=NWN2Scripts.Detail&id=55

Areas

Here you can find information on creating areas.

You may also want to check out this page concerning naming conventions when you are naming your areas: http://www.wendersnaven.com/node/46

Area lighting

ciViLiZed posted the following links for day and night lighting options for areas:

Day/Night stages lighting is discussed here and here.

See the Day Night Cycle Prefab at the vault for a great collection of lighting settings for areas.

Bloom

From the NWN2 Teakguides:

Bloom Effects: Bloom effects change the quality of the lighting to create a more saturated, richer and hazier looking game world. The screenshot comparison above demonstrates the difference between enabling or disabling this option in NWN2. If bloom is not to your taste, you can disable it to gain a few FPS, however aside from making the game world seem more vibrant, it also works to reduce the appearance of aliasing (jaggedness) at far less impact than enabling Antialiasing. Note that the more advanced HDR lighting can't be enabled in NWN2; even though there is a UseHDRIfAvailable setting it does not currently work.

Periodiko posted additional comments in this forum thread:

Technically speaking, if you crank bloom up then it will blur everything you see a little, but it will blur bright things far more than dark things. If you crank it really high it will create a dreamy sort of effect, where the bright lights are a little too bright and everything is a little blurry. If you turn it off then the area will seem darker and more sterile.

The main ways it's used in the Neverwinter Nights Toolset that I've seen is with the "hazy" effect. For example, the Githyanki house in the OC has the bloom cranked up really high so the whole area feels magical and dreamy. It is also cranked higher during daytime lighting settings to reproduce the haze of the sun. I think the default morning setting that you see first-thing when you don't adjust the time-settings has it running pretty strong.

ciViLiZed posted the following explanation of some of the settings:

BloomSceneIntensity (BSI) : Sets the overall brightness level of all lights. (With this, individual light intensity values in effect become relative rather than absolute.) As it brightens light, it will not brighten places where light does not reach. A setting of 0, eliminates all light except the highlights (see below). A negative value creates negative brightness which effectively darkens highlights. A BSI of 1, with other bloom settings set to 0, has the same effect as if bloom was disabled.

BloomHighlightThreshold (BHT): Sets the size and quantity of highlight hotspots. Models and tiles have defined zones (“hotspots”) where light causes highlights when it hits them. Different hotspots will be highlighted depending on the angle of the light (e.g. GroundLight vs SkyLight). A higher BHT value will result in bigger and more numerous hotspots. A negative value (regardless of the number) sets hotspots to their maximum. The minimum value at which hotspots appear seems to be about 0.5.

BloomHighlightIntensity (BHI): Sets the intensity of the highlights. Highlights will expand/flare more and more as the value is increased. A very high BHI value (e.g. 1000) with a low BHT (e.g. 0.5) will show clearly where the hotspots are located. Increasing BHI and BHT will eventually burn out the entire scene. A negative BHI value creates darker and darker highlights (eventually creating a negative effect if BSI is positive)

BloomBlurRadius (BBR): Multiplies each individual highlight and spreads these “clones” around the original, like petals of a flower in… bloom. (Original highlight size though seems to be reduced in this operation, making it seem that the highlight might be broken down and its pieces spread, rather than it being cloned.) A higher value increases the distance (i.e. radius) between the center of the original and the center of the clones/pieces. The clones/pieces are spread regularly in a flat grid pattern around the original highlight. Typically, 8 clones/pieces appear to be created. The angle of the flat grid remains perpendicular to the point of view, while the distance between the clones/pieces varies with viewing distance. BBR value is an absolute, so prefixing a negative has no impact. BBR, BHT and BHI combine to create a blur effect. Increasing the BBR up to a point where the additional highlights detach themselves from their model will result in a ghosting effect.

BloomGlowIntensity (BGI): No effect in interior areas. (In fact, the default interior DayNight stages settings have it set to 0.)

Ovocean added these also:

As I understand it, the bloom effect is a filter applied to each frame by the 3D card.
More precisely, it sorts of make a blured copy of the frame and mix it together with the original. (Consequently, dark parts of the frame spread around as much as bright parts (depending on the BHT). There is no direct link between light sources and the bloom effect.)
The toolset gives us some control over the blur filter and how the blured framed is mixed (I would say 'multiplied') with the original frame :

BloomSceneIntensity : Controls how much of the original frame will be in the final mix (= it's luminosity). Set to "0", you'll only see the blured copy of the frame. "1" stands for "luminosity 100%".

BloomBlurRadius : Defines the radius of the blur (how far colors are spread).
Actually, the blured frame is made by mixing a great number (47, if I can trust my sight) of copies of the original frame, arranged in a repeating pattern. The greater the shift of a particular copy, the more transparent it is. The BBR defines the shift between each copy.
If this is not clear to you, try setting the BSI to 0 and play with great values for the BBR.

BloomHighlightIntensity : Well, now, it looks like there is even one more filter put somewhere in the process. This filter controls the luminosity of the blured frame and the BHI is the main parameter of it : it's the global luminosity value (of the blured frame).

BloomHighlightThreshold : This second parameter sets the (color's) intensity threshold beyond wich the colors are affected by the BHI. I don't know what threshold corresponds to what intensity, but when a particular pixel's intensity is under the threshold, it's luminosity is set to 0.

Finally, here are the settings I use when I want a bloom effect wich slightly blends the colors without modifying the overall luminosity of the scene :
BSI = 0.8
BBR = 10
BHI = 0.25
BHT = 2

PS : I've seen no effect for the BloomGlowIntensity.

Check out the full thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=564969&forum=113

Exteriors

Information concerning exteriors.

AmstradHero: Exterior Area Proofing Tips

AmstradHero has posted a great list of tips for proofing your areas over at the Vault. It's a good checklist of things to remember both before and after building your areas. He's got it posted as a very nice looking pdf, but I've duplicated it here as well (Rember to head over and give it a vote if you found it useful):

Here are a few guidelines for working with and improving your areas, whether prefab or not. It's useful to keep in mind as a sort of "final proof" of an area before finishing with it.

Terrain Tips:

Avoid Steep Edges

  • Unless you have a specific need to do so, avoid having huge height differences over a short period. The textures will stretch vertically and will not look as good.
  • This also applies to edges that are at a uniform incline over a large area. Breaking the slope up with a small flat section will improve its overall appearance dramatically.

Blend Textures

  • Vary your opacity when laying down textures to get a blended edge unless there is a specific reason for not doing so.
  • Paths don't immediately end in a sharp line, and dirt/grass should blend over the top of the edges in an uneven fashion.
  • Don't blend too much, otherwise you'll lose definition in your texturing and the area will look too monotonous.
  • Look at the minimap of your finished area – if there are large areas that repeat, blend.

Use The Colour Tool

  • Use the colour tool to provide additional variance in your paths or grassy sections. Typically, use a colour that is similar to those of the nearby textures unless you are aiming for a specific look.
  • Paint greens and browns over grassy/dirt sections, and use grey over mountain cliffs. Typically, gullies or depressions should be darker due to the implication that water would sit and make the ground damper and darker - though obviously this doesn't apply to deserts.
  • Try using a little bit of brown and grey in "junction" areas that would see a lot of wear and tear.

Darken Terrain Underneath Placables

  • A big way to improve the appearance of the terrain is to darken the area under and around placeables, typically with a grey brush. Keep the effect tight and focussed around the placeable.

Fix Your Walkmesh

  • Do not leave your walkmesh at its default. Fix it so that rocky mountainous sections are not walkable, along with deep pools & lakes.
  • Do use walkmesh cutters around your trees - this cannot be stressed strongly enough.
  • Prefabs that have a good walkmesh are greatly appreciated by modders.

Placeable Tips:

Check Placeable Heights

  • A beginner mistake that occurs lots is objects floating in the air. Just because a particular part of a placeable in sunk into the ground, it does not mean that part of it might still not be 'floating'. Make sure that this is not the case unless it makes sense for it to do so.

Use Height/Position Lock

  • Double clicking on an object will cause it to raise up so its centre point is at the level of the terrain. Moving an object will also have the same result. Seeing as in many cases objects are "sunk" to provide a better effect, it is extremely annoying to have to reposition their height if this is done accidentally.
  • Using the "Z" key to toggle height-locking on any selected objects, or the "*" key to lock their position entirely.
  • Modders really appreciate this being done for prefabs, and it's a very good habit for builders to get into.

Convert Placeables to Environmental objects

  • Any placeables in non-walkable areas of the map should be converted to environmental objects seeing as the player can never interact with them.
  • Many placeables in walkable areas of the map should be converted to environmental objects as well. Any object the player is unlikely to interact with is a likely choice. Make sure you fix the walkmesh around them as described previously.

Sound Tips

Limit Non-Positional Sounds

  • Carefully check the volume of any area wide-ambients - these should be used very sparingly, as a low volume is quite loud.

Adjust Intervals

  • Non-looping sounds should have the "Random" & "Continuous" checkboxes ticked, but not looping.
  • Increase the time between durations and also the interval variance.
  • Make sure the sound will play only at appropriate times during the day/night.

Implement Variance

  • Look at adjusting the volume and pitch variation on the sounds. Often a slightly softer sound with more variation can provide a more varied feel.
  • Use positional variance. Remember that you can limit that positional variation to a single axis to focus a sound within a particular corridor, alleyway or gully.

Lighting Tips

Use Colour

  • Don't use the default lt_white light. It's far too nondescript. Add some colour to your light, using warmer colours (yellow/orange) for a calming effect, or cooler colours (blue/green) to give a more ominous feel.
  • Be careful not to use too much saturation unless you are aiming for a particular effect. For example, saturated green can give a sickly/diseased atmosphere, whereas bright red gives a hot and dangerous feel.

Tweak Your Day/Night Settings

  • Pay attention to this for exterior areas. There are various lighting settings available on nwvault that might be useful. Take one of these and tweak.

Beware of Shadows

  • Point lights will often have very heavy shadows. Set your shadow intensity to no more than about 0.4 in most cases.
  • Lamp placeables will often need to have their shadow settings set to not cast shadows from point lights if you are using them with point lights.

Don't Overdo It

  • Don't have too many lights close to each other. Look at their ranges and make sure you have no more than 3 or 4 lights overlapping at any given point.
  • Shadow casting point lights are very resource intensive. Limit their use within an area.

Final Words

This is just a quick document to provide a few areas to focus on as the final touches for when producing an area – it's not intended to be a full area creation tutorial. I hope you find it useful to glance at before closing an area for the final time.

- AmstradHero aka Shadow Beast

Again, if you found this useful, make sure you head over to his Area Proofing Tips page on the Vault and give it a vote.

Anduraga's area building tips

One of my favorite builders when it comes to textures is Anduraga. He's given some great tips for the Waterdeep project and other projects over at the Weave. He recently posted a great list of tips for people looking to build good exterior areas. Here's his intro:

I find that many people find area building a very difficult task, and when they do make areas, they are often basic, because of the lack of tutorials, tips, etc. I can relate that to somewhat in a different department. Scripting isn’t really my strong suit, but I can manage to do the basics. But anyway, to the point of this post/thread. I have designed this thread to help new builders, adept builders and even master builders with tips and tricks of the trade. I haven’t checked out many of the tutorials on the vault (Shame on me, I know), so all this stuff I’m throwing out here now might already have been covered.

Check out his list of tips here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=578694&forum=113

 

DLA Tutorial: Exterior Area

BenWH over at DLA has posted a great tutorial on creating exterior areas in the DLA Toolset forums:

Trying out the NWN2 toolset for the first time? Here are the results of my explorations on building an exterior area, combined with the wisdom of several others…

Read the full tutorial here:
http://www.dladventures.net/vB/showthread.php?t=3791

FRW: Texturing a good grasslands area

Phoenixus posted a great tutorial on texturing a good grassland area. Check it out here:

http://nwcitadel.com/forums/showthread.php?t=858

Importing terrain with YATT

You can import terrain data into the toolset to help build exterior areas using YATT. From the YATT website

Yet Another Terrain Tool (YATT) is a plugin for the Neverwinter Nights 2 Toolset allowing importing of terrain information (including heightmaps, colourmaps, texturemaps, etc) directly into the toolset. It does the importation of height, colour and texture data directly through the TRN stream, meaning it's reasonably nice and fast.

You can download the YATT plug-in form the vault. There's also a good tutorial on the vault for beginners by Laban. The YATT website also has a number of case studies and additional information.

One way that some builders generate terrain data is with L3DT. From the site:

L3DT is a Windows application for generating artificial terrain maps and textures. It is primarily intended for game developers seeking to make large high-quality 3D worlds (eg. for RTSs, MMORPGs, etc), as well as for digital artists who have designs for their landscapes and need a program to build them. 

Thanks to nicethugbert for point me in the direction of some of this (I read his sig on the forums). I've known about YATT for a while, but didn't have much luck with other mapping programs. L3DT seems to be more promising. Also check out NTB's Eroded Hills and Valleys, where he has posted some of the areas he generated with these two tools.

Layering textures and sounds

The layer with the highest percentage is the one that determines what sounds a creature makes when it walks on that area. Make sure you bake the area in order for the sounds to take effect.

NWN2 Mods: The Arena

Mike - aka Plane Walker, aka soulraven666 - over at NWN2 Mods has posted a step-by-step tutorial on creating a "roman Colosseum."

I thought I would detail the process I am going through in creating this Arena so this post is going to be an ongoing one that I continue to add to as I progress. Please feel free to reply with comments.

Head over to the NWN2 Mods forum and check it out:
http://www.nwn2mods.com/forums/index.php?showtopic=21

NWN2 Toolset: Areas

NWNmaster over at nwn2toolset.com has a great set of tutorials for creating areas. His current list of topics include:

Create an area
Interiors
All about Terrain
Texturing
Tips for creating an Area
Grass
About Water
How to add a Start Location
Create a waterfall
Create door transitions
Day and Night Settings
Walkmesh
Baking

Head on over and check it out:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/area.html

NWN2 Toolset: Bridges

NWNmaster over at nwn2toolset.com has a great tutorial for placing a bridge.

After seeing a few people having problems with placing bridges I thought I would give it a go and see what the fuss was about. First thing I did was to create two raised areas like so:

Head on over and check it out:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/placeables/bridge.html

TerraCoppa: Copying and rotating areas

A great tool for making changes to your area is TerraCoppa, by Tani. The most obvious benefit of this tool is being able to rotate areas, so that north matches with north. Here is Tani's description:

TerraCoppa is a toolset plugin allowing you to copy and rotate parts of one (exterior) area to another, including:

- terrain (heightmap)
- tinting (colors)
- textures
- gras
- water
- objects (creatures, placeables, ...)

of course you could copy objects via toolset as well, but it lacks the ability to copy or rotate terrain (heightmap).

Go grab the tool here:
http://nwvault.ign.com/View.php?view=NWN2PlugIns.Detail&id=25

Documentation is a bit light, but here is a quick rundown on how I got it to work:

  1. Install the plug-in and restart the Toolset.
  2. Back up your module!
  3. Open your module and the area you want to rotate.
  4. Create a new external area, of the same size.
  5. Launch the plug-in from the Plug-ins menu.
  6. Set the first area as the source and the new area as the destination.
  7. Leave everything checked.
  8. Look for the dropdown at the bottom of the screen and choose the amount you want to rotate the area. (90, 180, 270).
  9. Click the green button and let it go.
  10. Make sure you bake afterwards.

For additional reading, here is a thread on the forum talking about "North Direction" and rotating the area.
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=558621&forum=113

The walkmesh helper

The walkmesh helper is a tool created by Zarathustra217 and apparently quietly slipped into the 1.05 patch.

I came across this post by TheStoryteller01 asking about making creatures hover above terrain. Grinning Fool posted some really amazing looking screenshots that he created using the walkmesh helper.

The walkmesh helper is a tool on the vault by Zarathustra217. Here's the description:

This is a simple package intended to make a builder's life easier. It consists of simple squared invisible placeables with a walkable walkmesh. When scaled, the Walkmesh Helper objects are handy to use along with Walkmesh Cutters (found under trigger) to have more control of the walkmesh. This especially is evident when using a combination of placeables, like several bridges. Place the Walkmesh Helper just above the walkable plane of the placeables, scale it to properly cover the desired area, and cut away with Walkmesh Cutters as fit. You might get the best result by converting the placeables to environment objects, but it shouldn't be required.

It is intended to work as an override, and doesn't require that the end users of your module have this package in place. They will still experience the effect it has on the walkmesh without it installed.

Here's the link:
http://nwvault.ign.com/View.php?view=NWN2HakpaksOriginal.Detail&id=27

Here's an additional tutorial on using this that Feargus Urquhart posted in the developer blog:
http://forums.obsidianent.com/index.php?automodule=blog&blogid=2&showent...

As far as I can tell, the tool on the vault contains a flat plane and a ramp, while patch 1.05 adds two flat planes: a stone version and a wooden version (I'm guessing these are for the footfalls.)

Warning: At the time of this writing, putting the walkmesh helper files in your override seem to cause problems with the official walkmesh objects that came out in 1.05. Hopefully OEI will add the ramp objects soon.

For those of you looking to use it for those annoying house placeables that don't allow you to actually walk up the stairs, try the ramp with a scale of 2, 10, and 7. Getting in place can be a bit tricky, just because it is hard to see exactly where it is sitting. Try baking the area and viewing it with baked and surface mesh enabled and you should see a seamless yellow path onto the roof. I had pretty good results with house 1, but house 3 would only work if I created an additional plan on the roof.

 

jlf2n: Learning shading

jlf2n posted a great thread about how to reverse engineer methods for shading. In his post, shading refers to using the color brush to add shadows. You'll also see this sometimes refered to as "grayscaling." Here's his intro:

Being new to the NWN2 toolkit I set out in search of a tutorial to show me a terrain shadowing tricks. I couldn’t find any so I set to dissecting one of the areas that came with the main quest to see what I could see. The process I used was very helpful to me so I thought I would run through it here for you guys.

He goes on to walk you through opening an area from the OC, removing all the shading, and trying to recreate it. A great idea for learning how the people at Obsidian put some of the areas together.

Check out the thread on the nwcitade here:
http://nwcitadel.com/forums/showthread.php?t=1158

Creating seamless areas

ScreminMemes and Miserere posted some great advice in the Toolset Q&A thread on the official forums on making seamless exterior areas:

Quote: Posted 10/13/06 02:03 (GMT) by ScreminMemes
The off limits area is there to create the illusion of seamlessness. All you need to to to make your areas seamless is copy one then move it to the side until the last two in-bounds rows from the original area are the first two out of bounds in the next area.

Quote: Posted 10/16/06 17:28 (GMT) by Terror2001
I've been looking for a way to copy sections of a map to create this seamless effect but have yet been unable to. I understand the copying of the map to a new map, but how do you select and move a group of tiles?

Don't try to copy sections of a map. Instead:
(1) Make a copy of the entire area (i.e. copy the area itself, not the terrain and stuff in it). Just select the area in the area list, right-click, and select copy.

(2) Identify the edge you want to carry over (let's say it's the North edge of the original area, so you want to preserve the *North* edge of the new area as well).

(3) Select and delete all objects that do not fall within the 4 tiles along the edge you are preserving (otherwise all those objects will collapse to the new edge when you do the next steps, which will screw up the areas you want to preserve). So in our example we delete all objects that are not within 4 tiles of the *North* edge of the new area.

(4) Use the Resize option (I think it's in the Edit menu, but I don't have the toolset in front of me right now) and reduce the size of the edge *opposite* the one you are preserving until you have only 6 tiles in width, total (4 of which will be off limit areas). The 2 off-limit areas from the other area will now be the walkable areas of the new area. In our example, we would remove most of the tiles on the *South* edge of the new area.

(5) Use the Resize option again to increase the size of the area back to what you want it to be, this time on the other edge. Now you have extended out the walkable area in the other direction and can build it up however you want. So, in our example we would add several tiles to the *North* edge. Et voila.

Think of the process as kind of inch-worming your way from area to area. You move to a new area (by making a copy), contract the area to eliminate the parts you are leaving behind, and then extending again in the direction you are moving. Does that make sense, or do I sound like I'm on crack?

Anyway, hope that helps. I've tried this and it works like a champ. Where this method falls apart is if you try to create four areas arranged in a square pattern, since the fourth area you make will only be able to "inherit" the edge of one of its two adjoining areas, not both. That's where you'd have to do some fudging.
_________________
Miserere
Project Lead (Retired)
Tales of the Pendragon (Defunct)

You can find the conversaion here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=502381&forum=1...

Interiors

Information on interior tilesets.

DLA Tutorial: Interior Area

BenWH over at DLA has posted a great tutorial on creating an interior area in the Toolset forums as a follow-up to his exterior area tutorial:

http://www.dladventures.net/vB/showthread.php?t=5016

Load Screens

Thanks to the Halloween 2008 discussion over at bouncyRock Entertainment, I came across four links for creating load screens:

A tutorial at the nwn2toolset site:
http://www.nwn2toolset.dayjo.org/CustomContent/loadscreen.html

Summary from Amraphael/Nihlar
http://nwn2-zork.blogspot.com/2007/11/load-screens.html

A conversation in the Custom Content boards:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=612275&forum=115

A conversation in the Scripting Boards:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=637175&forum=114

Enjoy!

Avoiding area corruptions

Most people have had better luck after patch 1.05, but apparently it is still happening. Here is some basic information to help:

Check out the Toolset Corruption thread on the Toolset forum.

Some things you can do

  • Don't just change the variables on objects. Delete the variables and re-create them, or better yet, delete the object, update it the blueprint, and replace it.
  • Don't leave areas open. Save and close, then back it up.
  • Turn autosave off if you are getting this a lot.
  • Run kivinen's check module script. (See the local page for more info)
  • Occasionally back up your areas to .erf files.
  • Remove any haks that could have scripts that are causing problems.

Tracking down the cause

One of the most common corruption problems comes when you don't properly set the variable type on a trigger. As a general rule, set the variable type first.

There seem to be additional problems when working with speak triggers. stg_why and mattaus have posted how to recreate these issues:

  • open an existing area
  • change an attribute of an existing object (or simply add a speaktrigger, although its not 100% of time for everyone causing corruption)
  • save , close toolset

- sgt_why

Some people are advocating turning off the auto save function because of this.

Corrupted backups

There's also an issue where some areas are getting corrupt and are not noticed until further down the development process.

Phil5000 posted some frustrations in the Toolset forum about this:

Hi there. Ever since my mod was corrupted and I lost half of it I've been saving backups regularly. Well it got corrupted again but in a different way. The game wouldn't load the mod but it seemed ok in the toolset. So I opened up every area to check and when I hit one particular one I got a 'program has caused error and must close' message.

So I loaded a backup and checked that same area and I got that same message! I know for a fact the area is ok having played it through several times. So what could have happened?

This time the game would load it though so I went in there to have a look. Everything is black. There's nothing in there at all. I can turn the camera around and access my inventory but the PC isn't there. It's just like a void in space.

The idea that your area could have been corrupt long ago will make any builder nervous.

Chris_Rocks posted a possible back-up strategy about exporting your areas as .erf files. While this may be a bit cumbersome and will require more space, it will definitely give you a good backup that you can easily bring into your module. Remember that there's never such a thing as backing up too much.

jackyo123 posted a comment suggesting that it's always a good idea to shut the area down when you are done building with it:

one thing that is ESSENTIAL to do -

I was in the habit, because of the ridiculous load times of anything to do with the toolset, of simply leaving my large areas open.

I would happily go along, making edits here, edits there, etc. Saving multiple backups, everything looks good.

Then, a night or 2 later, the toolset crashes. Ok, no biggie, i have a hundred backups. I open up the toolset, go to open my big area - NOPE. Gives me a CAST error or something. Ok, go back 1 version. NOPE, same thing. Go back 10 versions. Nope, same thing.

What was happening is that the area i had open the whole time had become corrupted, but i had not known about it, since it was open already in the toolset, and i didnt try to reload it.

So I no longer do this. I close down an area as soon as i am done working on it, then re-open it to verify its ok. THEN i close it again and move on to my next piece of work.

He also offeres some additional backup strategies:

Also, you need to be making backup copies of the DIRECTORY (usually has a temp^&^E%^%^%&&$modname associated witn it) by manually copying this directory to a safe place every once in a while. I copy the directory every 3 or 4 mod saves. I can often pull scripts, blueprints, etc out of there, and merge them with the last known 'good' copy of an area before it got trashed, and everything is ok.

Thanks to these fine people for their thoughts.

It may also be helpful to check out my stragety for versioning your modules when working with a campaign.

Kivinen: module debug tools

Kivinen has some great tools for working the the toolset on his site here:

http://www.kivinen.iki.fi/nwn/

check-module

One of the best tools for debuging your module is his check module tool, which can be downloaded here:

http://www.kivinen.iki.fi/nwn/exe/check-module.exe

You can find the documentation here:

http://www.kivinen.iki.fi/nwn/docs/check-module.html

Some have suggested you will actually need to save the module out to a directory.

update-ifo

After you find errors, you can try fixing them with his update-ifo tool:

http://www.kivinen.iki.fi/nwn/exe/update-ifo.exe

Here's the documentation:

http://www.kivinen.iki.fi/nwn/docs/update-ifo.html

He also has perl versions of everything, if you want more up to date options, but I've included the exe files since that's what most people will probably be grabbing.

Blueprints and Objects

This section deals with blueprints and objects (creatures, items, placeables, etc)

Creatures

This section deals with creatures.

Companions

Gnorian asked for help making companions in this thread and Dorateen came up with the following reply:

Credit to Celestian the Good:

Making a companion, step by step.

First create your companion NPC. I made a fighter/wizardlevel 1/1 and called him Melf the Elf. His Tagname is "melf" and his resref/template was gh_henchman_melf01.

Load up this new NPCs properties and select import properties->script set and load up "c_CompanionScripts.xml". If you do not have this file you can create it by loading the properties of one of the official campaings companions and selecting export properties->script set and save as "c_CompanionScripts.xml".

Next create a conversation.

Right click the root section, select add and for the text just say "Would you like a new companion"?
right click the line you just created and click add and for the text use "Yes, please join my group.".

Now, find and click the "Actions" tab below and add the following global action scripts:

ga_roster_add_object
ga_roster_selectable
ga_roster_party_add
ga_reset_level

Once you have all the scripts added and in the order above click "refresh" for each script to see the variable options. Once you see those enter in the following values:

ga_roster_add_object sRosterName:melf sTarget:melf
ga_roster_selectable sRosterName:melf bSelectable:1
ga_roster_party_add sRosterName:melf
ga_reset_level sCreature:melf bUseXPMods:1

Replace "melf" with whatever tag you used for your companion.

Save the conversation and then add it to your new companions conversation (under properties).

Place the NPC somewhere in your module and go talk to him. Hit the "yes" response and he should be your new best friend!

Further down, ByblosHex adds this advice:

Note that the NPC's tag must be 10 or less characters for these scripts.

Continue further in the thread for a discussion about how to structure companion conversations. I'll try to pull all of these elements together in a more coherent form at some point.

Check out the full thread:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=537485&forum=113

NWN2Toolset: Companions

NWN2Toolset has released a short and sweet tutorial on creating companions.

Check it out:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/merchants/companion.html

NWN2 Character Builder

lancerlot_30v recently posted a great new site with a robust character builder tool called the NWN2 Character Builder. Check it out at http://nwn2db.com. It's great for those times when you are in the toolset and can't remember what feats an NPC should have.

See the full forum thread announcement.

Thanks to BeyondthePale for posting this to the nwvault front page.

NWN2 Toolset: Creatures

NWNmaster over at nwn2toolset.com has a great set of tutorials for working with creatures and encounters. His current list of topics include: Create an NPC Adjust Creatures Inventory How to setup Generic Encounters How to setup Custom Encounters Head on over and check it out:

http://www.nwn2toolset.dayjo.org/ToolsetTuts/blueprints/creatures/creatures.html

 

Persistent Zombie

This is a quick to tutorial I posted to the Vault while exploring creatures and scripting in the toolset. It will show you how to:

  • Create a custom creature
  • Create custom items
  • Change properties on creatures and items
  • Edit a script for a creature.

Specifically we will create a new zombie that has the properties of a troll. Our zombie will regenerate and can only be killed by fire or acid, but we'll make a few adjustments to the script.

You can view it from the vault here:
http://nwvault.ign.com/View.php?view=NWN2Tutorials.Detail&id=37

Why is everyone injured?

Patch 1.04 is apparently responsible for making all the NPCs standing around the module injured. It has something to do with current hit points versus max hit points. Here's a thread talking about it:

http://nwn2forums.bioware.com/forums/viewtopic.html?topic=561730&forum=1...

Reports suggest that this only affects previously created module. New modules don't seem to suffer from this bug.

A suggested fix was to manually look at the characters' current and max hit points in the Toolset.

Placeables

Information on placeables.

Containers

Don't forget that containers (chests, dressers, long dead corpses to loot, etc.) should have the following flag set under the behavior section of the properties window:

Has Inventory?: TRUE
Static: FALSE
Useable?: TRUE

If you want dynamic treasure, make sure you define a treasure script for the On Death and On Open events. One option, gp_treasure_op_de, is documented here: http://www.wendersnaven.com/node/65

Leaving the faction to hostile will allow players to bash the object without any real repercussions. In NWN1, setting the faction to a neutral faction would cause any nearby members of that faction to attack the PC if certain events were triggered. If I recall, these were On Death and On Disturbed. I'm unsure what events trigger reactions in NWN2, but they are probably the same.

Converting to Environmental

Converting placeables to environmental objects reduces the size of areas. I think it also increases performance for players. Environmental objects do not cut into the walkmesh, meaning that players will be able to walk right through them. Sometimes this is not an issue, such as when they are out of the walkmesh anyway, but otherwise you will want to use the walkmesh cutter trigger to keep players from walking through your objects.

Caution converting Environmental to Placeables

johnbgardner posted this warning to other builders in the official forums:

I just noticed that when you convert an environmental object back to placeable the Current Hit Points, Hardness, and Hit Points are left at 0. Believe it or not this makes the placeable unuseable regardless of the Useable setting. It was driving me crazy that one placeable could be used while another with identical properties (except for the above which I had ignored) wouldn't. Setting those properties back to the default values made the object useable again. Wierd.

See the thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=535748&forum=113

Effects

Here you can find information concerning the effects in the nwn2 Toolset.

DLA Tutorial: Effects

BenWH over at DLA has posted another great tutorial for the nwn2 Toolset. This time he takes on the effects editor.

Well, this is actually a plug in, but it comes included with the toolset, so I've placed it here with the tutorials.

We're going to create just one effect to get started, but because I am far from being a dab hand with this editor, you can then use this experience to get comfortable with it:

Read the full tutorial:
http://www.dladventures.net/vB/showthread.php?t=3843

nwn2toolset: Visual Effects Plugin Tutorial

There's a good tutorial on nwn2toolset.com on using the visual effects editor, where he takes you though the process of making a snow effect.

Check it out here:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/plugin/visualeffects.html

 

pfx/bbx/sef

Pfx get generated by the effects editor and should be saved in your campaign's individual folder inside the campaign folder.

For example:
C:\Documents and Settings\\My Documents\Neverwinter Nights 2\Campaigns\\effect1.pfx

More from LysanderReturns at http://nwn2forums.bioware.com/forums/viewtopic.html?topic=520330&forum=1...

"The pfx/bbx/sef files associated with your custom vfx can go into a custom campaign folder, ie a new campaign. The /campaigns folder is for holding /campaigns/[individualcampaign] folders.

ie: campaigns/Purgatorio/customvfx.sef would make the customvfx.sef accessible for any modules associated with the Purgatorio campaign (using the campaign editor).

The .sef can also go into a hak. It will also work in override.

Finally, there is Dev post around here somewhere that says you can put them in the temp module folder and they will get saved into the module.

-Monty"

Currently, the suggested way to add a sef file to a module at the time of play is to place it in the override directory. The next patch is supposed to address some issues hak files.

Lights

I opened one of the OC areas to see what settings they defined for realistic firelight (torches, candles, fireplaces, etc). Based on that, these are the settings I am using for basic light sources:

Behavior

  • Lerp: False
  • Flicker: TRUE
  • Flicker Variance: 0.05
  • Flicker Rate: 18
  • Flicker Type: Jumpy

Shadows

  • Cast shadow?: True
  • Shadow Intensity: Between 0.3 and 0.6 depending on how it looks.

You may also want to nudge the colors just a bit towards red and orange. Not to the point of being overpowering, but just enough that it's not plain white and gives a subtle red/orange undertone.

nwn2toolset: lighting tutorial

Nwn2toolset posted this great tutorial on using lights by Geethree. It covers shadows, lerp and some other great items that you might have missed on your first pass through the lighting options.

Check it out here:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/blueprints/lights/light.html

Stores and merchants

From the official documentation:

"Stores are only accessed through script in a conversation – they are not objects that the player can detect. Stores have blueprints just like other types of objects. After you create your store’s blueprint, place it on the map normally. It is generally best to place your store next to the NPC. Check out the Sample Module for an example of a store."

Stores are usually started from a script attached to a conversation using the "ga_open_store" script. Place a store in the area and use the tag for the store as the first parameter.

Item costs 

The nMarkUp and nMarkDown parameters are for when you want to adjust a store's buy and sell price due to a plot driven situation or some other condition. Generally, you can leave these at 0 and 0.

You can create your own stores based on the pre-generated ones by right clicking and choosing copy blueprint. Note that when you do this, the seling and buying percentages are both 0. If you don't fix this, everything in your store will have a base cost of 1.

Thanks to seryn for doing the leg work to figure out that the OC uses a standard sell price of 100% when players purchase items and a 40% of sell price when the store buys from the player. These options are located in the properties window of the store. This is also the balance that Berliad's FRW character creator uses.

Plugins

If you're having problems working with items in stores, you may want to consider Lazjen's CPS Inventory Manager. Some features in this plugin include:

  • Full item listing per store tab panel
  • True Item Costs that match in game amounts
  • Icons shown next to items
  • The ability to choose the quantity of an item (use -1 for infinity in Stores)
  • Link to the property editor and previewer
  • A selection of filters on the items shown: Included Base Item Types, Exclude Creature Items, Exclude Zero Quantity Items, Exclude Zero Cost Items, Cost Range Filter, Name Filter and Description Filter
  • Some filter settings remembered between sessions (work in progress)
  • Buy/Sell item types setup for Stores
  •  

Issues with stores in patch 1.05

GodBeastX, Ash Darkwood and others recently reported a problem with patch 1.05 where you can no longer  set the buy and sell list of item types for stores. Apparently this worked fine in 1.05 beta, but now throws an exception and makes it impossible to set up these lists in 1.05 final.

The bug was reported and acknowledged by Rob McGinnis, Obsidian Community Coordinator.

Check out the thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=560804&forum=113&sp=0

Variables

You can set variables on blueprints and objects by clicking on the "..." icon in the "Variables" field under the "Scripts" section of the Properties window. Choose the variable type that you will use (string, integer, etc) and place the value in the appropriate field.

This allows you to set flags that scripts can read. This is how switches work.

There have been some reports that setting a value without setting the type will result in a corrupted module. Hopefully this will be fixed soon, but in the meantime, make doubly sure you set the type when assigning variables.

Conversations

Information about conversations.

Tutorials

There are a lot of good tutorials out there on basic conversation creation. Here are just a few that I've found useful that deal explicitly with tutorials.

Also be sure to check out the conversation sections in the more general tutorials listed in the Getting Started section of this site.

Machinations: Conversation Tutorial

BetterThanLife over at Machinations.org has posted a tutorial on conversations. This tutorial teaches you how to implement conversations, and then goes into some of the more advanced details of creating different types of dialog conversations. The included module, gives three distinctly different examples. An explanation of the use of 'static cameras' is also given and shows how they aren't as 'static' as many think.

Download the zip file with a pdf and example module here: http://www.machinations.org/NeverwinterNights2/ConversationTutorial.zip

(Thanks to Usheen for pointing out the new, working link.)  

NWN2Toolset: Conversation Tutorial

NWN2 Toolset has a great section on conversations.

You can find it here:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/conversations.html

Cutscenes

Cutscenes in NWN2 generally happen through a combination of conversations, conversation switches, and camera control. I'll try to expand this more later, but here is a general procedure:

  1. Create your area, creatures, effects, etc.
  2. Create your conversation. Check with the other guides and tutorials listed on this site for more information about how to create a conversation. The one key thing to remember is that every conversation node is basically a camera shot.
  3. Set up your OnClientEnter cutscene script for the area, remembering to attach it to the area. You can make the speaker either the main NPC who will be doing the talking, or create an Ipoint to act as the speaker.
  4. Next place your static cameras. Check out this page on camera control for more information.
  5. Finally, bring it all together with a conversation switch script that you can reference on each node to control the action.

Cutscenes, multiplayer and OnClientEnter

Kid Gloves asked a great question on the official forums about cutscenes and multiplayer. Nimdolf gave this answer:

Well after playing the OC with my friend online, it works like this. Whoever triggers the cutscene gets to control it, pick what to say, etc. and all of the other players see the cutscene also and what choices you choose. If you join the game midway through a cutscene however you must wait until it is over to do anything.

Check out the thread:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=521668&forum=114

jackyo123: Cutscene Tutorial

jackyo123 posted a cutscene tutorial here:
http://nwvault.ign.com/View.php?view=NWN2Tutorials.Detail&id=65

This tutorial document (in rtf format, for those who hate MS-Word) and associated .MOD file walk a basic toolset user through their first cutscene, with animations, movement, etc.

It explains:

- Triggering cutscenes
- Setting up cutscenes that the Player isn't part of (NPC to NPC)
- Camera controls
- Animations
- Basic use of included scripts
- Some snags that you can avoid, that are associated with Cutscene creation

There is *no* scripting in this tutorial, and no scripting knowledge is required. But you should have a basic familiarity with the Toolset.

 

nwn2toolset: How to make cutscenes

NWN2 Toolset has this tutorial, which might help those trying to figure out cutscenes: How to make cut scenes by Montgomery Markland of Rogue Dao Studios.

An overview of setting up a cinematic-style cutscene conversation

What you will need:

1) A conversation
2) A blocking script
3) A way to begin your cutscene (either a speak trigger, an on_client_enter script or something else)
4) Plus the area, npcs etc., etc., etc.

Check it out here:
http://www.nwn2toolset.dayjo.org/ToolsetTuts/blueprints/staticcams/cutscenes.html

FRW: Conversation Tips by David Gaider

Some time ago, Papermonk posted some tips about conversations from David Gaider. I recently ran across it and thought it might be good to revisit. Here's a quote from his intro:

I assume most of you know who that is - if not, he's one of the big design boys at Bioware and had his hand in BG2 a LOT, among other things.

Mr. Gaider joined CODI briefly (before being pulled back to insane grinds at BW) but before he left he really helped us figure a few things out.

Rylock's Conversation Tips

1) If you have a large character to write, TEMP dialogue is your friend.

Don't worry about getting caught up in the details right at the beginning. You'll get bogged down with how something is said rather than just getting the structure together... which is important when the NPC has a lot to say. Write a single line that covers each starting condition ("This is what I say when you first meet me!") and then write really quick lines afterwards that cover only the basics of what you're trying to get across. You can go back afterwards and flesh the lines out and add "flavour" routes in the dialogue later.

2) Write comments.

Even if you're doing the scripting yourself, write comments... write comments whenever scripting is needed, either for a starting condition, somebody's supposed to perform an action, a variable should get set here and so forth. You will thank yourself later.

3) Don't repeat yourself unless you have to.

Too many times we get newbie writers here who will have dialogue where the same information comes up numerous times... and they'll write that information up each separate time. A little differently, to be sure, but it's the same info.

Don't do this to yourself. And don't delude yourself into thinking this makes better dialogue. Always recycle whatever you've already written if it's at all possible. One of the most common ways this is done:

"You want to ask me something, you go right ahead."
1 - PC question #1.
2 - PC question #2.
3 - PC question #3.
4 - I don't have any more questions.

After each question is answered, you loop back to the first line (the "You want to ask me..." or even a new line like "You want to know something else?" that has the same response links). Only when the PC is done with his questions and picks #4 will you then go back to the rest of the information the NPC has.

Recycling sub-menus like this will make your structure much, much simpler to understand (especially for you) than trying to have each separate question flow into everything else the NPC might have to say or do. If you do that, I guarantee you will run into situations where the player wanted to ask something else but the question is no longer available to him.

4) Don't use more Starting Conditions than you have to.

Now, this can be taken in one of two ways. While it can be good writing to have multiple starting conditions when the NPC is clicked on (he says something different based on updated circumstances and so forth), a good rule of thumb would be to include everything that the character needs in a single sub-menu as often as possible.

What do I mean? Another example:

"Greetings once again, <FirstName>. Missed something the last time we spoke, didja?"
1 - Do you know your way around this area?
2 - You mentioned that you lived in the building next door...
3 - I was told the building next door is brand new. Are you lying to me?
4 - You come to this bar often?
5 - What do you know about the other patrons here?
6 - So what's there to do for kicks around here?
7 - Want to play some cards, old-timer?
8 - I got that money that Traul owed you.
9 - I should go.

Now... obviously the player's not going to see all of these PC responses at the same time. You can look at that list and see clearly that some of these responses require some foreknowledge that the PC may or may not have. So you add Starting Condition scripts to them all.

1 - No script. It's always available. During the answer the NPC mentioned he lived in the building next door... set a variable on the PC to indicate that info is known.
2 - Only shows if the variable mentioned in #1 has been set.
3 - Only shows if the variable mentioned in #1 has been set AND another variable indicating the PC has spoken to someone else about the new building is also set.
4 - In this one the NPC will mention that yes, he has been coming here a while. Set another variable on the PC. #4 no longer shows once that variable has been set.
5 - Only shows if the variable mentioned in #4 has been set (or if you figure it's a generic enough question, scratch the variable and both 4 and 5 can always show). In the dialogue resulting from this, the NPC could mention that Traul owes him money and he hasn't been able to collect... whether or not the PC agrees to get the money, set a variable on him (he should at least know about it and be able to ask Traul).
6 - In this one the NPC mentions he likes to play cards and challenges the PC to a game. Set another variable on the PC. #6 no longer shows when this is set.
7 - Only shows when the variable in #6 is set. Goes directly to a game of cards.
8 - Only shows if the PC was able to collect money from Traul (after the variable was set in #5).
9 - Always shows.

...and so on. The benefit for doing all this? At the end of every section of dialogue for the NPC (and keep in mind each of these could go into its own sub-menu with separate questions and routes) you do not have to sit around and weigh exactly which PC responses apply in that situation. Link to them ALL and the dialogue will both sort itself out and flow naturally... and save you a lot of time.

5) Make sure the goods are readily available.

What do I mean by that? Simple... don't bury a good piece of writing somewhere where nobody will ever find it. Unless you intend for something to be an Easter Egg, don't give your NPC's specialized dialogue that will only show up once in a blue moon. If you want to add it later, then fine... but finish the damn thing first or you never will.

6) You can always add more later.

Yes, we are all perfectionists. We want the dialogue to include everything possible the very first time through. Well, suck it up, sister, because that isn't going to happen. Don't over-plan the dialogue... get in what you need, first, and add more stuff in later. And keep in mind not every NPC needs to know or tell everything imagineable.

Here are two additional points by Sethai:

7) Limit your text.

I don't know how it will work in nwn2, but in nwn it is best to limit your text to about 2.5 lines, so each section of dialogue never comes past the npc's portrait. Overflow into another node if need be. Huge blocks of text just look unproffessional and discourage the player from reading them. I try to follow the OC conventions, because it makes the game more immersive when you're not distracted by the little things.

8) Most obvious responses first

When, ordering your responses, try and put the most expected, non consequential response first (stuff like "continue" or "could I ask some questions?"); you don't want people to be 1ing through, and accidentally attack the quest giver. Put your "Goodbye" option at the bottom of the list so people know where to find it.

Here's the original post on the FRW forums:
http://nwcitadel.com/forums/showthread.php?t=227

 

Multiplayer and NWN1 vs NWN2 style

sgt_why asked a great question about writing conversations that are multiplayer friendly. Check it out for yourself here:

http://nwcitadel.forgottenrealmsweave.org/showthread.php?t=1175

A decent amount of this comes down to the options on a conversation. Open a conversation and check the options window and you'll see several items of interest. The mains ones here are Multiplayer Cutscene and NWN1 style.

Here is a response that I wrote up for that thread and decided to repost here: 

The multi-player flag got a bad wrap because it was over used in the OC. If you don't have it set to multi-player, you should have it set to use the NWN1 style of conversation. A good rule of thumb seems to be:

  • If it's a cut scene where you want everyone to stay in place because people are moving around and there's a lot of scripting (or just because it's an important plot point and you want everyone to pay attention), use NWN2 style and make it a multi-player conversation.
  • If it's a standard dialog where you don't have scripting and don't need to "pause the game", leave multi-player set to false and use the NWN1 style.

Here is a good description by Nimdolf a while back on how multiplayer works in the OC:

"Well after playing the OC with my friend online, it works like this. Whoever triggers the cutscene gets to control it, pick what to say, etc. and all of the other players see the cutscene also and what choices you choose. If you join the game midway through a cutscene however you must wait until it is over to do anything."

Again, that is with the options set to NWN2 style and multi-player. If you don't have multi-player set to TRUE, they are not involved, but I think they are stuck in limbo. If you have the style set to NWN1 and multi-player set to FALSE, players can run around and talk to whomever they want.

Another point is to watch your conversation triggers. All too often you end up with rogues and rangers doing the talking because they are scouting ahead and there is no way to "hand off" the conversation. Usually this is fine. In important conversations where a party might elect a different PC to do the talking, however, let them start it on their terms and you'll take care of a lot of this.

 

The Journal

Here are some things to note about the journal:

1. If you are using campaign, you have to use a campaign journal. The module-level journal will not work.

2. You can either update the journal using the script ga_journal, or you can use the "Quest" field on the "Node" tab to browse and find your journal entry.

3. The players will not automatically get the XP defined in the Journal when they hit an endpoint. You have to manually award the XP by attaching the script ga_give_quest_xp to that dialog node.

 

Camera Control

Tips and tricks for controlling the camera during conversations.

Here is BetterThanLife's section on the camera from his tutorial on machinations.org:

Static cameras are basically cameras that you can place directly into the game
world and position like any other object. If you press the ‘Preview’ tab next to the
properties tab, you will get a rendering of what the camera is seeing, then you
can move it around to carefully position much like a director. You then use static
cameras by attaching them to lines in conversation dialog through the use of the
Node tab as explained in the previous section. You need to give your static
camera a tag name and then link it to the Node. From there you have the ability
to make the camera stationary (default), pan or track. While a static camera
might sound like it doesn’t move, if you use pan or track, it will either always face
the target (pan) or move along with the target (follow). Obviously in order for this
to have any use, the target would need to be moving. This is where the Action
tab comes into play. You might have a script that makes the actors walk as they
are talking, and have static cameras positioned about, following their movement,
so as to create a cut scene. (The camera’s target will be whoever the speaker of
the dialog line is). You can even choose the shot angle of the static cameras,
though I haven’t experimented with it, the names should be obvious as to what
they will do.

You may also want to check out this page concerning the conversation switch script template and how it works with camera control.

Static Camera Orientation

UPDATE: Patch 1.07 and MotB changed the way you interact with the camera. Now you just hold down the right mouse button and you can control both turn the camera and control the pitch. 

Kephisto posted a great set of instructions in the Toolset forum concerning the camera:

Holding down the control and shift keys then right dragging should roll the camera while holding down alt and shift with right clicking will pitch the static camera up and down.

You can rotate it towards the left and right like other objects as well. To raise and lower it hold down the alt button while moving them. All together you can put it in just about any position and angle you want.

If there are any problems it could be, just guessing, that your keyboard shift and alt and control keys may have a different configuration, but in general play around with those three keys when the static camera is selected and you'll discover a feel for it.

In case you may be wondering, I've already placed many static cameras behind NPCs, across treetops and roofs, angled upwards from the ground, and even upside down viewing a monster.

When you're ready to have even more fun, Inder, right click on the static camera and select properties in new window - which, believe it or not, will bring up another properties window of which you can select view and actually see exactly what the camera does, in real time.

From there it is a matter of selecting a line of a conversation and selecting that static camera. Overall, I hope you enjoy using them.

And further down:

Each line in a conversation, whether spoken by the player or the NPC, has its own properties. For example, please highlight any line in a conversation and look at the bottom left, which should have the four tabs : Conditions, Actions, Node, Animations.

While you have a line in your conversation highlighted (selected) please click on the bottom tab named Node. In the Node panel that comes up in the bottom left should be a wondrous amount of options, divided into three main categories : Behavior, Camera Settings, and Line. Click the left (plus) sign of the Camera Settings category.

Now you should see many options for the Camera Settings, for that one specific line of conversation alone. You are now able to set if you want the camera settings to be random or want the Movement Type to be None, Pan, or Track, or even if you want that line of conversation to use any of your Static Cameras or even if you want the visual shot to be a Close Up, Walk-by, Medium, Over the Shoulder, or even more.

Even without using a static camera, just about all the above options (and more) are still available. So if you want to have a specific part of a conversation have a certain look to it, you can merely select a specific option and leave it at that.

When using Static Cameras all that is needed is to place the desired static camera’s tag in the Static Camera field, which is listed in the Camera Settings of the Node panel. There is probably a better way to say all this but I hope at least this information helps.

And a follow-up by LysanderReturns:

Perfect summation Kephisto. Just to add one last step, you need to set the mode field on the node to "static camera" if you want to use a static cam or "user defined" if you want to choose one of the preset cams (like worms eye or walk by or whatnot).

Check it out: http://nwn2forums.bioware.com/forums/viewtopic.html?topic=514512&forum=113

The invisible cameraman

You can use an invisible cameraman to control where the camera is facing and make the static cameras pan and track to follow the action.

Creating your cameraman

First create your invisible cameraman. Go to blueprints > creatures > special to find the "Attach Spell Node" creature. Place him in the area and give him the following attributes:

  1. First create your invisible cameraman. Go to blueprints > creatures > special to find the "Attach Spell Node" creature. Right click and choose "Copy Blueprint" > "Module" to create a module level blueprint.
  2. Change the new creature blueprint's identification fields to "c_cameraman." The full list would be:
    • Comment: {c_cameraman}
    • Template Resref: c_cameraman
    • Resource Name: c_cameraman
    • Localized Description: leave blank
    • Tag: c_cameraman
    • First Name: {c_cameraman}
  3. Make the creature a plot element by changing "Plot" to "True." This is just in case he gets stuck in a fireball or something, so that he won't start attacking the party.
  4. Place the creature in the area. (You can also spawn him in later via a script using CreateObject(). This would also allow you to change his tag.)
  5. Give the placed creature object a unique tag. If you are following campaign naming conventions, this might be in the form of "c_" + area_id + "_cameraman". If you have serveral cameramen in one place, consider using and "A," "B," or "C" at the end.
  6. Consider giving the placed creature object a name in brackets so you can easily find him in the toolset. You may want to use the tag as the localize name so it is easy to locate him in the creature list.

Using your cameraman in a conversation

Now you can select the cameraman via GetObjectByTag() in a conversation switch. This will allow you to move him around using AssignCommand() calls.

Place a static camera in the area and give it a unique tag. To get the camera to follow him we will use the Node tab on the conversation nodes. To do this open your conversation and go to the node you want perform a moving camera effect on. Follow these steps:

  1. Under the camera settings expandable field, click in the "StaticCamera" field to get a dropdown. Use this to find your camera and choose it. You can also just paste in the tag for your camera.
  2. Set the "Mode" field to "Static Camera"
  3. Go down under the "Line" section and set the speaker to be the tag of your cameraman. Note that this is the tag of your placed creature object, not your blueprint.
  4. Finally, go back up under the "StaticCamera" section and we will set the "MovementType." There are three types to choose from.
    • None - The camera will not focus on the speaker for the duration of the conversation node, but will alsi not move. Good to use if you want an establishing shot that doesn't focus on the speaker.
    • Pan - The camera will swivel left or right to follow the speaker. It will also pitch up and down. This is a nice way to follow the action from a static point. You should note, however, that the camera will level out to the horizon when you choose this, meaning that any custom orientation you gave the camera when you placed it (such as having the camera on an angle) will be lost.
    • Track - The camera will change position to follow the creature. Custom orientations seem to be kept with this option, but I have not played with this one as much. I'll follow up once I have more information.

References

Thanks to Deist who suggested the use of the Attach Spell Node creature. Originally I was trying to use the ScriptHidden flag, but found that the camera does not follow the creature if this is on.

Check out the full thread:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=535548&forum=113

Panning the camera to the sky

Here's a threat talking about how to pan the camera up towards the sky:

http://nwn2forums.bioware.com/forums/viewtopic.html?topic=535097&forum=1...

Scripting

A great place to get started learning how to script with NWN2 is http://www.nwn2scripting.com. He's got some great tutorials on getting started, including a "first program" article and some general tips on using the Toolset.

Jassper posted a great list of resourced for those looking to get more familiar with scripting:

Noobs Corner is laid out to help the newbe scripter. Also, here are some links from nwn1 scripting/toolset which can relate to nwn2:

Check out the full thread where he posted these:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=521085&forum=114

Thanks also to Grumpy Badger who recently let me know about this stickied thread on the NWN2 forums:
Helpful Scripts - http://nwn2forums.bioware.com/forums/viewtopic.html?topic=573084&forum=114

 

Variable scope

KublaKhan1797 asked a question about variable scope on the official boards, and ScarfaceDM gave a nice summary:

A standard variable defined outside (and above) any function or void main will be global within that script, a standard variable defined within a function or void main will not be global within that script, it will be usable within the function or void main that it was defined in.

A local variable is stored on an object and is retrievable from any script as long as it exists, they are not persistent unless stored on items in a PCs inventory and then the PCs character exported.

A global variable is not persistent in any way, it is simply 'global', it is not stored on any object thus making it retrievable via its sVarName and not from an object.

A campaign variable is stored in the database folder in your NWN2 directory and also not on any object, and is persistent and retrievable from any script as long as it exists.

The thread is here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=539873&forum=114

Campaign variables

These get get saved to the Bioware Database, which is included in NWN2. They can be accessed via the SetCampaign* and GetCampaign* functions. This is a physical write to the hard drive, and can bog down servers if there are a lot of requests happening at once.

It is worth noting that variable names cannot be longer than 32 characters, or the setting of the variable will fail.

A good system for managing campaign variables is Knat's NBDE.

Globals

Globals get saved to a globals.xml file that gets placed in your save game directory when you save the game. You can set and get global variables with the SetGlobal* and GetGlobal* functions.

These variables exist at a level similar to the campaign folder, meaning they exist in the context of a saved game and can cross from one module to another. They are not physically written to the xml file until a save happens, however.

A good way to check that your variables are getting saved correctly is to save the game an open the file.

One important thing to note is that global variable names can have spaces, but they cannot be more than 32 characters long.

Add From Template

Here are the script templates you can add by right clicking in the Scripts window and choosing "Add From Template." I found it nice to have them available outside of the Toolset for ease of reference.

I'll be adding the rest later.

Conversation Switch

Use this template when you are creating a script that will control actions during a conversation. Pass the variable nAction from the conversation to tell the script which case you want to perform. For instance, pass 100 as the nAction argument to execute the code for case 100.

If you need more information on what a case statement is, see the Wikipedia entry on case statements.

A common way to control the action in conversation switches is with ActionPauseCutscene() and AssignCutsceneActionToObject(). A cut scene action is an action that has a special flag that tells the pause function to resume once the action has been complete. An example from the OC would is:

ActionPauseCutscene(1000, FALSE);
AssignCutsceneActionToObject(oRegulator, ActionWait(1.0f));

This example uses a regulator because the example it comes from (a romance script in module 3500) needed to keep both speakers available for other actions. For best results, a regulator is an Ipoint speaker, which can be found under Blueprints > Placeables > Misc Props. I found that removing the heartbeat from the Ipoint and also using it as the speaker is a good way to make sure that you don't run into conflicting action assignments.

Once you have the pauses set and you static cameras place on your converations nodes, you can add custom functions in the case that will control the movement of other characters. For instance, in the following example you can see that there are a number of custom functions that are included in the file that get referenced.

		case 6:
			ActionPauseCutscene(15000, FALSE);
			AssignCutsceneActionToObject(oRegulator, ActionWait(15.0f));
			MoveCameraman1Again();
			PlayRomanceStinger();
			MovePC();
			DelayCommand(11.0f, FadeOut());
			break;	

and further down:

void MoveCameraman1Again()
{
	object oCameraman = GetTarget("3501_cameraman1");
	object oWP = GetTarget("3501_wp_camerman2");
	
	AssignCommand(oCameraman, ClearAllActions(TRUE));
	DelayCommand(1.0f, AssignCommand(oCameraman, ActionForceMoveToObject(oWP, FALSE)));
}

Note that I usually use GetNearestObjectByTag instead of GetTarget, but that's just because I'm not sure what GetTarget really does.

Obviously you can go pretty crazy with this. Here is the base code from the template for reference:

// 
/*
    master script for conversation X
*/
// 

#include "ginc_actions"


void main(int nAction)
{
    object oPC = GetPCSpeaker();

    switch ( nAction )
    {

        case 100:	//
			break;

        case 200:	//
			break;

        case 300:	//
			break;

        case 400:	//
			break;

        case 500:	//
			break;
    }

}

Area OnClientEnter Cutscene

The onClientEnter cut scene script is a great way to start a cut scene conversation. Create either an Ipoint with a new tag or use a creature as the main speaker. Also create a conversation. Then plug these two into number three (below).

The condition to play and the additional cutscene scripting are great places to use variables, either on the module or campaign level, to control whether the cut scene should fire. For instance, if you set a quest tracking variable called "sidequest2" to be 10 when the party got the quest, and you wanted to test for condition sidequest2 == 10, you'd place that in step two below. Then in the additional cut scene scripting you'd update the quest tracking variable to 20 so that the game knew not to play this cutscene again.

// Area OnClientEnter Cutscene.nss
/*
	Area OnClientEnter event handler template. Setup cutscene(s) to fire when the party enters a new area.
	This script will execute after a group area transition using JumpPartyToArea().
	bCutsceneCondition will determine if a cutscene should play, but each cutscene is restricted to play only once.
	
	HOW TO SETUP A CUTSCENE:
		0. Copy and paste script block into "CLIENT ENTER CUTSCENES"
		1. Specify a title for your cutscene
		2. Replace (FALSE) with condition to play cutscene
		3. Specify Speaker and Dialog of conversation
		4. Add additional cutscene scripting
	
		// Cutscene: 1. Example Title
		if (GetIsCutscenePending(stCI) == FALSE)
		{
			bCutsceneCondition = (FALSE);	// 2. Replace (FALSE) with condition to play
			sSpeakerTag = "";				// 3. Specify Speaker and Dialog
			sDialogName = "";

			stCI = SetupCutsceneInfo(stCI, sSpeakerTag, oPC, sDialogName, bCutsceneCondition);	

			if (GetIsCutscenePending(stCI) == TRUE)	
			{
				// 4. Additional cutscene setup
			}
		}
*/
// BMA-OEI 2/3/06
// BMA-OEI 2/7/06 added speaker == PC check
// ChazM 2/7/06 modified implementation
// ChazM 2/7/06 moved funcs to ginc_cutscene
// BMA-OEI 2/7/06 support multiple cutscenes
// BMA-OEI 2/7/06 revert original controlled char
// BMA-OEI 2/8/06 added comments, Group Area Transition restriction

#include "ginc_cutscene"

int StartingConditional()
{
	// Do not execute if OnClientEnter was not fired from a group area transition
	if (FiredFromPartyTransition() == FALSE) return (FALSE);

	// Get party leader, force control of owned PC
	object oPC = GetFirstEnteringPC();
	object oLeader = GetFactionLeader(oPC);
	oPC = SetOwnersControlledCompanion(oLeader);

	// Initialize temp CutsceneInfo
	struct CutsceneInfo stCI;
	stCI = ResetCutsceneInfo(stCI);
	int bCutsceneCondition;
	string sSpeakerTag;
	string sDialogName;

	// *** START CLIENT ENTER CUTSCENES ***

		// Cutscene: 1. Example Title
		if (GetIsCutscenePending(stCI) == FALSE)
		{
			bCutsceneCondition = (FALSE);	// 2. Replace (FALSE) with condition to play
			sSpeakerTag = "";				// 3. Specify Speaker and Dialog
			sDialogName = "";
	
			stCI = SetupCutsceneInfo(stCI, sSpeakerTag, oPC, sDialogName, bCutsceneCondition);	
	
			if (GetIsCutscenePending(stCI) == TRUE)	
			{
				// 4. Additional cutscene setup
			}
		}
	
	// *** END CLIENT ENTER CUTSCENES ***

	// Cue cutscene or revert control to original character
	if (GetIsCutscenePending(stCI) == TRUE)
	{	
		FireAndForgetConversation(stCI.oSpeaker, oPC, stCI.sDialog);
	}	
	else
	{
		SetOwnersControlledCompanion(oPC, oLeader);
	}

	// If cutscene is pending, fade to black
	return GetIsCutscenePending(stCI);
}

Common Tasks

Here are some common scripting tasks.

Adjusting Characters when they enter a module

A common task that can be more confusing that it should be is adjusting the level, equipment or gold of a character when entering a module. A solid understanding of what scripts are called when the PC enters is a good place to start. Much of this information is taken from this post: http://nwn2forums.bioware.com/forums/viewtopic.html?topic=528278&forum=1...

What happens when a PC enters a module

When a PC logins in, the first events to fire are the OnAcquireItem and OnPlayerEquipItem events. At that point, the PC object exists and can have inventory. But it has no location.

Then OnClientEnter fires. The PC object is complete, but still has no location. (the lack of location is what causes most scripting issues)
Once the PC has been assigned an area, OnPCLoaded is called.

Then OnEnter and OnClientEnter are called for the area the PC ends up in. (OnEnter is called for all creatures entering an area - including NPC right after onModuleLoad, OnClientEnter is just for PCs)

A trigger would be called last.

Transitioning between modules in a campaign

One more thing I noticed: when you transition to a new module in a campaign (StartNewModule and LoadNewModule), OnPCLoaded is not called. OnClientEnter is called, and so are the area's OnEnter and OnClientEnter. (onClientLeave is also not called)

OnPCLoaded is called when a PC logs out and back in.

Adjusting the new characters

The best way I've found to adjust a new PC is to use an OnClientEnter Script. Go to View > Module Properties to get to the Module Properties window. Under the Scripts heading, look for the On Client Enter Script.

The following script is an example that checks to see if this is the first time the PC has entered the current campaign, removes all inventory, then sets the XP and gold for a level 3 character.

// example_oncliententer
/*
Description:
Onclient enter to call
Also has additional functions to set up first time
entry scripts for the pc.
FRW xp and gold guidelines:
Level XP Gold
2nd 1,000 450
3rd 3,000 1,350
4th 6,000 2,700
5th 10,000 4,500
6th 15,000 6,500
7th 21,000 9,500
8th 28,000 13,500
9th 36,000 18,000
10th 45,000 24,500
11th 55,000 33,000
12th 66,000 44,000
13th 78,000 55,000
14th 91,000 75,000
15th 105,000 100,000
16th 120,000 130,000
17th 136,000 170,000
18th 153,000 220,000
19th 171,000 290,000
20th 190,000 380,000
*/
// Vendalus Nov 15, 2008

// Removes all items from the players inventory
void RemoveAllItems( object oPC )
{
DestroyObject(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_ARROWS, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_BELT, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_BOLTS, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_BULLETS, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_NECK, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC));
DestroyObject(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC));

object oItem = GetFirstItemInInventory();
while( GetIsObjectValid(oItem) ){
DestroyObject(oItem);
oItem = GetNextItemInInventory();
}

}

// Checks to see if this player has already entered the campaign for the first time
int GetHasEnteredThisCampaign( object oPC )
{
return GetGlobalInt("ENTERED_"+GetName(oPC));
}

// Notes that this player entered the module for the first time
void SetHasEnteredThisCampaign( object oPC )
{
SetGlobalInt("ENTERED_"+GetName(oPC), TRUE);
}

// Gives some starting gold
void GiveStartingGold( object oPC, int nAmount )
{
int nGold = GetGold(oPC);
TakeGoldFromCreature(nGold, oPC, TRUE);
GiveGoldToCreature(oPC, nAmount);
}

void main()
{

// get our entering player
object oPC = GetEnteringObject();

// Only run if this is a pc who is entering for the first time
// and who is not a DM.
if( GetIsPC(oPC) && !GetHasEnteredThisCampaign(oPC) && !GetIsDM(oPC)){

// Note that this pc has entered for the first time
SetHasEnteredThisCampaign(oPC);

// Remove all items from the entering player
RemoveAllItems(oPC);

// Give them some starting gold for level 3
GiveStartingGold(oPC, 1350);

// Adjust to level 3
SetXP(oPC, 3000);

}

}

Obviously in a case like this, you'd want to present the character with a store immediately. Note also that there is a chart at the top of the script showing the XP and total gold guidelines per level as outlined by the Forgotten Realms Weave.

What happens when a PC leaves the module

Similarly, when the PC logs out OnClientLeave gets called. At that time, the client information is no longer associated with the object, just the physical characteristics. (which is another scripting issue) Then OnExit for the area is called (unless the PC logs out dead, then it is not called). Usually, there is nothing to do here and there have been some reports of this not firing correctly all the time.

Ambient Animations

A good place to start with general animations is the switches page here:

http://wendersnaven.com/node/43

The short answer is that you can set the following variables on a creature:

Ambient Animations
X2_L_SPAWN_USE_AMBIENT = 1

Immobile Animations
X2_L_SPAWN_USE_AMBIENT_IMMOBILE

With no waypoints, "X2_L_SPAWN_USE_AMBIENT" includes the familiar wandering around near their spawn point and doing some basic interactions with other NPCs. "X2_L_SPAWN_USE_AMBIENT_IMMOBILE" causes them to do the same interactions (waving, force talking, etc.), but they stay in one place. They will turn to face other NPCs, however.

There are a few waypoints that cause additional behaviors. From x0_i0_amins:

Creatures will move randomly between objects in their
area that have the tag "NW_STOP". (I think there is a % chance of them doing this or the standard wander around.)

UPDATE:  After some testing, it appears the behavior in the next two paragraphs does not work. Generally speaking, waypoints across areas don't work at all in NWN2. They tended to be inconsistent in NWN1, also. Begin incorrect documentation:

 Creatures who are spawned in an area with the "NW_HOME" tag
will mark that area as their home, leave during the day,
and return at night.

Creatures who are spawned in an outdoor area (for instance,
in city streets) will go inside areas that have one of the
interior waypoints (NW_TAVERN, NW_SHOP), if those areas
are connected by an unlocked door. They will come back out
as well.

End incorrect documentation. 

There is a good conversation about ambient animations scripts happening here:

http://nwcitadel.forgottenrealmsweave.org/showthread.php?t=1184

Changing area music with a trigger

qwertyuiop666 asked a question about how one would go about changing the background music in an area when a player walks over a trigger. Here's his question:

I would like to have the music change when the player walks down a path. I am assuming that the best option is to do it from a generic ground trigger to change the music playing when I step on it? I managed to make a trigger that stops the current song. That was easy. I made the ground trigger and then in the "On Enter Script" I just used the "ga_music_stop" script from the drop down.

Shaughn78 and Melirinda were kind enough to give some helpful suggestions. Here is the script that Shaughn78 eventually posted with some minor tweaks for readaiblity:

void main()
{
object oEnter = entering object;
object oArea = GetArea(oEnter);
int nMusic = GetLocalInt (OBJECT_SELF,"music");
int nDefault = GetLocalInt (OBJECT_SELF,"default");
int nCurrent = Get Current Music;
int nOnce = GetLocalInt (OBJECT_SELF,"once");
if(!GetIsPC(oEnter))
{
return;
}
if (nOnce == 0)
{
SetLocalInt (OBJECT_SELF,"once",1);
SetLocalInt (OBJECT_SELF,"default",nCurrent);
}
if(nCurrent != nMusic)
{
MusicBackgroundChangeDay(oArea, nMusic);
}
else
{
MusicBackgroundChangeDay(oArea, nDefault);
}
}

See the full thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=645938&forum=114

 

Death and Respawn

UPDATE: Kaldor Silverwand recently posted a good walkthrough on how to use the death and bleeding scripts from SoZ on the official forums. If you've got that installed, it might be a nice reference.

There are a number of options out there for dealing with death, but when dealing with respawn, there is one very important thing to know:

The death and respawn event scripts never on Respawn fire when you use the GUI_DEFAULT_DEATH_SCREEN with DisplayGuiScreen. This is the call for nwn_o0_death, the default script for death events.

Both nwn_o0_death and nwn_o0_respawn contain respawn code, but the gui actually uses a callback script named gui_death_respawn. Opening this file through the File > Open script/conversation menu, you'll see that the default death script is:

// gui_death_respawn.nss
/*
Death GUI 'Respawn' callback: wake up groggy
*/
// BMA-OEI 6/29/06


#include "ginc_death"


void main()
{
// Resurrect PC
object oPC = OBJECT_SELF;
WakeUpCreature( oPC );
RemoveDeathScreens( oPC );

// Apply Groggy penalty
effect eGroggy = EffectDazed();
//eGroggy = EffectLinkEffects( EffectSlow(), eGroggy );
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eGroggy, oPC, RoundsToSeconds( 2 ) );
}

This results in the character standing up right where the died. Generally, it is better to send them to a safe place, such as a standard waypoint with the tag "NW_DEATH_TEMPLE".

For example, here is how Lordniah did his respawn callback script in the FRW base module.

// gui_death_respawn.nss
/*
Death GUI 'Respawn' callback: wake up groggy
*/
// BMA-OEI 6/29/06


#include "ginc_death"


void main()
{
// Resurrect PC
object oPC = OBJECT_SELF;
WakeUpCreature( oPC );
RemoveDeathScreens( oPC );

// Apply Groggy penalty
effect eGroggy = EffectDazed();
//eGroggy = EffectLinkEffects( EffectSlow(), eGroggy );
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eGroggy, oPC, RoundsToSeconds( 2 ) );


//Jump respawner to temple waypoint if it exists
object oTemple = GetObjectByTag("NW_DEATH_TEMPLE");

if(GetIsObjectValid(oTemple))
{
ClearAllActions(TRUE);
ActionJumpToLocation(GetLocation(oTemple));

}

}

Thanks to Lordniah for putting that comment in his k_module_respawn script that it never fires. Hopefully this info will help someone else out there.

GetGoldPieceValue()

Thanks to cdaulepp and loudent2 for pointing this one out:

When you are using GetGoldPieceValue() on an item to get the value, if the item is not identified the function will return 1.

See the full post here:

GetGoldPieceValue() Does it work correctly?

 

Lugoun's Find and replace a word in a string

Lugoun posted this handy script in the Helpful Scripts thread in the official forums. It allows you to do a find and replace on a string. Just pass in the text you want to perform the find and replace on, the string to find and the string you want to replace it with. His script is below and I've added comments.

// Returns a string based on sStartString where sCurrentWord is replaced by sNewWord 
string FindReplaceSubString(string sStartString, string sCurrentWord, string sNewWord)
{
int nLength = GetStringLength(sStartString);
int nCurrSubLoc = FindSubString(sStartString, sCurrentWord);
string sLeftSide = GetStringLeft(sStartString, nCurrSubLoc);
int nCurrentLength = GetStringLength(sCurrentWord);
int nLeftSideLength = nCurrSubLoc + nCurrentLength;
int nRightSideLength = nLength - nLeftSideLength;
string sRightSide = GetStringRight(sStartString, nRightSideLength);
string sNewString = sLeftSide + sNewWord + sRightSide;
return sNewString;
}

So for instance, you can do a call like this:

string sStartString = "the quick brown fox is quick";
string sNewString = FindReplaceSubString(sStartString, "quick", "slow");

Which would assign sNewString a value of "the slow brown fox is slow".

Making a creature lay down

You can make a creature lay down by placing the following two commands on a dialog node:

ga_play_ca_snd with the sAnim set to "laydownB"
ga_play_custom_animation with the sAnim set to "proneB"

Make them stand up by using:

ga_play_custom_animation with sAnim set to "standupB"

Note that this only work for NPCs you can select via a tag.

Thanks to John B. Gardner's Animation Viewer, where I figured out how to do this.

Making an invisible object cast a spell at the PC

In this thread, puiwaihin was trying to figure out why his invisible creature couldn't cast spells at the PCs. In the end they figured out that anything that is invisible or hidden can't do it.

jackyo123  suggested making the creatures super small instead.

Check it out here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=576056&forum=114

NWScript: Giving gold in a conversation

Bemmu over at NWScript.com has created a tutorial that will take you through creating a basic conversation with an attached script to give the PC Speaker some gold.

Tutorial level: very basic

Following along with this tutorial should only take a few minutes. The goal will be to create a new Neverwinter Nights 2 module with one creature in it that you can interact with to receive gold from it.

Click here to view the tutorial:
http://www.nwscript.com/how-to-make-an-npc-give-you-gold.php

NWScript: Levers and doors

Bemmu over at NWScript has created a tutorial for attaching a script to a lever that will open a door.

Tutorial level: very basic

The goal in this tutorial is to create a lever that will cause a door to open when pulled. Following along should be very easy and there will only be about three lines of nwscript (the scripting language in Neverwinter Nights 1 & 2) involved.

Head over to NWScript to check it out:
http://www.nwscript.com/making-a-lever-operated-door.php

NWScript: Object Creation

Bemmu over at NWScript.com has created a tutorial for creating multiple objects in a line using vectors. The object in question happens to be beer!

Tutorial level: basic

A nice feature of virtual worlds is that things can be created out of thin air without cost. In this tutorial we will play a bit with this by creating a sort of beer vending machine, where pulling a lever will add a new beer bottle to the end of an endlessly expanding row of them.

Head over to NWScript to check it out:
http://www.nwscript.com/infinite-beer.php

Scripted Waypoints

A great way to control ambient movement of NPCs is using scripted waypoints. See the sticky thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=512800&forum=114

Examples

You can see scripted waypoints at work in the Official Campaign's 1700_Merchant_Quarter.mod and 3000_Neverwinter_A3.mod merchant exterior areas. In module 1700 the road network method is used for ambient commoners (although I could not find the actual script) and in 3000 the dock workers use it.

Here's what Charles Mead (Gameplay Scripter) posted:

Here's some info on a new feature called Scripted Waypoints.

Scripted waypoints builds on the current waypoints system by making the arrival at each waypoint call a script. There are no special requirements for preparing this – it will work with any NPC using the regular default scripts and any new or previously placed set of walkway points.

Quick refresher of the standard waypoint system:
Creatures will automatically walk along a sequence of waypoints that are tagged according to the following convention: “WP_<creature’s tag>_##”. The NPC will begin the journey at waypoint 1 and continue traveling sequentially to waypoint n, and then back again in reverse.

Basic Useage:
In the new “scripted waypoint” system, whenever a creature reaches a waypoint, it calls a script that is named very similarly to the tag used for the waypoints, like this: “wp_<creature’s tag>”. Notice there is just one script for the entire set of waypoints. If the script does not exist, then nothing additional happens and the NPC simply walks back and forth through the set of waypoints.

Below are some examples of “scripted waypoints” scripts:

Example 1.
This script tells the NPC to stop at every waypoint and face in the direction the waypoint is facing and pause 1 second before continuing to the next waypoint.
Notice the inclusion of “ginc_wp” which has a number of helpful functions such as FaceAndPause().

 

#include "ginc_wp"
void main()
{
    int iCurrentWP = GetCurrentWaypoint();
    FaceAndPause(iCurrentWP, 1.0f);
}

Note how we call GetCurrentWaypoint() which returns the waypoint we have just reached. This will typically always be the first thing called in a “scripted waypoints” script.

Example 2.
This is a more complex script that completely overrides the normal waypoint behavior and demonstrates how each waypoint can be individually scripted. It accomplishes the following:
When the NPC reaches waypoint 1, he will sit down for a few seconds, and then randomly travel to one of the other waypoints in the set other than the first.
When the NPC reaches waypoint 2, he will play a “get low” animation, and then proceed to waypoint 1.
When the NPC reaches waypoint 3, he will simply head back to waypoint 1.
If there are more than 3 waypoints in the set, then when the NPC reaches one of those he will behave in the default way.

 
#include "ginc_wp"
 

  
#include "ginc_wp"

void main()
{
int iCurrentWP = GetCurrentWaypoint();
int iNextWP;
switch (iCurrentWP)
{
case 1:
iNextWP = Random(GetNumWaypoints()-1) + 2;
SetNextWaypoint(iNextWP);
ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 7.0);
break;
case 2:
SetNextWaypoint(1);
ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 4.0);
break;
case 3:
SetNextWaypoint(1);
break;
}
}

Note in this example the use of SetNextWaypoint(). The “next” waypoint is the one the NPC is enroute to. SetNextWaypoint() allows us to override this and redirect the NPC to an alternate waypoint.

The script template “wp_tag” is available in the script templates directory in source safe. Simply copy and paste it with the proper script name, replacing the word “tag” with the tag of the creature that will be walking waypoints.

*Advanced Usage*
How to have two or more creatures with different tags walk the same set of waypoints:
To override the initial waypoint set a creature uses, simply set a local string variable “WP_TAG” on the creature with the value of the desired waypoint set to use. So, if you have a bear waypoint set for a creature tagged “bear”, you could get a chicken to also walk these waypoints by setting the chicken's local variable WP_TAG to “bear”.
Note that this variable is only checked when the creature is first spawned, so changing this value via script will have no effect.

How to change the set of waypoints a creature walks dynamically:
You can change the set of waypoints a creature walks at any time via script using this function:
object SetWWPController(string sWalkWayPointsTag, object oCreature=OBJECT_SELF);

So from the previous example, we could have our chicken walk the bear’s waypoints by calling this function in script:
SetWWPController(“bear”);

How to pause/restart a creature walking waypoints.
To stop a creature from walking waypoints, use:
SetWalkCondition(NW_WALK_FLAG_PAUSED, TRUE);

You may also want to clear all actions, otherwise, the creature will still complete his pending actions which will take him to whatever the next waypoint is.

To Restart a creature walking waypoints, use:
SetWalkCondition(NW_WALK_FLAG_PAUSED, TRUE);

The creature should get started on his next heartbeat.

How to create a road network:
The basic outline for a script like this is available in the script template “wp_road_walker” and reads as follows:

  
#include "ginc_wp"

const int REDIRECTOR_WP = 1;

void main()
{
int iCurrentWP = GetCurrentWaypoint();// where we are
int iNextWP;
switch (iCurrentWP)
{
case 1:
// Node 1 should be placed off somewhere out of the way. This is where the creatures
// will hang out in between reaching the end of the path and starting on a new path.
// Creatures will change their appearance in between travels.

// 1st param is the list of nodes they may reappear at. Must follow the pattern XX,YY,ZZ...
// 2nd param is the length of time to wait before reappearing.
StandardRedirectorNode("02,03", 5.0f);
break;
case 2:
// Nodes 2 on up define the network the road walkers travel. They will never return to the node
// they just came from. When they reach an end node (typically a door or a route out of the area)
// they will be be "redirector node" - typically node 1.

// 1st param is the list of nodes they may travel to. Must follow the pattern XX,YY,ZZ...
// (end nodes are those with only 1 element in the list)
// 2nd param is the redirector WP
StandardRoadNetworkNode("03", REDIRECTOR_WP);
break;

case 3:
StandardRoadNetworkNode("02", REDIRECTOR_WP);
break;

}
}

Where can I learn more about other thing I can do?
Many useful functions are listed in the prototypes of the include file “ginc_wp”.

 

Sitting

Patcha posted a script to let PCs sit on objects.

I'm providing you the way to let object be "sittable" and the script that allow PC to sit on them!

The file contains:
- the script (in a .erf to import)
- the English tutorial to bring "sittable" objects
- the Italian tutorial (the same)
- a module with many brench and chairs, to test this mothod

Check it out on the vault:
http://nwvault.ign.com/View.php?view=NWN2Scripts.Detail&id=43

Starting a conversation with a placeable

This apparently still uses the old "nw_g0_convplac" from NWN1. Follow these steps:

  1. Start by copying the placeable you want to use. Right click on it and choose "copy blueprint > module". Find it at the bottom of the list and click on it to access its properties.
  2. Change the name, tag, resref as needed in order to keep track of it.
  3. Under the behavior section, set the following:
    • Plot = TRUE (optional, but suggested)
    • Static = FALSE
    • Useable? = TRUE
  4. If you have not already done so, create your conversation file and give it a name. Return to the behaviors section and either paste that name into the "Conversation" field, or use the dropdown to choose it from the list.
  5. Finally, under the Scripts section, set the On Used Script to "nw_g0_convplac"

Test it out and your should get your conversation when you use the placeable.

Treasure

The default treasure generation script seems to be gp_treasure_op_de. It seems to check variables set on the container it is called from. It includes some of the X2 scripts from HotU. I spent some time walking through how this all works.

Note: After playing with this system a bit more, I've found that:
1. The base chance is 50%. This means that unless you set the base chance on an area, you'll get just a few gold just over 50% of the time.
2. The magic treasure type tends to give one or two +1 weapons for a level 1 PC. This may be a bit over-powered for low-level mods.
3. For better customization, consider lordniah's FRW base module's implementation of the NWN1: SoU treasure scripts (For more see http://www.wendersnaven.com/node/98).

gp_treasure_op_de

Here is the header comment, which explains the basics:

// gp_treasure_op_de
/*
    Spawns in general purpose treasure and gold based on variables:

	TreasureClass - one of three values.  Default is low
		const int X2_DTS_CLASS_LOW     = 0;       //Treasure Class Low
		const int X2_DTS_CLASS_MEDIUM  = 1;       //Treasure Clas Medium
		const int X2_DTS_CLASS_HIGH    = 2;       //Treasure Class High

	TreasureType - add desired types together.  For example, gold + disposable = 5
		Defualt is 5 (gold + disp)
		Note that you cannot add the same type more than once (i.e. no gold+gold).
		const int X2_DTS_TYPE_DISP 	= 1;
		const int X2_DTS_TYPE_AMMO	= 2;
		const int X2_DTS_TYPE_GOLD	= 4;       	// actually gold and gems
		(not allowed) const int X2_DTS_TYPE_ITEM	= 8;        // char specific Item (ignores treasure class)
		const int X2_DTS_TYPE_MAGIC	= 16;       // random magic items
		const int X2_DTS_TYPE_MUNDANE = 32;     // random mundane items

	This script should be placed in the container's OnOpen and OnDeath events.
	If bashed, disposeable will be dropped and broken item generated.
	If no treasures are generated, 1d20 gold will be created.
*/

This allows module authors to quickly create random treasure of different types by setting both the "TreasureClass" integer variable and the "TreasureType" integer variable on the container. "TreasureClass" uses a simple 0, 1, or 2. "TreasureType" uses a single number that adds up the type values you want for the container. For example, ammo (2) + gold (4) + magic items (16) would be a value of 22.

An important thing to note is that X2_DTS_TYPE_ITEM (8) is not allowed. Here is the reason given in a comment further down in the script: "these don't scale and are to dangerous for balance reasons to have in the standard treasure generation."

x2_inc_treasure

Our script then calls DTSGenerateTreasureOnContainer(), which is located in "x2_inc_treasure." This script first calls gets a random number of items to create based on the call to DTSGetMaxItems().

Looking at DTSGetMaxItems(), we see that it first looks for the module-level integer variable "X2_DTS_MAXITEMS." If it can't find it, it uses a default of 2. Note that this variable is not set in the switches file or in the default "On Module Load" file, which means the value will be 2 unless you have specifically set it.

Returning to DTSGenerateTreasureOnContainer(), the next step is to call DTSGenerateTreasureItems() for each item we are going to create. This function checks the chances for each of the types of items we told it to create with the variables set on the container. The chance is defined by DTSGetBaseChance(). The default is defined as 50 in the constants at the top of the file, but these can be overridden at the area and module level with the variable "X2_DTS_BASECHANCE." If a class and chance condition is met based on a randomized number, an item is created by DTSGetRandomItemResRef().

Looking at DTSGetRandomItemResRef(), we see that we first have to get the name of the .2da file we want to reference using DTSGet2DANameByType(). This file looks for a module-level string variable, and uses a default if it can't find one.

The variables it looks for are:

  • X2_DTS_TYPE_DISP
  • X2_DTS_TYPE_AMMO
  • X2_DTS_TYPE_ITEM
  • X2_DTS_TYPE_GOLD
  • X2_DTS_TYPE_MAGIC
  • and X2_DTS_TYPE_MUNDANE

(Note that these match the constants uses for the treasure type.)

The default .2da files that will be used are:

  • des_treas_disp
  • des_treas_ammo
  • des_treas_gold
  • des_treas_items
  • des_treas_magic
  • des_treas_mundane

Remember that all these files can be found in Data/2da.zip, in your NWN2 programs files ("C:\Program Files\Atari\Neverwinter Nights 2\Data" by default). Extracting the .zip files to your desktop and opening the .2da files in Microsoft Excel, will reveal how these are laid out. For example, looking at the random magic .2da file (des_treas_magic.2da), will show that the low class items are all +1, the medium class items are +1 and +2, and the high class items are +2, +3 and +4. There is also a very high column, which is probably left over from the epic levels in NWN1: HotU.

Wandering Monsters

Controllore posted a concise answer to using the old HotU "wantering encounter while resting" script.

View the module properties, in the On Module Load event you will see "x2_mod_def_load". Uncomment the line (around 123)

SetModuleSwitch ( MODULE_SWITCH_USE_XP2_RESTSYSTEM, TRUE )

Then where you see

SetWanderingMonster2DAFile( "des_restsystem" )

uncomment it and change "des_restsystem" with any other name you choose.
"des_restsystem" is the name of the 2da file that will be used for the wandering monsters (type, percentage of appearing at daytime/nighttime).
Edit des_restsystem.2da, do your changes and save it with the name you used in x2_mod_def_load.

That should do it.

Edit:
Into your areas, insert a variable named X2_WM_ENCOUNTERTABLE of type string. Its value must be the name used for the TableName in the des_restsystem.2da.

Read the full threat here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=535148&forum=114

Companions

Here's some helpful resources for working with companions... (more cominig soon)

Companion Influence

The companion influence system used in the OC is not available by default in new modules. To get them, copy all of the kr_influence* scripts from "C:\Program Files\Atari\Neverwinter Nights 2\Campaigns\Neverwinter Nights 2 Campaign." You can then paste them into your own campaign. Note that you will need to edit the constants and companion names across all scripts to match your own companions.

FRW: suggestions for dealing with companions

In a conversation between Wayne and Lord Niah over in the FRW forums Lord Niah had some good suggestions for working with companions.

Here are some rules of thumb for dealing with companions and the roster. I don't recall some the exact names for commands and do not have acces to the toolset at the moment.

#1 You should only have one instance of a companion placed within your campaign and you should never spawn that companion using CreateObject.
#2 If you want to destroy a companion, then use the despawn command (not the DestroyObject command)
#3 If you want to spawn your companion back in, use the spawn command instead of CreateObject
#4 If you want to add your companion to the roster, but don't want players to see them in the GUI selection screen, then just mark them as Campaign NPCs. Don't waste time adding/removing the companion from the roster every time they join or leave the party. Once they are in the roster, you just have to add/remove them from the party.

Check out the forum here:
http://nwcitadel.com/forums/showthread.php?t=873

Henchmen

Henchmen are companions who the player cannot directly control or adjust inventory for. Thanks to sgt_why for this explanation on how to set them up.

Here's his post from http://nwn2forums.bioware.com/forums/viewtopic.html?topic=545390&forum=114

for this example;
string sTag = "c_human"

// is this a henchmen ? TRUE or FALSE
gc_henchman(sTag)

// this adds them to your party as henchmen, not companion
ga_henchman_add(sTag);
/*
note: this has (4) actual parameters ... the last flag can be very useful.
sTag - tag of the creature you want to add
bForce - if set to 1, sTarget will be added even if player already has maximum henchman
sMaster - The Creature you are adding the henchman to (default is PC Speaker)
bOverrideBehavior - if set to 1, sTarget's event handlers (scripts) will be replaced with henchman ones.
*/

// removes the henchmen from the party
ga_henchman_remove(sTag);

- - - - -
I put all of these into the conversations and seems to work great. In fact, think if the henchman dies .. they are removed from the group as well.

And you cant click on them and change thier inventory .. although I did notice there appear to be scripts out there to make the henchman show you his inventory and such, like a companion. But it would need to be during a conversation or such. (I think?)

I wanted to add a couple "friendly"(s) in my areas .. that if the PCs save them, will offer to help out for a short time .. as well as award 50xp for not letting the mobs kill them off.

Following his directions, I was able to create a few henchmen and get them to work with very little setup. Some quick things I noticed:

  • A "guard this area and I'll come back for you" dialog option with the ga_henchman_remove script on it worked great to when you want to temporarily ditch them.
  • Use unique tags for each creature. If, in his example, you have a set of friendlies standing around, each one needs it's own conversation and tag. It helps to write the conversation first, then duplicate it. This will lead you to creating more distinctive NPCs anyway.
  • Set the bOverrideBehavior = TRUE if you didn't do anything with the scripts on your henchmen, or they won't follow the PC.
  • Commoner NPCs won't attack, which worked just how I wanted. I was able to create a lost little girl that the party could escort home. Thankfully, she didn't run up and try to punch people in the groin.

Kudos to OE on making such an easy to use system, and thanks again to sgt_why

Groups

Include ginc_groups to see a number script used for working with group of creatures.

Recently DaveyHavock asked a question about how to use groups to create an onDeath event.

Howdy, wondering if someone has a moment to explain how the custom group ondeath script is used. I guess what i dont understand is how to name the grp, i see it uses getgroupname, but how do i define what the group is?

Kaldor Silverwand  provided a good response with an example script:

The first meeting with Neeshka makes use of groups in this way.

The functions you'll need are are in ginc_group.

Here is a bit of script that I have used for having a few halfling NPC's put into a group and then a script is started once they are dead.

Here's the code he posted. Remember to include ginc_groups. Change the group name and tags, then attach this on a dialog action and you're good to go!

	string sGroupName = "HalflingBrothers";
object oNHalfling;
int i;
ResetGroup(sGroupName);
for (i = 1; i<=3; i++)
{
object oNHalfling = GetObjectByTag("NHalfling" + IntToString(i));
GroupAddMember(sGroupName, oNHalfling);
ChangeToStandardFaction(oNHalfling, STANDARD_FACTION_HOSTILE);
StandardAttack(oNHalfling, GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC));
}
GroupOnDeathExecuteCustomScript(sGroupName, "0160_a_cs_halfling_postfight");
 

See the full thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=646321&forum=114

 

Naming Conventions

It's important to name your scripts in a consistent manner so that you know what they do and you know where to find them when you need them. Here is some information to help with naming.

CODI naming conventions

Barry The Hatchet posted a good roll up of the script naming conventions the CODI project came up with in NWN1. Here's the link: http://nwcitadel.forgottenrealmsweave.org/showthread.php?t=1131

Here's the actual list:

Include Scripts
Include scripts should be prefixed with INC_

Event Driven Scripts
Following the prefix for EVENT driven scripts, this is the majority; you have 1 letter denoting the object type that has the event this script goes in, they are as follows:
* N - NPC
* M - Monster/Creature
* A - Area
* O - Module
* P - Placable
* T - Trigger
* D - Door
* R - Trap
* C - Conversation
* E - Encounter
* I - Item - This script is not placed on an item per se, but called by module level scripts.
* X - No Object - Use this for a script that is called by other scripts. Executable scripts.

This character is followed by a two character short for the event it goes in, by category:

* N, M
o CO - onConversation
o DI - onDisturbed
o PA - onPhysicalAttacked
o SP - onSpawn
o UD - onUserDefined
o SC - OnSpellCastAt
o BL - onBlocked
o DM - onDamaged
o HB - onHeartbeat
o DE - onDeath
o CR - onCombatRoundEnd
o PE - onPerception
o RE - onRest

* A
o EN - onEnter
o EX - onExit
o HB - onHeartbeat
o UD - onUserDefined

* O
o CE - onClientEnter
o CL - onClientLeave
o PR - onPlayerRest
o RS - onRespawn
o DY - onPlayerDying
o DE - onPlayerDeath
o LE - onPlayerLevelUp
o IA - onItemActivated
o IQ - onItemAquired
o UI - onUnaquireItem
o ML - onModuleLoad
o HB - onHeartBeat
o UD - onUserDefined
o EI - onEquipItem

* P
o US - onUsed
o HB - onHeartBeat
o DE - onDeath
o AT - onAttacked
o SC - onSpellCastAt
o DM - onDamaged
o OP - onOpen
o OC - onClosed
o DI - onDisturbed
o LO - onLocked
o UL - onUnlocked
o UD - onUserDefined

* T
o CL - onClick
o EN - onEnter
o EX - onExit
o HB - onHeartBeat
o UD - onUserDefined

* D
o AT - onAreaTransitionClick
o OC - onClosed
o DM - onDamaged
o DE - onDeath
o FO - onFailedToOpen
o HB - onHeartBeat
o LO - onLocked
o OP - onOpened
o AT - onAttacked
o SC - onSpellCastAt
o UL - onUnlocked
o UD - onUserDefined

* R
o DI - onDisarmed
o TT - onTrapTriggered

* E
o EN - onEnter
o EX - onExit
o OE - onExhausted
o HB - onHeartBeat
o UD - onUserDefined

* C
o AT - Actions Taken
o AP - Appears When (StartingConditional Script)
o AB - onConversation Aborted
o EN - onConversation end

* I
o US - Called when the item is used.
o AQ - Called when the item is Aquired.
o UA - Called when the item is UnAquired.

Prefix examples

Module OnClientEnter script prefix: OCE_
Area OnEnter script prefix: AEN_
Placeable OnUsed prefix: PUS_
__________________
Just bend the pieces 'til they fit.

Official Documentation: Script Naming Conventions

buried in the official Toolset documentation is a section about naming conventions for scripts. I've replicated it here for easy reference.

All scripts in NWN2 are are prefixed with one of the following:

  • “g” for global scripts
  • “i_” for item related scripts (these are also global)

Item Scripts

Use the following for item scripts:

i_<Item Tag>_ac

script to execute when item activated

i_<Item Tag>_aq

script to execute when item acquired

i_<Item Tag>_ua

script to execute when item unacquired

i_<Item Tag>_eq

script to execute when item equipped

i_<Item Tag>_ue

script to execute when item unequipped

The module events will be written to automatically execute the proper script.

Conversation Scripts

Conversations have 2 script types.

a_<Speaker>…

actions taken

c_ <Speaker>…

conditional (Text appears when...)

Event Scripts

Scripts for events on objects should have a prefix to indicate the Object Type. If an object has multiple events, a suffix should be added each script to indicate the Event Type.

 

Object Type

Abbreviation

Area

use area num

Creature (Being)

b

Door

d

Encounter

e

Merchant

m

Placeable

p

Trigger

tr

 

Event

Abbreviation

Area**

Creature

Door

Encounter

Merchant

Placeable

Trigger

blocked

bl

X

click*

ck

X

X

close*

cs

X

X

X

combat round end*

ce

X

conversation

co

X

damaged

da

X

X

X

death

de

X

X

X

disturbed

di

X

X

enter

en

X

X

X

exhausted*

ed

X

exit

ex

X

X

X

fail to open

fa

X

heartbeat*

hb

X

X

X

X

X

X

lock

lo

X

X

open

op

X

X

X

perception

pe

X

physical attacked

at

X

X

X

rested

re

X

spawn

sp

X

spell cast at

ca

X

X

X

unlock*

ul

X

X

used

us

X

user defined*

ud

X

X

X

X

X

X

* These abbreviations don’t use the first 2 letters of the event name.

** Areas don’t need abbreviations.

Boldfaced events are defaults and are assumed if no event is given.

Other Scripts

Scripts not covered above should use these prefixes

inc_

include file

ai_

artificial intelligence (combat ai)

n_

extra miscellaneous script

Opening system scripts

For those of you like me who could not figure out how to open a system script except from the dropdown on creature properties, look under "File > Open Conversation/Script." The keyboard shortcut is "Ctrl + Shift + o."

It seriously took me a month to find that for some reason.

Spells and spell hooks

Thanks to DedoITA for pointing me in the direction of Lilac Soul's tutorial on spell hooks. Here's the introduction:

Since version 1.59, it has become exceedingly easy to hook spellcasting. Rather than having to edit each individual spell script, all you now how to do is create a single spell script of your own, and then have that script perform whatever you want the spell to do. In that script, you also get to set whether the original spell script should continue or not.

If you only want to edit a single spell, it may still be easier to just edit its spell script, but I still recommend using the spellhook system. Why? Because, if the spell script is updated in a future patch, your edits will still be valid, but so will the ones BioWare made.

However, the new spell-hook system is very useful for editing a number of spells (even all spells), for instance to make it so that they only work under certain conditions, or that, perhaps, the caster automatically takes a certain amount of damage whenever casting a spell. Thus, you can also use the spellhoook system to make certain creatures react to certain spells in different ways, etc. etc. The sky is the limit really.

Some of the menu options have changed for NWN2, but most of this is still valid.

Check out the full tutorial:
http://www.nwnlexicon.com/compiled/tutorial.lilacsoul-spell-hooking.html

 

 

Visual Effects

Creating visual effects through scripting works much the same way in NWN2 as it did in NWN1. Use EffectVisualEffect() to create an effect, then ApplyEffectToObject() or ApplyEffectAtLocation() to place that effect in the game.

From the official NWN2 Documentation:

"Visual effects are composed of effect files, which are individual components of an effect (a particle system, a trail, a billboard, etc.), and SEF files, which point to the effect files and organize them into a more complex visual effect."

Effect constants start with "VFX_".

  • Apply VFX_IMP_ constants instantly, to a target.
  • Apply VFX_DUR_ constants for a duration, either permanent or temporary, to a target.
  • Apply VFX_FNF_ constants instantly, and only at a location.

NWN Lexicon: visual effects samples

The following samples for creating visual effects through scripting are from the NWN1 Lexicon. (Currently the lexicon is at http://nwn1.nwn2lexicon.com/, but I'm unsure what's in store for that site.)

// Sample code for applying a VFX_IMP_ visual, a AC-bonus
// (Mage armor) visual, to a target.
void main()
{
    // This is the Object to apply the effect to.
    object oTarget = OBJECT_SELF;

    // Create the visual portion of the effect.
    effect eVis = EffectVisualEffect(VFX_IMP_AC_BONUS);

    // Apply the visual effect to the target.
    // - We apply VFX_IMP_ constants instantly, to a target.
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}

// Sample code for applying a VFX_DUR_ visual, a 
// stoneskin visual, to a target.
void main()
{
    // This is the Object to apply the effect to.
    object oTarget = OBJECT_SELF;

    // Create the visual portion of the effect
    effect eDur = EffectVisualEffect(VFX_DUR_PROT_STONESKIN);

    // Apply the visual effect to the target.
    // - We apply VFX_DUR_ constants for a duration, here 
    //    it is permanent (could be temporary), to a target.
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDur, oTarget);
}

// Sample code for applying a VFX_FNF_ visual, a fireball, 
// to a location.
void main()
{
    // This is the Target to apply the effect at.
    location lTarget = GetLocation(OBJECT_SELF);

    // Create the visual portion of the effect
    effect eAOE = EffectVisualEffect(VFX_FNF_FIREBALL);

    // Apply the visual effect to the target.
    // - We apply VFX_FNF_ constants instantly, and only
    //   at a location.
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eAOE, lTarget);
}

Non-functional Visual Effects

Jassper asked a question in the official forums about certain VFX constants not working. Cracking open the visualeffects.2da, it was discovered that a lot of the effects listed don't have .sef files associated with them.

From loudent2 :

It turns out a lot of the effects have been deprecated. It isn't immedietely apparant which ones (I had a similar problem using the tornado effect). Not sure if this is the problem in your case.

And from Ravine_HU:

I've read somewhere about this... coz the VFXs totally changed in nwn2 - everything is in the sef-files. U can check the visualeffects.2da for the list - find the row, and if there is no xy.sef references in it...unlucky.

I personally miss some nice effect from nwn1, like this raise dead for example. I can't even find that kind of effect which is only visible to the PC whom attached to (for example, no effect for blindness...).

However, the visual effect editor is cool.

Oh yeah, and check the "broken functions list" topic too, there are some issues with applying visualeffects.

More from Jassper

After looking in the 2da file for spells, NWN2 uses visual sp_conjuration_conjure.sef for raise dead. I copied that to the visualeffects.2da under the heading VFX_IMP_RAISE_DEAD and vola! I have an effect - altough it is not the NWN1 style raise dead.

So that indeed seems to be the issue - these effects simply wern't included, or haven't been replaced yet.

BTW, quesion about saveing changes in the 2da's. Will the new 2da be local to that mod only, or is it now a global change for all modules?

And finally, from mykael22000

Saved .2das get written out to your override directory - meaning they'll affect all of your games, but aren't stored inside the module you edited so if you send it to someone else, they won't have a copy...

Get the nwnhak utility from NWN1, create a new hak and move the .2da into it. Then park it in your Hak directory and tell the module to use it. It still won't be sent to anyone with the module, but at least it'll complain and tell them that they are missing it. it also won't stuff up all of your other games.

Switches

Here is x2_inc_switches in its entirety. It's a great reference to have when trying to set options on objects via "switch" variables.

The most commonly used is probably the creature section for setting ambient animations, etc.

//------------------------------------------------------------------------------
//   x2_inc_switches::   Interface for switching subsystem functionality
//------------------------------------------------------------------------------
/*
   This file provides a basic interface for switching different Hordes of
   the Underdark subsystems on/off  and allows centralized access to certain
   "expert"  functionality like overriding AI or Spellscripts.

   Changing any of these switches from their default position is considered
   unsupported and done at your own risk - please do NOT send any bug reports
   about problems caused by these switches.
*/
//------------------------------------------------------------------------------
// Copyright (c) 2003 Bioware Corp. * Created By: Georg Zoeller * On: 2003-07-16
//------------------------------------------------------------------------------
// ChazM (OEI) 10/20/05 - added MODULE_SWITCH_ENABLE_SEPERATE_ITEM_SCRIPTS, GetEventPostfix(),
//					modified GetUserDefinedItemEventScriptName()
// ChazM (OEI) 4/4/06 - added support for 32 character script names for item scripts.
// BMA-OEI 8/21/06 -- Moved campaign flags from kinc_globals.nss
// ChazM 8/25/06 - Shortened campaign variable names to fit in 32 char limit.


//void main(){}

//------------------------------------------------------------------------------
//									C A M P A I G N
//------------------------------------------------------------------------------

// These are stored as globals - note that global names can only be 32 chars long.
// Force kills dominated group members if no valid members remain - checked on HeartBeat ( nw_g0_dominate )
const string CAMPAIGN_SWITCH_FORCE_KILL_DOMINATED_GROUP = "N2_S_KILL_DOM_GROUP";

// Removes effect and prevents transition if object is dominated - checked on transition ( ginc_transition )
const string CAMPAIGN_SWITCH_REMOVE_DOMINATED_ON_TRANSITION = "N2_S_REMOVE_DOM_ON_TRAN";

// This global determines whether or not the campaign uses the personal reputation system, which affects
//	whether or not neutrals can be damaged by spells
const string CAMPAIGN_SWITCH_USE_PERSONAL_REPUTATION = "N2_S_USE_PERSONAL_REP";


//------------------------------------------------------------------------------
//                                    M O D U L E
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// * Force Use Magic Device Skillchecks, Default = FALSE except for GAME_DIFFICULTY_CORE_RULES+
// * If switched to TRUE, a rogue has to succeed in a UMD check against DC 25+SpellLevel
// * in order to use a scroll. See x2_pc_umdcheck.nss for details
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_UMD_SCROLLS    = "X2_SWITCH_ENABLE_UMD_SCROLLS";

//------------------------------------------------------------------------------
// * Toggle on/off the Item Creation Feats, Default = O
// * Disable the Item Creation Feats that come with Hordes of the Underdark for the
// * module.
//------------------------------------------------------------------------------
const string MODULE_SWITCH_DISABLE_ITEM_CREATION_FEATS    = "X2_SWITCH_DISABLE_ITEMCREATION_FEATS";

//------------------------------------------------------------------------------
// * Toggle Area of Effect Spell behaviour
// * If set to TRUE, AOE Spells will hurt NPCS that are neutral to the caster if they are
// * caught in the effect
//------------------------------------------------------------------------------
const string MODULE_SWITCH_AOE_HURT_NEUTRAL_NPCS = "X0_G_ALLOWSPELLSTOHURT";

//------------------------------------------------------------------------------
// * For balancing reasons the crafting system will create 50 charges on a new wand
// * instead it will create 10 + casterlevel charges. if you want to be "hard core rules compliant"
// * 50 charges, enable thiis switch
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_CRAFT_WAND_50_CHARGES    = "X2_SWITCH_ENABLE_50_WAND_CHARGES";

//------------------------------------------------------------------------------
// * Some epic spells, namely Hellball, do damage to the caster. We found this too confusing
// * in testing, so it was disabled. You can reactivate using this flag
//------------------------------------------------------------------------------
const string MODULE_SWITCH_EPIC_SPELLS_HURT_CASTER = "X2_SWITCH_EPIC_SPELLS_HURT_CASTER";

//------------------------------------------------------------------------------// * Deathless master touch is not supposed to affect creatures of size > large
// * but we do not check this condition by default to balance the fact that the slain
// * creature is not raised under the command of the pale master.
// * by setting this switch to TRUE, the ability will no longer effect creatures of
// * huge+ size.
//------------------------------------------------------------------------------
const string MODULE_SWITCH_SPELL_CORERULES_DMASTERTOUCH = "X2_SWITCH_SPELL_CORERULE_DMTOUCH";

//------------------------------------------------------------------------------
// * By default, all characters can use the various poisons that can be found to poison their weapons if
// * they win a Dex check. Activating this flag will restrict the use of poison to chars with the UsePoison
// * feat only
//------------------------------------------------------------------------------
const string MODULE_SWITCH_RESTRICT_USE_POISON_TO_FEAT = "X2_SWITCH_RESTRICT_USE_POISON_FEAT";

//------------------------------------------------------------------------------
// * Multiple Henchmen: By default, henchmen will never damage each other with AoE spells.
// * By activating this switch, henchmen will be able to damage each other with AoE spells
// * and potentially go on each other's throats.
// * Warning: Activating this switch has the potential of introducing game breaking bugs. Do
// *          not use on the official SoU campaign. Use at your own risk. Really, its dangerous!
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_MULTI_HENCH_AOE_DAMAGE = "X2_SWITCH_MULTI_HENCH_AOE_MADNESS";

//------------------------------------------------------------------------------
// * Spell Targeting: Pre Hordes of the underdark, in hardcore mode, creatures would not hurt each other
// * with their AOE spells if they were no PCs. Setting this switch to true, will activate the correct
// * behaviour. Activating this on older modules can break things, unless you know what you are doing!
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_NPC_AOE_HURT_ALLIES = "X2_SWITCH_ENABLE_NPC_AOE_HURT_ALLIES";

//------------------------------------------------------------------------------
// * If set to TRUE, the Bebilith Ruin Armor ability is going to actually destroy
// * the armor it hits. Would be very annoying for players...
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_BEBILITH_RUIN_ARMOR = "X2_SWITCH_BEBILITH_HARDCORE_RUIN_ARMOR";

//------------------------------------------------------------------------------
// * Setting this switch to TRUE will make the Glyph of warding symbol disappear after 6 seconds, but
// * the glyph will stay active....
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_INVISIBLE_GLYPH_OF_WARDING = "X2_SWITCH_GLYPH_OF_WARDING_INVISIBLE";

//------------------------------------------------------------------------------
// * Setting this switch to TRUE will enable the allow NPCs running between waypoints using the WalkWaypoints
// * function to cross areas, like they did in the original NWN. This was changed in 1.30 to use only
// * waypoints in one area.
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_CROSSAREA_WALKWAYPOINTS = "X2_SWITCH_CROSSAREA_WALKWAYPOINTS";

//------------------------------------------------------------------------------
// * Setting this switch to TRUE will disable the glow of a newly found secret door
// * used in some locations in XP2
//------------------------------------------------------------------------------
const string MODULE_SWITCH_DISABLE_SECRET_DOOR_FLASH = "X2_SWITCH_DISABLE_SECRET_DOOR_FLASH";

//------------------------------------------------------------------------------
// * Setting this switch to TRUE will disable execution of tagbased scripts that are enabled
// * by default when using the standard module events (x2_mod_def_*)
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS = "X2_SWITCH_ENABLE_TAGBASED_SCRIPTS";

//------------------------------------------------------------------------------
// * Only applies if MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS is true.
// This switch determines which type of tagbased scrtipting to use 
// (used in module events g_mod_*, x2_s3_hitcastspell, and x2_inc_spellhook)
// FALSE = use X2 version wherein all item events are in 1 script.  	
// TRUE = use seperated scripts named "i__<2 letter postfix>"
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_SEPERATE_ITEM_SCRIPTS = "NWN2_SEPERATE_ITEM_SCRIPTS";


//------------------------------------------------------------------------------
// * Setting thsi switch to TRUE will enable the XP2 Wandering Monster System
// * for this module (if you are using the default rest script and you have set
// * up the correct variables for each area
//------------------------------------------------------------------------------
const string MODULE_SWITCH_USE_XP2_RESTSYSTEM = "X2_SWITCH_ENABLE_XP2_RESTSYSTEM";

//------------------------------------------------------------------------------
// * if this variable is set, the AI will not use Dispel Magic against harmfull AOE
// * spells.
//------------------------------------------------------------------------------
const string MODULE_SWITCH_DISABLE_AI_DISPEL_AOE = "X2_L_AI_NO_AOE_DISPEL";

//------------------------------------------------------------------------------
// * Setting this variable to TRUE on the module will disable the call to the
// * random loot generation in most creatures' OnSpawn script.
//------------------------------------------------------------------------------
const string MODULE_SWITCH_NO_RANDOM_MONSTER_LOOT = "X2_L_NOTREASURE";

//------------------------------------------------------------------------------
//                             M I S C
//------------------------------------------------------------------------------
const string MODULE_VAR_OVERRIDE_SPELLSCRIPT ="X2_S_UD_SPELLSCRIPT";

const string MODULE_VAR_TAGBASED_SCRIPT_PREFIX ="X2_S_UD_SPELLSCRIPT";

//------------------------------------------------------------------------------
// * Variable that holds the wandering monster 2da filename
//------------------------------------------------------------------------------
const string MODULE_VAR_WANDERING_MONSTER_2DA ="X2_WM_2DA_NAME";

//------------------------------------------------------------------------------
// * This variable allows to specify a % for NOT using dispel magic against AOEs
// instead fleeing
//------------------------------------------------------------------------------
const string MODULE_VAR_AI_NO_DISPEL_AOE_CHANCE = "X2_L_AI_AOE_DISPEL_CHANCE";

//------------------------------------------------------------------------------
// * Setting this variable to TRUE will cause the Combat Expertise/Improved Combat Expertise
// * modes to be disabled whenever a player is casting a spell.
//------------------------------------------------------------------------------
const string MODULE_VAR_AI_STOP_EXPERTISE_ABUSE = "X2_L_STOP_EXPERTISE_ABUSE";


//------------------------------------------------------------------------------
//                             C R E A T U R E S
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// * see x2_ai_demo for details
//------------------------------------------------------------------------------
const string CREATURE_VAR_CUSTOM_AISCRIPT = "X2_SPECIAL_COMBAT_AI_SCRIPT";

//------------------------------------------------------------------------------
// * Setting this variable on a spellcaster creature will make its spelluse a
// * bit more random, but their spell selection may not always be appropriate
// * to the situation anymore.
//------------------------------------------------------------------------------
const string CREATURE_VAR_RANDOMIZE_SPELLUSE = "X2_SPELL_RANDOM";

//------------------------------------------------------------------------------
// * Set to 1 to make the creature activate stealth mode after spawn
//------------------------------------------------------------------------------
const string CREATURE_VAR_USE_SPAWN_STEALTH = "X2_L_SPAWN_USE_STEALTH";

//------------------------------------------------------------------------------
// * Set to 1 to make the creature activate detectmode after spawn
//------------------------------------------------------------------------------
const string CREATURE_VAR_USE_SPAWN_SEARCH = "X2_L_SPAWN_USE_SEARCH";

//------------------------------------------------------------------------------
// * Set to 1 to make the creature play mobile ambient animations after spawn
//------------------------------------------------------------------------------
const string CREATURE_VAR_USE_SPAWN_AMBIENT = "X2_L_SPAWN_USE_AMBIENT";

//------------------------------------------------------------------------------
// * Set to 1 to make the creature play immobile ambient animations after spawn
//------------------------------------------------------------------------------
const string CREATURE_VAR_USE_SPAWN_AMBIENT_IMMOBILE = "X2_L_SPAWN_USE_AMBIENT_IMMOBILE";

//------------------------------------------------------------------------------
// * Set to 1 to make the creature immune to dispel magic (used for statues)
//------------------------------------------------------------------------------
const string CREATURE_VAR_IMMUNE_TO_DISPEL = "X1_L_IMMUNE_TO_DISPEL";

//------------------------------------------------------------------------------
// * Set this variable to 1 on a creature to make it walk through other creatures
//------------------------------------------------------------------------------
const string CREATURE_VAR_IS_INCORPOREAL = "X2_L_IS_INCORPOREAL";

//------------------------------------------------------------------------------
// * Set this variable to 1 - 6 to override the number of attacks a creature has based on its BAB
//------------------------------------------------------------------------------
const string CREATURE_VAR_NUMBER_OF_ATTACKS = "X2_L_NUMBER_OF_ATTACKS";

//------------------------------------------------------------------------------
// * The value of this variable (int) is added to the chance that a creature
// * will use magic in combat. Set to 100 for always, 0 for never
//------------------------------------------------------------------------------
const string CREATURE_AI_MODIFIED_MAGIC_RATE = "X2_L_BEH_MAGIC";

//------------------------------------------------------------------------------
// * The higher value of this variable, the higher the chance that the creature
// * will use offensive abilities in combat. Set to 0 to make them flee.
//------------------------------------------------------------------------------
const string CREATURE_AI_MODIFIED_OFFENSE_RATE = "X2_L_BEH_OFFENSE";

//------------------------------------------------------------------------------
// * The higher value of this variable, the higher the chance that the creature
// * will aid friendly creatures in combat. Not that helping usually degrades
// * the overall difficulty of an encounter, but makes it more interesting.
//------------------------------------------------------------------------------
const string CREATURE_AI_MODIFIED_COMPASSION_RATE = "X2_L_BEH_COMPASSION";

//------------------------------------------------------------------------------
// * This allows you to script items that enhance a palemaster's summoned creatures. You need
// * to put the name of a script into this variable that will be run on any creature called by
// * the pale master's summon undead ability. You can use this script to add effects to the creature.
// * You can use the OnEquip/OnUnEquip event hooks set this variable.
//------------------------------------------------------------------------------
const string CREATURE_VAR_PALE_MASTER_SPECIAL_ITEM = "X2_S_PM_SPECIAL_ITEM";


//------------------------------------------------------------------------------
// These constants define item messages that are routed to script files with
// the item tag's through the default XP2 module scripts.
//------------------------------------------------------------------------------
const int X2_ITEM_EVENT_ACTIVATE 		= 0;
const int X2_ITEM_EVENT_EQUIP 			= 1;
const int X2_ITEM_EVENT_UNEQUIP 		= 2;
const int X2_ITEM_EVENT_ONHITCAST 		= 3;
const int X2_ITEM_EVENT_ACQUIRE 		= 4;
const int X2_ITEM_EVENT_UNACQUIRE 		= 5;
const int X2_ITEM_EVENT_SPELLCAST_AT 	= 6;

const int X2_EXECUTE_SCRIPT_CONTINUE 	=0;
const int X2_EXECUTE_SCRIPT_END 		=1;

const int SCRIPT_MAX_STRING_LENGTH 		= 32;
const int SCRIPT_ITEM_EXTENSION_LENGTH 	= 3;

const string SCRIPT_EXTENSION_ITEM_EVENT_ONHITCAST 		= "_hc";
const string SCRIPT_EXTENSION_ITEM_EVENT_ACTIVATE		= "_ac";
const string SCRIPT_EXTENSION_ITEM_EVENT_EQUIP 			= "_eq";
const string SCRIPT_EXTENSION_ITEM_EVENT_UNEQUIP		= "_ue";
const string SCRIPT_EXTENSION_ITEM_EVENT_ACQUIRE		= "_aq";
const string SCRIPT_EXTENSION_ITEM_EVENT_UNACQUIRE		= "_ua";
const string SCRIPT_EXTENSION_ITEM_EVENT_SPELLCAST_AT 	= "_ci";
	
// Set the active User Defined Item Event
// X2_ITEM_EVENT_ACTIVATE
// X2_ITEM_EVENT_EQUIP
// X2_ITEM_EVENT_UNEQUIP
// X2_ITEM_EVENT_ONHITCAST
// X2_ITEM_EVENT_ACQUIRE
// X2_ITEM_EVENT_UNACQUIRE
// X2_ITEM_EVENT_SPELLCAST_AT
void SetUserDefinedItemEventNumber(int nEvent);

// Get the active User Defined Item Event
// X2_ITEM_EVENT_ACTIVATE
// X2_ITEM_EVENT_EQUIP
// X2_ITEM_EVENT_UNEQUIP
// X2_ITEM_EVENT_ONHITCAST
// X2_ITEM_EVENT_ACQUIRE
// X2_ITEM_EVENT_UNACQUIRE
// X2_ITEM_EVENT_SPELLCAST_AT
int GetUserDefinedItemEventNumber();

//------------------------------------------------------------------------------
// * Used to switch between different rule implementations or to subsystems for the game
// * see x2_inc_switches for more detailed information on these constants
//------------------------------------------------------------------------------
void SetModuleSwitch(string sModuleSwitchConstant,int bValue);

//------------------------------------------------------------------------------
// * Returns the value of a module switch
//------------------------------------------------------------------------------
int GetModuleSwitchValue(string  sModuleSwitchConstant);

//------------------------------------------------------------------------------
//                                D O O R S
//------------------------------------------------------------------------------
const string DOOR_FLAG_RESIST_KNOCK = "X2_FLAG_DOOR_RESIST_KNOCK";

//------------------------------------------------------------------------------
// * Used to toggle custom flags on a door
// * oDoor - Door to set the switch on
// * Valid values for sDoorFlagConstant:
// * X2_FLAG_DOOR_RESIST_KNOCK -
// *        Set to 1 to prevent knock from working with feedback.
// *        Set to 2 to prevent knock from working without feedback
//------------------------------------------------------------------------------
void SetDoorFlag(object oDoor, string sDoorFlagConstant, int nValue);
int GetDoorFlag(object oDoor, string  sDoorFlagConstant);

//------------------------------------------------------------------------------
//                           W A Y P O I N T S
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// * By setting this variable to 1 on a waypoint, a creature using this
// * waypoint as part of its WalkWaypoints routine will assume the facing
// * of the waypoint upon reaching it.
//------------------------------------------------------------------------------
const string  WAYPOINT_VAR_FORCE_SETFACING = "X2_L_WAYPOINT_SETFACING";

//------------------------------------------------------------------------------
//                           I T E M S
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// NOTE: THIS NO LONGER WORKS. TO PREVENT MODIFICATION USE THE PLOT FLAG
//------------------------------------------------------------------------------
const string ITEM_FLAG_NO_CRAFT_MODIFICATION = "X2_FLAG_ITEM_CRAFT_DO_NOT_MODIFY";
void SetItemFlag(object oItem, string sItemFlagConstant, int nValue);
int GetItemFlag(object oItem, string  sItemFlagConstant);

//------------------------------------------------------------------------------
// * Execute sScript on oTarget returning an integer.
// * Do not nest this function
//------------------------------------------------------------------------------
int ExecuteScriptAndReturnInt(string sScript, object oTarget);

//------------------------------------------------------------------------------
// * Sets the return value for scripts called via ExecuteScriptAndReturnInt
// * valid values are
// * X2_EXECUTE_SCRIPT_CONTINUE - continue calling script after executed scriptis done
// * X2_EXECUTE_SCRIPT_END - end calling script after executed script is done
//------------------------------------------------------------------------------
void  SetExecutedScriptReturnValue(int nValue = X2_EXECUTE_SCRIPT_END);

//------------------------------------------------------------------------------
// * This is a security feature. If you are running a *local vault* server and you
// * have tag based script execution enabled, people could bring items into your
// * game that execute existing scripts. You can set a script prefix here to
// * prevent that. Note that you have to add this prefix to your item scripts in
// * the module to make them work.
//------------------------------------------------------------------------------
void SetUserDefinedItemEventPrefix(string sPrefix="");

//------------------------------------------------------------------------------
//                          S P E L L S C R I P T S
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Allows the module creator to specify a script that will be run before any spellscript is run
// You can call SetModuleOverrideSpellscript() at the end of the script specified by
// sScriptName. If you call this function this will prevent the original spellscript
// (and all craft item code) from being executed.
// If you do not add this line, the original spellscript and/or crafting code will
// run in addition to your script
//------------------------------------------------------------------------------
void SetModuleOverrideSpellscript(string sScriptName);

//------------------------------------------------------------------------------
//                             C R E A T U R E S
//------------------------------------------------------------------------------

void SetCreatureFlag(object oCreature, string sFlag, int nValue);
int  GetCreatureFlag(object oCreature, string sFlag);

//------------------------------------------------------------------------------
// * Define a replacement script for DetermineCombatRound
// * See x2_ai_demo for details
//------------------------------------------------------------------------------
void SetCreatureOverrideAIScript(object oCreature, string sScriptName);

//------------------------------------------------------------------------------
// * Call this at end of your custom override AI script set via CREATURE_VAR_CUSTOM_AISCRIPT
// * See x2_ai_demo for details.
//------------------------------------------------------------------------------
void   SetCreatureOverrideAIScriptFinished(object oCreature = OBJECT_SELF);
void   ClearCreatureOverrideAIScriptTarget(object oCreature = OBJECT_SELF);
object GetCreatureOverrideAIScriptTarget(object oCreature = OBJECT_SELF);

//------------------------------------------------------------------------------
// * Define the name of the 2da file which is used for the wandering monster
// * system
//------------------------------------------------------------------------------
void SetWanderingMonster2DAFile(string s2DAName = "des_restsystem");



//----------------------------------------------------------------------------
// Interface to switch on / off specific  subsystems or behaviors
// Check X2_INC_SWITCHES.NSS for details
//----------------------------------------------------------------------------
void SetModuleSwitch(string sModuleSwitchConstant,int bValue)
{
    if (bValue == 0)
    {
        DeleteLocalInt (GetModule(),sModuleSwitchConstant);
        return;
    } else if ((sModuleSwitchConstant) == MODULE_SWITCH_AOE_HURT_NEUTRAL_NPCS && bValue == TRUE)
    {
      bValue = 10;
    }
    SetLocalInt (GetModule(),sModuleSwitchConstant, bValue);
}

//----------------------------------------------------------------------------
// Return the value of a module switch set by SetModuleSwitch
// See X2_INC_SWITCHES for a list of all module switches
//----------------------------------------------------------------------------
int GetModuleSwitchValue(string  sModuleSwitchConstant)
{
    int nRet =  GetLocalInt (GetModule(),sModuleSwitchConstant);
    return nRet;
}

void SetDoorFlag(object oDoor, string sDoorFlagConstant, int nValue)
{
    if (nValue == 0)
    {
        DeleteLocalInt (oDoor,sDoorFlagConstant);
        return;
    }
    SetLocalInt (oDoor,sDoorFlagConstant, nValue);
}

int GetDoorFlag(object oDoor, string  sDoorFlagConstant)
{
    int nRet =  GetLocalInt (oDoor,sDoorFlagConstant);
    return nRet;
}

void SetItemFlag(object oItem, string sItemFlagConstant, int nValue)
{
    if (nValue == 0)
    {
        DeleteLocalInt (oItem,sItemFlagConstant);
        return;
    }
    SetLocalInt (oItem,sItemFlagConstant, nValue);
}

int GetItemFlag(object oItem, string  sItemFlagConstant)
{
    int nRet =  GetLocalInt (oItem,sItemFlagConstant);
    return nRet;
}

void SetModuleOverrideSpellscript(string sScriptName)
{
    SetLocalString(GetModule(),MODULE_VAR_OVERRIDE_SPELLSCRIPT,sScriptName);
}

string GetModuleOverrideSpellscript()
{
     string  sScript = GetLocalString(GetModule(),"X2_S_UD_SPELLSCRIPT");
     return sScript;
}

//------------------------------------------------------------------------------
// You can call this in our overridden spellscript. If you call this
// this will prevent the original spellscript (and all craft item code)
// from being executed. If you do not add this line, the original spellscript
// and/or crafting code will run in addition to your script
//------------------------------------------------------------------------------
void SetModuleOverrideSpellScriptFinished()
{
    SetLocalInt(OBJECT_SELF,"X2_L_BLOCK_LAST_SPELL",TRUE);
}

int GetModuleOverrideSpellScriptFinished()
{
    int nRet = GetLocalInt(OBJECT_SELF,"X2_L_BLOCK_LAST_SPELL");
    DeleteLocalInt(OBJECT_SELF,"X2_L_BLOCK_LAST_SPELL");
    return nRet;
}

void SetCreatureOverrideAIScript(object oCreature, string sScriptName)
{
    SetLocalString(oCreature,CREATURE_VAR_CUSTOM_AISCRIPT,sScriptName);
}

void SetCreatureOverrideAIScriptFinished(object oCreature = OBJECT_SELF)
{
 //   WriteTimestampedLogEntry("Custom AI Finished");
    SetLocalInt(oCreature,"X2_SPECIAL_COMBAT_AI_SCRIPT_OK",TRUE);
}

object GetCreatureOverrideAIScriptTarget(object oCreature = OBJECT_SELF)
{
    object oRet= GetLocalObject(oCreature,"X2_NW_I0_GENERIC_INTRUDER");
    return oRet;
}

void ClearCreatureOverrideAIScriptTarget(object oCreature = OBJECT_SELF)
{
    DeleteLocalObject(oCreature,"X2_NW_I0_GENERIC_INTRUDER");
}

void SetCreatureFlag(object oCreature, string sFlag, int nValue)
{
    if (sFlag == CREATURE_VAR_IMMUNE_TO_DISPEL)
    {
        if (nValue != 0)
        {
            nValue = 10;
        }
    }

    SetLocalInt(oCreature,sFlag ,nValue);
}

int GetCreatureFlag(object oCreature, string sFlag)
{
    int nRet = GetLocalInt(oCreature,sFlag);
    return nRet;
}

//----------------------------------------------------------------------------
// Get the current UserDefined Item Event Number
// X2_ITEM_EVENT_ACTIVATE
// X2_ITEM_EVENT_EQUIP
// X2_ITEM_EVENT_UNEQUIP
// X2_ITEM_EVENT_ONHITCAST
// X2_ITEM_EVENT_ACQUIRE
// X2_ITEM_EVENT_UNACQUIRE
// X2_ITEM_EVENT_SPELLCAST_AT
//----------------------------------------------------------------------------
int GetUserDefinedItemEventNumber()
{
    return GetLocalInt(OBJECT_SELF, "X2_L_LAST_ITEM_EVENT");
}

//----------------------------------------------------------------------------
// Set the current UserDefined Item Event Number
// X2_ITEM_EVENT_ACTIVATE
// X2_ITEM_EVENT_EQUIP
// X2_ITEM_EVENT_UNEQUIP
// X2_ITEM_EVENT_ONHITCAST
// X2_ITEM_EVENT_ACQUIRE
// X2_ITEM_EVENT_UNACQUIRE
// X2_ITEM_EVENT_SPELLCAST_AT
//----------------------------------------------------------------------------
void SetUserDefinedItemEventNumber(int nEvent)
{
    SetLocalInt(OBJECT_SELF,"X2_L_LAST_ITEM_EVENT",nEvent);
}
	
		
string GetEventPostfix()
{
	string sPostfix = "";
	int nEvent = GetUserDefinedItemEventNumber();

	switch (nEvent)
	{
		case X2_ITEM_EVENT_ONHITCAST:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_ONHITCAST;
			break;
		case X2_ITEM_EVENT_ACTIVATE:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_ACTIVATE;
			break;
		case X2_ITEM_EVENT_EQUIP:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_EQUIP;
			break;
		case X2_ITEM_EVENT_UNEQUIP:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_UNEQUIP;
			break;
		case X2_ITEM_EVENT_ACQUIRE:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_ACQUIRE;
			break;
		case X2_ITEM_EVENT_UNACQUIRE:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_UNACQUIRE;
			break;
		case X2_ITEM_EVENT_SPELLCAST_AT:
			sPostfix = SCRIPT_EXTENSION_ITEM_EVENT_SPELLCAST_AT;
			break;
	}
	return (sPostfix);
}

//----------------------------------------------------------------------------
// Returns the name for the User Defined Item Event script for oItem,
// including possible prefixes configured by SetUserDefinedItemEventPrefix
//----------------------------------------------------------------------------
string GetUserDefinedItemEventScriptName(object oItem)
{
    string sPrefix = GetLocalString(GetModule(), MODULE_VAR_TAGBASED_SCRIPT_PREFIX);
	string sTag = sPrefix + GetTag(oItem);
	int iMaxPreExtensionLength = SCRIPT_MAX_STRING_LENGTH - SCRIPT_ITEM_EXTENSION_LENGTH;

	if (GetLocalInt(GetModule(), MODULE_SWITCH_ENABLE_SEPERATE_ITEM_SCRIPTS))
	{
	    if (GetStringLength(sTag) > iMaxPreExtensionLength)
		{
	        sTag = GetStringLeft(sTag, iMaxPreExtensionLength);
		}
	 	sTag = sTag + GetEventPostfix();
	}
    return sTag;
}


//----------------------------------------------------------------------------
// You can define a prefix for any User Defined Item Event here, to prevent
// people from executing scripts you do not like them to execute on your
// local vault server
//----------------------------------------------------------------------------
void SetUserDefinedItemEventPrefix(string sPrefix="")
{
    SetLocalString(GetModule(), MODULE_VAR_TAGBASED_SCRIPT_PREFIX, sPrefix);
}

//----------------------------------------------------------------------------
// Wrapper for Execute Script to execute a script and get an integer
// return value. Do not nest this function!
//----------------------------------------------------------------------------
int ExecuteScriptAndReturnInt(string sScript, object oTarget)
{
    DeleteLocalInt(oTarget,"X2_L_LAST_RETVAR");
    ExecuteScript(sScript,oTarget);
    int nRet = GetLocalInt(oTarget,"X2_L_LAST_RETVAR");
    DeleteLocalInt(oTarget,"X2_L_LAST_RETVAR");
    return nRet;
}

//----------------------------------------------------------------------------
// Helper function for ExecuteScriptAndReturnInt
//----------------------------------------------------------------------------
void  SetExecutedScriptReturnValue(int nValue = X2_EXECUTE_SCRIPT_CONTINUE)
{
    SetLocalInt(OBJECT_SELF,"X2_L_LAST_RETVAR",nValue);
}

//----------------------------------------------------------------------------
// Define the name of the 2da file which is used for the wandering monster
// system
//----------------------------------------------------------------------------
void SetWanderingMonster2DAFile(string s2DAName = "des_restsystem")
{
    SetLocalString(OBJECT_SELF,MODULE_VAR_WANDERING_MONSTER_2DA,s2DAName);
}

Campaigns

The OC uses a campaign system where there is a central umbrella that connects all the different parts (modules). It would seem that this is a great tool for builders who want to publish a series of modules. So far that has not been a lot of talk about this (I think a lot of people are still getting used to the Toolset), but I think it will become more important as time passes. Here's a thread on the official forum talking about campaigns: http://nwn2forums.bioware.com/forums/viewtopic.html?topic=527622&forum=113

A success story with some suggestions from Quoll.

My campaign is working smoothly. I also had a hitch getting it to load at first, and it was all simply a naming issue. Make sure your campaign start module is named the same as a real module in your campaign... then I think it was either adding the ".mod" or removing it. I'd check for sure but I'm not near my editor, but if what you have doesn't work, try the other way.

On the campaign vs module resources, so far it seems to me to simply be a cool way to manage resources. If you know you only use scripts, characters, etc for a short time, only load them for that period, then never again. Those would be the module resources. If you have a companion or scripts you use all the time, make them campaign based. It's sort of a global vs local concept (but only sort of).

I've set a personal rule of thumb to never make one of my areas bigger than any of the official campaign modules. That seems the smartest route unless you want to do a lot of testing.

Another benefit of campaigns that nobody seems to realize yet is how well it fits into group workflow! Several people can all be working on different "modules" at the same time, then just import the updates to a master campaign. Pretty cool.

Good luck all!

And more from flem1

Actually, here's a cool thing: campaign resources, AFAIK, aren't stored in savegames. So for a SP mod you could upload anything that might be changed in an "expansion" (i.e. adding another mod to the campaign) as a campaign dialog/script/whatnot, and then allow players to pick off right where their final save from the last mod left off, including revisiting old areas for new content as well as remembering what happened...

And from Max Gamer

There's only one way I managed to solve the unpacking module hang when starting a new campaign:

1) Close down your starting module in the toolset. For some odd reason the toolset is fussy about having it open when making it the starting module.

2) Make a new campaign in the campaign editor and type in the starter module name to be exactly the same as the filename without the .mod extension.

3) Hit the save campaign button.

4) Lastly add your starter module to the list of modules the campaign will use. This last step may not be essential to get the starter mod loading but will definitely be needed later on.

Step-by-step guide to creating a campaign

NWN2 uses a campaign system where there is a central umbrella that can connect a group of modules. It would seem that this is a great tool for builders who want to publish a series of modules.

This assumed you have a module that you are working on. I'm going to do this with my SKS series, so SKS01 will be my starting module.

  1. Open the Toolset without loading a module. Apparently there is an issue with having your starting module open while you do this.
  2. Click on "Plugins" > "Campaign Editor" to open the CampaignEditorForm
  3. Click "Add Campaign" in the upper right hand corner.
  4. You should see a new entry appear called "New Campaign." Click on this and the properties window will fill in with our blank campaign.
  5. Edit the fields in the properties window, giving your campaign a name, description and display name. Feel free to go through the other options to see how they work. Remember that you can also come back and edit your campaign options, so for now let's move on once you have the basic "Appearance" information.
  6. In the section below the properties window, click the "Add Files" button and choose your starting module.
  7. This part I'm not too sure about: click on the module you just added and click the "Set Module to use Selected Campaign" button. I missed this part and had to go back and forth a few times in order to get the campaign options to light up in the Toolset. As a result, I can't say for certain if it is the selected module that you are setting to use the campaign, or the currently open menu. If someone could comment on that point, it would be much appreciated.
  8. Finally, choose "Save Campaign," again in the upper right hand corner. Now you can close dialog window.
  9. Open your module that you added above and test to see if it is using the campaign by right clicking on a blueprint and making sure that "Copy Blueprint" > "Campaign" is a working option. If not, see the point above.
  10. Once you get it working, save your module. You should now have a module file in your My Document's modules folder and a campaign in your My Document's Campaign folder. Start up the Toolset and try to launch your new campaign via the New Game > Campaign choices.

Thanks to all who contributed to this thread in the official forums, which is where I learned how to do this. I've pulled some great excerpts in the page above this.

Naming Conventions

The Official Campaign uses the following conventions in regards to keeping track of modules and areas across the whole campaign. All of this seems to allow a convenient way of tracking where things are in the campaign.

Modules

Each module has a number in the tens of hundreds, followed by an underscore and the name of the module (eg. "1300_Old_Owl_Well.mod").

Areas

Each area in that module has a number within that hundred, followed by a short name of the area (eg. "1302_oldowlwell").

The display name for the area has the area id number in curly brackets preceding it (eg. "{1302}Old Owl Well").

The tag of the area seems to vary between the display name without the number and without spaces, but still capitalized (eg. "OldOwlWell") or the area id with the name (eg. "1304Bonegnasher"). Best practice for module builders would seem to be to always include the area id in the tag.

Scripts

Scripts specifically attached to this area, and this area only, are in the form of the area id and the script type (eg. "1302_enter").

Waypoints

Waypoints seem to use the area id as well. For instance, the initial entrance to the area 1304Bonegnasher is a waypoint with the tag "1304_enter." Note that this is the localized name for the waypoint, as well, which allows for easy reference.

Doors

Doors with transitions can also follow this convention in the form of:
plc_dr_ < id of the current area > _to_ < id of the target area >

For example, if you were setting up a transition between areas 1304 and 1305, they could be tagged as "plc_dr_1304_to_1305" and "plc_dr_1305_to_1304". Unlike waypoints, doors display their localized names to the players. This means that you will want to wrap your localized names in curly brackets.

Versioning control in a campaign

Note: There's a version control option under the Options menu, but at this time I don't know how one would hook into it. This is a poor man's solution that is easy to use.

I like to save multiple version of my modules just in case something happens. It's also nice to be able to test out something crazy, and roll it back to a previous version if you have to.

A simple way to do this with modules in a campaign is choose the "Save As" option, but I'm always afraid I'm going to continue working on a saved version instead of the one in the campaign. Nothing is worse than testing your module than suddenly realizing you've just wasted 20 minutes in the wrong version. A better way I've found is to simply copy the module and change the name. This allows your named (without version numbers) module to be the latest and greatest that shows up in your campaign.

As an example, I use a system where the first number is the release status, and the second number is the version. The release status is "0" for development and "1" for released. If I need to make large changes, I increment it from there, so if I were to totally redo something I'd change it to a "2." So my first module is the name of the module + "_0_001" and every time I increment it I increase that last number by 1. The first released version is "_1_001." As I fix bugs and update for patches, I continue to increment the last number.

Usually, for me a version is a day's of work or a major change that I don't want to screw up. As I progress with more and more versions, I usually burn them off to a disk... or just delete them. ;)

Use whatever system you want, but some sort of version control is a great idea. So is backing up your files.

Factions

A good place to start learning about factions is the faction section of the lexicon:

http://www.nwnlexicon.com/compiled/categoryfunction.reputationfaction.html

Factions are controlled in the Factions window. To view this page in NWN2 go to View > Factions. Here you will see a table showing how factions feel about each other.

Each row shows how the faction listed to the left feels about the faction in each column. To adjust how a faction feels about each faction, change the values in a row. 

Note that there is no Player row. This is because the Player faction cannot have feelings one way or another for other factions. Note also that, by default, all factions except for hostile are 100% friendly to Players. This is a change from NWN1 defaults.

Faction is measured on a scale from 0 to 100. Anything 10 or lower means the creatures of a faction are hostile to the creatures in the target faction. Anything 90 or above means the creatures of a faction are friendly to the creatures of the target faction.

Hostile creatures attack on sight. Friendly creatures can share buffs (such as bless and other area of effect spells), and will usually not be affected by area of effect attacks (such as fireballs). Note that area of affect damage will be determined by server and campaign settings.

You can check to see how one faction feels about another using GetReputation():

int GetReputation(
object oSource,
object oTarget
);

 

Adjusting Factions in the game

You can dynamically adjust how one faction feels about another using the following functions.

AdjustFactionReputation Adjusts all factions members reputation in relation to another faction.
AdjustReputation Adjusts positively or negatively how a whole faction views a specific person.
AdjustReputationWithFaction Adjusts reputation of each member in PC's party with NPC's faction

From the lexicon page on Adjust Reputation:

One method of maximizing the versatility of the AdjustReputation function in conjunction with custom factions is to create an inaccesible area devoted to holding custom faction holders. Let's say your custom faction is titled "CLO" . You would give a creature the tag "CustomFactionHolderCLO", set "CLO" as the faction on the creature and place it in the custom faction holder bed. Keep it isolated from all other custom faction holders. Do not check the "plot" flag on your creature (or this won't work). You are using a creature rather than a placeable because AdjustReputation does not work with placeables. Now, for example, if you want the entire custom faction to turn hostile against your PC, you would script:

AdjustReputation(PC, GetObjectByTag("CustomFactionHolderCLO"), -100)

You can even create a custom faction holder for a standard faction so that you can easily use AdjustReputation with that standard faction.

Also, you may want to read this thread:

http://nwn2forums.bioware.com/forums/viewtopic.html?topic=569037&forum=114

In it, they are talking about the need to set UsesPersonalReactions to TRUE in the campaign settings. This requires you to use a campaign folder if you want to do any serious work with factions.

Creating new factions

Create new a new faction by first going to View > Factions and openin the factions page.

  1. Click the Add Faction button at the top of the page.
  2. Give the faction a name in the property panel that should have just appeared in the lower-left-hand corner.
  3. Note that new factions are not global by default.
  4. Set how your new faction feels about other factions. TIP: click on a row that best matches the values you want, copy the row, and paste that values onto your new row to save time. This also works with columns.
  5. Assign creatures to your new faction by finding the faction field under the Basics heading in the properties tab. Click on the field to get a drop down and you should see you new faction.

Global factions

One of the things that trip new builders up when dealing with factions is the "global" setting. If a faction is global, any faction adjustments for a creature will affect the entire faction.

So if you make a commoner go hostile, all creatures in the Commoner faction will go hostile across the whole module. Most builders find this annoying and most players are confused when this happens. The first response is that the module is broken.

Thanks to Parat for this post about factions in the Toolset forums, where he pointed out that the four standard factions cannot be changed from being global. This is a change from NWN1.

His solution is to "switch all commoners to a new commoner faction, which is not global, as it seems that you cannot deactivate the global setting for the existing factions?

While this may be a pain, it gives you more options for dealing with factions in general. It is obviously best to consider this at the start of developing your module.

Note that this will only affect you if you've scripted faction changes or if your pvp settings are set to allow players to hurt or otherwise anger Commoners, Defenders and Merchants.

Also, you may want to read this thread:

http://nwn2forums.bioware.com/forums/viewtopic.html?topic=569037&forum=114

In it, they are talking about the need to set UsePersonalReactions to TRUE in the campaign settings. This requires you to use a campaign folder if you want to do any serious work with factions.

Using Personal Reputations

There is an issue where SetIsTemporaryEnemy and AdjustReputation don't work unless the campaign-level variable UsesPersonalReputations is set to TRUE. Follow these steps to make these work:

Quote: by TanisGorion
ok i found how it works, i must

1-open campaign editor
2-create a new campagin
3-insert the new module created
3-put personal reputation on TRUE
4-click save campaign
5-Click on use this campaign on the module selected.
6-close and reopen the module.

Also note that you probably want to create custom factions, because the four static factions cannot act as non-global factions.

See more about both of these issues here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=569037&forum=114

 

Testing

Here you will find some useful information regarding testing.

Here's a general thread discussing some good ways to make testing and debuging easier in a large module:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=572072&forum=113

The debugger, debug messages, debug creatures with conversations set up to help you test and the console are just a few of the tools you have at your disposal. 

So far this section mainly deals with scripting. See the links below:

Debugging

Getting the debug messages to print to the log or the screen can really help when trying to track down a problem in your module. Following up on some leads from jackyo123 and a few frustrating google searches, here's how I got it to work:

1. Set the Toolset to compile with Debugging

I'm not entirely sure this is needed or how this affects module, but it's also useful for using the ScriptDebuggerServer, so I have it on.

  • Go to view > options
  • Click on the script link
  • Set GenerateDebugInformation to TRUE

2. Edit nwnplayer.ini

This one took me a while to find, partly because the documentation for DebugPostString() says you need to edit nwn.ini instead of nwnplayer.ini.

  • Open nwnplayer.ini with notepad. Most people will find it at C:\Documents and Settings\Sean\My Documents\Neverwinter Nights 2\nwnplayer.ini
  • Near the bottom of the file, under [Server Options], find the two lines that say "Scripts Print To Log=0" and "Scripts Print To Screen=0". Change these both of these values to "1" to get messages to print out to both the log and the screen. Change only one if you like.

3. Add PrettyDegug messages

Add your PrettyDebug messages where you want them. You'll notice that you'll get a lot of messages from the regular scripts, as well. These are great when you trying to figure out why the script that seems to be saying it should do something, isn't doing what you want.

4. Turn the Debug Messages On

You can do this in the game or you can do this via the ini file.

In game:

  • Press the "`" (teldah) key to get to the console.
  • Type "DebugMode 1"
  • Type "debugtext"
  • Press the "`" key again to return to the game.

In the nwnplayer.ini:

  • Open C:\Documents and Settings\Sean\My Documents\Neverwinter Nights 2\nwnplayer.ini with notepad.
  • Under[Game Options] add "Debug Text=1"
  • Note that you can always override this in the game.

If you are sending debug information to your logs, they will appear at:

C:\Documents and Settings\Sean\Local Settings\Temp\NWN2\LOGS\nwclientLog1.txt

If you are sending debug information to the screen, they will appear up by the mini-map.

The logscriptrun command

Thanks to jackyo123 for pointing this out. If you type in "logscriptrun" in the console while in debug mode, your log will fill up with all the scripts that are being called. It can be a bit much to wade through, but sometimes it's good to see if something was run.

Using the ScriptDebugger

The debug server is a way to walk through your scipts step by step. It creates a debug window that let's you see the path your script is taking, and is useful for figuring out why something is happening, or how something works. In programming, this is similar to breakpoints. Here's how I got it set up:

  1. In the Toolset, go to View > Options. In the options window, go to the Script page and change the "Generate debug information" field to TRUE. If you don't do this, the debugger has nothing to work with and will stop immediately after it starts.
  2. In the script you want to debug, add the line SpawnScriptDebugger();
  3. Optionally, compile all scripts in module, just in case.
  4. Go to the utilities folder inside your NWN2 program directory. This is C:\Program Files\Atari\Neverwinter Nights 2\Utils by default. Find the program DebugServer.exe and launch it.
  5. If you are running Windows XP, the firewall will ask you to unblock this program. Click unblock and you will see the small window.
  6. Now launch NWN2 and go to the options menu in the game.
  7. Find the "Full Screen" checkbox (it's small and at the top of a list of other options), and uncheck it. You need to do this in order to see the debug window. Failure to do so could leave you stuck, while the debug windows waits for you to tell it to continue executing the script.
  8. Now with both windows next to each other, run your module.

When it gets to where you placed the SpawnScriptDebugger(), the game will freeze and wait for you to tell the debugger to continue. Keep clicking "Step Into" until you have finished the script. At this point play will continue as normal.

There are some other options in the debug window that I didn't play with, so experiment.

GameFAQs: Debug Commands

Gamespot and GameFAQs posted some additional information on Debug Commands in their Cheats section.
Debug Mode Codes
While playing, hit ~ to bring up the console. Then type in "DebugMode 1" without the quotes. You may then use the following codes. (Note that all codes are cAsE sEnSiTiVe and some such as the set(stat) codes require you to select a target when you use them)
Cheat Effect
dm_givegold # Gives the desired amount of gold
dm_god Invincibility
dm_unlockcamera Allows you to use the camera with better scrolling and the such
givefeat # Add the feat to your currently selected character (use #'s 2 through around 500)
giveitem [item tag] # Gives active player item
givespell # Gives a spell identified by it's id number to the character.
givexp # Gives the desired amount of XP to your character.
givexp [-ve number] Decreases your experience points by the value entered
irolltwenties 20 in every statistic.
polymorph # Turns your controlled character into a different creature.
removefeat # Remove the feat corresponding to that number
resetlevels Delevel you if your experience points is near to 0
rs ga_alignment(-1,0) to move one point towards evil
rs ga_alignment(-1,1) to move one point towards Chaos
rs ga_alignment(1,0) to move one point towards good
rs ga_alignment(1,1) to move one point towards Law
rs ga_influence (x,y) Raises influence level for that companion.
rs ga_party_limit(6) Raises the amount of party members you may have at once to 6. Default is 3 in Act 1 and 4 in Acts 2 and 3.
rs ga_time_advance(Hours,Min,Sec,Milli) replace Hours, Minutes, Seconds and Milliseconds with how much time you want to advance.
rs kr_influence A simple influence editor, in the form of a dialogue.
rs kr_roster_edit Opens a debug dialogue with an option to open the party roster to switch party members in and out at any time. (Use caution with other features there)
Set Appearance # Makes your character have the appearance of the # in the res ref table of the 2da appearance file...*Note this is just appearance*
SetCHA # Set charisma to given number.
SetCON # Set constitution to given number.
SetDEX # Set dexterity to given number.
SetINT # Set intelligence to given number.
SetSTR # Set strength to given number.
SetWIS # Set wisdom to given number.
unpolymorph Returns your controlled character to normal.
rs gr_dm Spawns a Dungeon Master NPC who will allow you to spawn items, add journal entries, open stores, add/remove party members, and teleport.
International language keyboard console opening
To open the console on a non-English keyboard (like Swedish for example), press the accentuation (not apostrophe!) and questionmark buttons in quick succession while holding down shift.
See the full page here:
http://www.gamespot.com/pc/rpg/neverwinternights2/hints.html

TweakGuides: Debug Commands

Tweak guides has a full list of debug commands posted on their fantastic NWN2 TweakGuide section.

The command console in Neverwinter Nights 2 allows users to apply various tweaks or changes to the game 'on the fly' while playing. To open and close the console, press the '~' key (or the key above TAB and/or below ESC) on your keyboard. To implement a console command, simply type its name along with any parameters required. Importantly, for many commands to work, you will need to first enable debug mode by entering the following into the console then pressing ENTER:

DebugMode 1

Note that console commands are case sensitive, so entering debugmode 1 for example won't work, it needs to be exactly as shown, i.e. DebugMode 1. The full list of console commands is provided further below in alphabetical order, however I provide full descriptions for the most useful commands first:

 

showfps - Toggles the frames per second (fps) display on/off.

trees - Toggles the rendering of all trees on/off. Useful for temporarily improving FPS in outdoor areas.

renderwater - Toggles the rendering of water on/off. Useful for temporary FPS boost in areas with water.

rain [0,1] - Toggles rain effects on if set to 1, off if set to 0.

daynight - Toggles the day/night cycle.

wireframe - Toggles wireframe mode on/off, useful for seeing the amount of detail actually being rendered/calculated in any area, even if it's not directly visible on screen.

gfxoptions - Brings up a special Graphics Options dialog box with a multitude of graphics-related settings you can change, including shadow intensity, toggling the day/night cycle, toggling rain on/off and altering the Bloom lighting parameters.

rs kr_roster_edit - Opens the NWN2 Companion Roster Editor, with a proper interface for adding, removing and altering various parameters for companions.

SetSTR, SetDEX, SetCON, SetINT, SetWIS, SetCHA [Value] - Right-click select a target, and use these commands to alter the relevant attribute to the value you wish. For example, right-click select your own character and use SetSTR 18 to give him/her 18 Strength.

givefeat [ID or all] - Select a character then use this command with the appropriate feat ID/name to give them that feat, or use 'all' to give them every feat.

giveitem [ID] [Number of items] - Select a character then use this command to give a particular item to the character, along with how many of that item to give. The list of ID tags for items can be found by launching the NWN2 Toolset, going to the Plugins menu item, selecting 'Universal Blueprint Changer', then selecting Items in the new dialog box and finding the appropriate name under the Tag column.

givespell [iD] - Select a character then use this command to give a particular spell to the character. The spell IDs can be found by launching the NWN2 Toolset, going to the View>2DA File menu option, then selecting the Spells file and using the number under the Name column.

givexp [value] - Select a character then use this command to give them the specified number of experience points.

dm_givegold [value] - Right-click select a character then use this command to give them the specified amount in gold pieces.

dm_god - Enables God mode, meaning you can't be killed.

The following are all the 181 console commands for Neverwinter Nights 2. Aside from DebugMode needing to be enabled for most of them to work, remember that many of them require you to either be the active character, or right-click select a particular character to apply a command successfully.

aabboxes

ambient

anim_blend

animation

animglod

animlod

anims

attachcamera

auditfeats

auditspells

automemorize

axes

base

blurradius

border

bugreport

c2

c3

camera_debug

camera_debug_full

camera_debug_los

capsules

clientstats

creatures

cutscene

cutscene_override

daynight

daynightscale

daytime

debugcam

DebugMode

debugtext

depthbatch

depthbatchindex

diffuse

DirShadowDepthBias

DirShadowSlopeScaleDepthBias

dm_givegold

dm_god

dm_jumptopoint

dropshadows

dumpmemory

dumptextures

emo_blend

EnableCombatDebugging

envshadows

exportchar

ffxbase

flicker_lights

fog

frecam

frusta

full

gfxoptions

givefeat

giveitem

givespell

givexp

glowintens

glows

hiliteintens

hilitethresh

hookpoints

irolltwenties

island

killgui

lights

loadgame

loc

loggameeffects

logrunscript

logserverai

lokkat

memstats

minimapsave

mipfilter

mousepick

mousepos

NetProfile

NetProfileReport

normals

obb_all

obb_cdoor

obb_sdoor

obb_water

obboxes

occlusion

partyadd

partyremove

paths

pbn

perception

physics

playbyname

PointShadowDepthBias

pointshadows

PointShadowSlopeScaleDepthBias

polymorph

portraitsave

possesscompanion

printactions

printcombatdata

printcreatures

printeffects

printfactiontable

printfeats

printglobalvars

printlevelstats

printlistenexpressions

printlocalvars

printperception

printrepository

printreputation

printscripts

profiling

rain

ReigidPointShadowZBias

removefeat

renderpc

renderwater

resetlevels

resetpackage

resetstats

resourcestats

RigidDirShadowZBias

rosteradd

rs

runscript

savedaynightstage

savegame

sceneintens

scriptprofiling

SelfDirShadowDepthBias

SelfDirShadowSlopeScaleDepthBias

SelfPointShadowDepthBias

SelfPointShadowSlopeScaleDepthBias

serverstats

SetCHA

SetCON

SetDEX

SetINT

setstatsdepth

SetSTR

SetWIS

shadowmap

shadows

showattacks

showcomments

showfps

showscriptcalls

showstats

showtriggerevents

skels

SkinDirShadowZBias

SkinPointShadowBias

sky

snow

softshadows

solid

specular

spheres

stats

surface

surfaceonly

takedamage

TerrainDirShadowDepthBias

TerrainDirShadowSlopeScaleDepthBias

TerrainDirShadowZBias

texfilter

textborder

tint

toggleserver

trees

unpolymorph

usebehavior

usescriptset

verifymemory

voiceover

wami

waterreflections

wireframe

 

Head over to the Tweak Guide for more information: http://www.tweakguides.com/NWN2_1.html

World Maps

The world map plugin allows you to create an interactive world map that lets players jump from location to location in a campaign.

OE: Instructions for creating world maps

grinning_fool has posted this on the official message boards in the Toolset thread:

These instructions came from OE:

** The Campaign Editor **
Important thing is that you have opened the campaign editor from the plugins menu in the toolset at least once, created a campaign using “Add Campaign”, named it, saved it to the Campaigns directory, and clicked “set current module to use selected campaign” while working in the module in which you’d like the world map to appear. Then you have to save the module.

** Creating a Map **
1. Open Plugins->World Map Editor in the toolset.

2. Choose File->New in the World Map Editor.

3. In the properties field, set the world map image property to the .tga or .dds of your choice. This is the background map image that will be displayed.

4. For the time being, you need to manually input the height and width of this image. Our OC image is 647x647 pixels. That would be listed as Height = 647, Width = 647.

5. Name the world map in the WorldMapName property

6. Now add a hotspot. Hotspots are the locations that a player clicks on the map when choosing a travel destination. Choose “Add” in the toolbar above the editor window. Click anywhere you would like to add a hotspot. These can also be click-dragged later.

7. Click “select” in the toolbar above the editor. Click on a hotspot.

8. Each hotspot has two associated scripts, an action and a conditional. These will be written by the user. The conditional script returns TRUE if the hotspot should be shown and FALSE if it should be hidden on the map. If you’d always like a given hotspot to display, just use the script gc_true.

9. The Action script gets called if the player chooses that particular hotspot in-game and clicks the “travel” button. Typically this script will contain a jump command, such as JumpPartyToArea(), that will send the party to a waypoint in the destination area the player clicked on the world map. A good simple script to use for this is ga_jump_players.

10. Fill in the icon image fields in the properties pane. These are the images that will be displayed by default, when the mouse hovers over the hotspot icon, and when the player clicks the hotspot icon, respectively. .tga is an acceptable format, and I believe .dds files willl also work. We use .tgas in the OC.

11. Fill in the DisplayName property. This is the name of the hotspot that the user will see in-game along the right side of the world map screen

12. Fill in the height and width of the three image icons. (These are the fields that literally just say “height” and “width.”) Note all three icon images need to be the same size. Our OC uses 32x32 icon images.

13. Fill in the Name property. You’ll see the display name at left in the World Map editor. It also functions as the “Tag” parameter for the ShowWorldMap() command described below.

14. Repeat 6-14 at least once. Probably your world map should have at least 2 functioning hotspots since at a bare minimum you’d probably want to travel back and forth.

15. Save the world map to the campaign directory of the campaign associated with the module in which you’d like to use this world map. So for a campaign called Drizzt, you’d put it in the folder Campaigns\Drizzt. I believe this should work from both the MyDocs\NWN2\Campaigns directory and the NWN2\Game\Campaigns directory.

** Bringing up the World Map in-game **
This can be done at any time, through any script, using the ShowWorldMap() command. We usually call it from the OnClicked event of a transition trigger placed down in game. The first parameter is the world map name, minus the .wmp extension. So Faerun.wmp would be specified as “Faerun.” The second parameter is the player object that is going to have the world map displayed on his screen. The last parameter is the name of the hotspot (set in step 13 above) that the player is currently standing in. I believe it can be the empty string (“”) for “no origin,” but haven’t checked.

There's a lot more information in the original thread:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=511655&forum=1...

If anyone can point out the Obsidian Entertainment reference that grinning_fool used, it would be appreciated.

Sunjammer's World Map Guide

Sunjammer posted an excellent guide about world maps on nwvault. From his description on that page:

The NWN2 World Map System provides an exciting new interface for representing long distance travel in your campaign. However as it introduces several new concepts and requires some scripting knowledge the World Map System has proven to be rather difficult to master.

The World Map Guide is designed to help you integrate a fully function World Map into you campaign with the minimum of pain and suffering. When complete the World Map Guide will take you every step along the road from constructing your first World Map to overhauling the World Map GUI.

You can download it here:
http://nwvault.ign.com/View.php?view=NWN2Tutorials.Detail&id=54

You may also want to check out Sunjammer's website.

Additional information for world maps

Wilkin the Wanderer posted some questions and expressed his frustration with the world map system in the official forums, leading to some great pointers by other community members.

Check out the thread:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=542076&forum=1...

Jaks' Realistic world maps

Jaks has posted the following tutorial on creating 3D maps.

For my campaign I really want to give a sense of the size and scope of the region in which the characters will participate. The world map feature of NWN2 will go a long way for providing that depth to our playing field. I've yet to hear details on what formats the world map can be drawn in but I do imagine a graphic format of some kind will be allowed to be imported into the module in some way. So to prepare I have begun to map out my region. Using a combination of the Forgotten Realms Atlas and my campaign book I started a new map for the region in my recently purchased CC3 (Campaign Cartographer 3) application. As usual CC is a bear to use. Trying to be detailed while at the same time trying to be stylish with it is difficult, despite the fact that CC3 has added a slew of new creative features. No matter how hard I try they all come out looking like CC maps, bland and dry. While perusing the recent release of pictures from GenCon I saw the pic for the world map here[link]. I like it, very stylish, almost 3D in a way. That got me thinking, Im a much better application user than I am an artist, could I instead find some 3D tools (like my recently acquired 3DSMax) to create a 3D scene for them to interact with? While looking around for a way to generate terrains (easily) in 3DSMax, I eventually gave up for some other apps that allow the building and rendering of heightfields[link to wikipedia]. This made alot of sense to me, seeing as how the toolset will be using Heightfields as well, it may benefit me to learn more about them, create a detailed and beautiful world map and at the same time find some tools that I may be able to be reused to create my areas as well. Below is the final product of my endeavors so far. As you can see it is a fully realized 3D terrain of the Durpar, Estagund and Var nations of the Shining South, all based around the Golden Waters bay.

The overland map for the Golden Waters area. Covers the nations of Estagund, Durpar and Var the Golden as well as showing the beginnings of the Raurin Desert. Notice how I was able to replicate the golden hue to the bay area as described in the official setting.

Applications Used: Leveller Demo, Terragen, Paint Shop Pro (substitute any graphics app)

So how did I do it? What applications did I use? Read on and I'll walk you through the process I took (without the heavy learning curve) to get to this point.

Check it out:
http://www.nwcitadel.com/blog/index.php?op=ViewArticle&articleId=16&blog...

And don't miss follow-ups:

Realistic World Map Tutorial Part 3 - Landmarks
http://www.nwcitadel.com/blog/index.php?op=ViewArticle&articleId=20&blog...

Realistic World Map Tutorial Part 3 - Mixing Terrains
http://www.nwcitadel.com/blog/index.php?op=ViewArticle&articleId=19&blog...

Realistic World Map Tutorial Part 2 - Terragen
http://www.nwcitadel.com/blog/index.php?op=ViewArticle&articleId=17&blog...

Script examples from the OC

The following examples have been taken from the Official Campaign for reference when building a world map for your campaign. Note that these scripts are "kampaign" scripts and do not exist in modules by default.

ka_hotspot_click

The script ka_hotspot_click is the most basic world map script from the Official Campaign. It is meant to go in the "ActionScript" field for a hotspot in the world map plugin interface. At end of the script, notice that this calls SaveRosterLoadModule (located in ginc_companion). This function takes two parameters: the name of the module to load and the name of the waypoint the party will jump to. Here are the parameters for this script: string sModule - The file name of the module string sHotspot - The name of the hotspot clicked for the purposes of checking for a special case int nProbSpecial - Percentage chance for a special encounter int nProbRandom - Percentage chance for a random encounter string sDestinationOverride - The waypoint to go to intead of the default for a module string sCustomScript - Name of a custom script to execute There is a percent chance per transition that the party will have an encounter, but it only happens once. I think that the encounter area sends the party along to where they were going after they have completed the encounter. Note the use of GetIsObjectValid(oDest) to determine if the transition is in the current module and SinglePartyTransition( oPC, oDest ) to jump to the waypoint if it is in the current module.

// ka_hotspot_click
//
// Action script for when a hotspot is clicked on the worldmap. Determines the location to send
// the party to.
// BMA-OEI 4/12/06 - replaced LoadNewModule() with SaveRosterLoadModule()

#include "kinc_worldmap"
#include "ginc_debug"
#include "ginc_companions"
#include "ginc_transition"

void JumpParty(object oPartyMember, object oDestination)
{
object oThisArea = GetArea(oPartyMember);
object oJumper = GetFirstFactionMember(oPartyMember);

while (GetIsObjectValid(oJumper))
{
PrettyDebug("Jumping " + GetName(oJumper) + " to " + GetTag(oDestination));
AssignCommand(oJumper, JumpToObject(oDestination));
oJumper = GetNextFactionMember(oPartyMember);
}
}

void main(string sModule, string sHotspot, int nProbSpecial, int nProbRandom, string sDestinationOverride, string sCustomScript)
{
string sDestination;
object oDestination;
int nRoll;
object oPC = OBJECT_SELF;

if(!GetIsSinglePlayer())
{
if(GetWorldMapLocked())
{
SendMessageToPC(oPC, GetStringByStrRef(STRING_REF_MAP_LOCKED));
return;
}
else
{
SetWorldMapLocked();
}
}

//we only want one map encounter per player attempt to travel --
//prevents the player getting barraged by module cutscenes
//when he just wants to get to point B.
if(!GetGlobalInt("bPlayedEncounterOnThisClick"))
{
sDestination = GetModuleEncounter(sModule, sHotspot);


PrettyMessage(sHotspot + " clicked.");
if (sHotspot == "1302OldOwlWell")
{
if (GetGlobalInt("10_met_grobnar") != 1)
{
object oDest = GetObjectByTag("wp_1003_enter");

SetGlobalInt("10_met_grobnar", 1);

if (GetIsObjectValid(oDest))
{
ForceRestParty( oPC );
// BMA-OEI 6/14/06
SinglePartyTransition( oPC, oDest );
//JumpPartyToArea(oPC, oDest);
}
else
{
ForceRestParty( oPC );
//LoadNewModule("1000_Neverwinter_A1", "wp_1003_enter");
SaveRosterLoadModule("1800_Skymirror", "wp_1003_enter");
}
return;
}
}

if(sCustomScript != "")
{
ExecuteScript(sCustomScript, OBJECT_SELF);
}

if(sDestination == "")
{
nRoll = Random(100);

if(nRoll < nProbSpecial)
{
sDestination = GetSpecialEncounter(sModule, sHotspot);
}
else if(nRoll < nProbSpecial + nProbRandom)
{
sDestination = GetRandomEncounter(sModule, sHotspot);
}
}
}
if(sDestination == "")
{
SetGlobalInt("bPlayedEncounterOnThisClick",FALSE);
if(sDestinationOverride == "")
{
sDestination = GetDefaultDestination(sHotspot);
PrettyMessage("Sending to default destination " + sDestination);
}
else
{
sDestination = sDestinationOverride;
}
}
else //we're doing a special, module, or random encounter
{
SetGlobalInt("bPlayedEncounterOnThisClick",TRUE);

// unless our present encounter overrides the message with a global variable, we play it
// and return.
if(!GetGlobalInt(ENCOUNTER_MESSAGE_OVERRIDE))
{
ShowEncounterMessage(sDestination, sModule);
return;
}
SetGlobalInt(ENCOUNTER_MESSAGE_OVERRIDE, FALSE);
}

//this variable handles origin-dependent redirection, like changing the point of
//entry in the docks district depending on whether you came from blacklake
//or the merchant quarter. We reset it to its default here. It is set in the
//cliententer scripts of applicable areas.
SetGlobalInt("OriginArea",0);

oDestination = GetObjectByTag(sDestination);

if(GetIsObjectValid(oDestination))
{
ForceRestParty( oPC );
// BMA-OEI 6/14/06
SinglePartyTransition( oPC, oDestination );
//JumpPartyToArea(oPC, oDestination);
}
else
{
ForceRestParty( oPC );
PrettyDebug("Unable to find waypoint in current module. Initiating module transition.");
PrettyDebug("Loading module. Destination = " + sDestination);
//LoadNewModule(sModule, sDestination);
SaveRosterLoadModule(sModule, sDestination);
}

}

kinc_worldmap

This is the heart of the world map functions. Not that all the includes and constants work for the OC only.

// kinc_worldmap
//
// Functions and constants for the NWN2 world map functionality
	
// EPF 12/8/05
	
#include "ginc_debug"
	
// the below files contain all the encounter logic
#include "kinc_module1000"
#include "kinc_module1100"
#include "kinc_module1200"
#include "kinc_module1300"
#include "kinc_module1600"
#include "kinc_module1700"
#include "kinc_module1800"
#include "kinc_module1900"
#include "kinc_module2000"
#include "kinc_module2100"
#include "kinc_module2200"
#include "kinc_module2300"
#include "kinc_module2400"
#include "kinc_module2600"
#include "kinc_module3000"
#include "kinc_module3100"
#include "kinc_module3400"
#include "kinc_module3500"

	
/////////////////////////
// FUNCTION DECLARATIONS
/////////////////////////
	
// ** hotspot functions	**

//make a hotspot visible on the world map
void ShowHotspot(string sHotspot);
	
//make a hotspot invisible on the world map
void HideHotspot(string sHotspot);

//returns true if a hotspot is visible on the world map
int GetIsHotspotVisible(string sHotspot);

//make all hotspots with numbers between nLow and nHigh (inclusive) visible
void ShowHotspotRange(int nLow, int nHigh);

//make all hotspots with numbers between nLow and nHigh (inclusive) invisible
void HideHotspotRange(int nLow, int nHigh);

//run at the start of a module to associate a hotspot with its default waypoint
void SetupDefaultDestinations(int nAct = -1);
	
// ** conversion functions **	

//hotspot number is the 4-digit area code for the area that the hotspot points to
string GetHotspotNameFromNumber(int nAreaNumber);
int GetHotspotNumberFromName(string sHotspot);

	
// ** encounter functions **

// returns the waypoint tag for a plot-based critpath encounter or the empty string if none is available
string GetModuleEncounter(string sModule, string sDestHotspot);

// returns the waypoint tag for a non-critpath encounter that isn't just random monsters or the empty string if none is available
string GetSpecialEncounter(string sModule, string sDestHotspot);

// returns the waypoint tag for a random monster encounter or the empty string if none is available
string GetRandomEncounter(string sModule, string sDestHotspot);

// show a "you have encountered a thing on the world map" message.  Callback initiates the transition.
void ShowEncounterMessage(string sDestination, string sModule);


// ** world map locout functions **

// multiple PCs simultaneously clicking travel on the world map causes problems.  We use a cooldown time to preven this.
void SetWorldMapLocked();
int GetWorldMapLocked();



/////////////////////////
// CONSTANT DECLARATIONS
/////////////////////////

// GENERAL //

// these are used with the Encounter message box
const int STRREF_ENCOUNTER_MESSAGE = 182995;
const string ENCOUNTER_MESSAGE_OVERRIDE = "00_bOverrideEncounterMessage";
const string LAST_DESTINATION = "00_sLastDestination";
const string LAST_MODULE = "00_sLastModule";
const string PC_CLICKER = "oLastWorldMapClicker";	//this is stored on the module not 

// these are for locking the world map so only one user can use it at a time
const string WORLD_MAP_LOCKED = "00_bWorldMapLocked";
const string WORLD_MAP_LOCKER = "oWorldMapLocker";
const int STRING_REF_MAP_LOCKED = 183512;
const string WORLD_MAP_LOCKED_DAY = "00_nWorldMapLockDay";
const string WORLD_MAP_LOCKED_HOUR = "00_nWorldMapLockHour";
const string WORLD_MAP_LOCKED_MINUTE = "00_nWorldMapLockMinute";
const string WORLD_MAP_LOCKED_SECOND = "00_nWorldMapLockSecond";
const int WORLD_MAP_LOCK_COOLDOWN = 18;	//seconds until we allow another click
const string WORLD_MAP_LOCK_INITIALIZED = "00_bWorldMapLockInit";

// ACT 1 HOTSPOTS HERE // 

// 1000
const int HS_NWC_A1 = 1001;

// 1700 Merchant Quarter
const int HS_MQ = 1013;

// 1800 Skymirror and Grobnar
const int HS_GROBNAR = 1003;
const int HS_SKY = 1040;
	
// 1900 Back Alley
	
// 1100
const int HS_WEST_HARBOR = 1100;
const int HS_WH_RUINS = 1120;
	
// 1200
const int HS_WILLOW = 1202;
const int HS_LIZARD1 = 1206;
const int HS_FORTLOCKE = 1209;
const int HS_GRAVEYARD = 1211;
const int HS_BANDITCAMP = 1214;
const int HS_HIGHCLIFF = 1217;
const int HS_HC_SHANDRA = 1208;
const int HS_HC_RUINS = 1218;
const int HS_LIZARD2 = 1220;
const int HS_GLADE = 1223;
const int HS_WIDOW = 1225;

// 1300
const int HS_OOW_A1 = 1302;
const int HS_BG_APPROACH = 1303;
const int HS_IRONFIST = 1308;
const int HS_EG_APPROACH = 1314;

// 1600
const int HS_EMBER = 1616;
const int HS_GITHAPP = 1620;
const int HS_GITHCAVE = 1621;
const int HS_GC_SHANDRA = 1610;
	
// ACT 2 HOTSPOTS HERE //

//2000
const int HS_NWC_A2 = 2000;
const int HS_NWC_BLACKLAKE = 2024;
const int HS_NWC_MERCHANT = 2013;

//2100
const int HS_CK_COURT = 2100;

//2200
const int HS_PL_A2 = 2200;
const int HS_PL_EMBER = 2210;
const int HS_PL_DUSKWOOD = 2211;

//2300
const int HS_CKA_FARM = 2300;
const int HS_CKA_TUNNEL = 2340;

//2400
const int HS_IR_OGRUINS = 2410;

//2600
const int HS_AJ_EXTERIOR = 2600;


// ACT 3 HOTSPOTS HERE //

//3000
const int HS_PARTY 			= 0000;
const int HS_HIGHCLIFF_A3	= 3010;
const int HS_LIZARDMEN 		= 3014;
const int HS_IRONFIST_A3	= 3030;
const int HS_GALARDRYM		= 3031;
const int HS_COT_MERE		= 3040;
const int HS_REAVER_A		= 3050;
const int HS_REAVER_B		= 3051;
const int HS_NWC_MERCH		= 3063;
const int HS_SH_FARM_A3		= 3070;
const int HS_PORT_LLAST		= 3080;
const int HS_WENDER			= 3081;

//3100
const int HS_CK_COURT_A3	= 2100;
const int HS_NOLALOTH 		= 3090;

/////////////////////////
// FUNCTION DEFINITONS
/////////////////////////

void ShowHotspot(string sHotspot)
{
	SetGlobalInt("WM_bShow" + sHotspot, TRUE);
}

void HideHotspot(string sHotspot)
{
	SetGlobalInt("WM_bShow" + sHotspot, FALSE);
}

int GetIsHotspotVisible(string sHotspot)
{
	return GetGlobalInt("WM_bShow" + sHotspot);
}


void ShowHotspotRange(int nLow, int nHigh)
{
	string sHotspot;
	while(nLow <= nHigh)
	{
		sHotspot = GetHotspotNameFromNumber(nLow);
		if(sHotspot != "")
		{
			ShowHotspot(sHotspot);
		}
		nLow++;
	}
}

void HideHotspotRange(int nLow, int nHigh)
{
	string sHotspot;
	while(nLow <= nHigh)
	{
		sHotspot = GetHotspotNameFromNumber(nLow);
		if(sHotspot != "")
		{
			HideHotspot(sHotspot);
		}
		nLow++;
	}
}


void SetDefaultDestination(string sHotspot, string sDestWP)
{
	SetGlobalString("WM_sDestWP" + sHotspot, sDestWP);
}

string GetDefaultDestination(string sHotspot)
{
	return GetGlobalString("WM_sDestWP" + sHotspot);
}

void SetupDefaultDestinationsAct1()
{
	// 1000 Neverwinter City Act 1
	SetDefaultDestination(GetHotspotNameFromNumber(HS_NWC_A1), "10_world_to_docks");
	
	// 1700 Merchant Quarter
	SetDefaultDestination(GetHotspotNameFromNumber(HS_MQ), "10_wp_docksi_to_merchant");
	
	// 1800 Skymirror and Grobnar
	SetDefaultDestination(GetHotspotNameFromNumber(HS_GROBNAR), "wp_1003_enter");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_SKY), "10_wp_OL_to_skymirror");
	
	// 1100 West Harbor
	SetDefaultDestination(GetHotspotNameFromNumber(HS_WH_RUINS), "wp_OL_to_1120");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_WEST_HARBOR), "tr_1100_from_1120");

	// 1200 Highcliff
	SetDefaultDestination(GetHotspotNameFromNumber(HS_WILLOW), "wp_OL_to_1202");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_LIZARD1), "wp_OL_to_1206");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_FORTLOCKE), "wp_OL_to_1209");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_GRAVEYARD), "wp_OL_to_1211");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_BANDITCAMP), "wp_OL_to_1214");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_HIGHCLIFF), "wp_OL_to_1217");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_HC_RUINS), "wp_OL_to_1218");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_LIZARD2), "wp_OL_to_1220");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_HC_SHANDRA), "12_wp_shandra_farm");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_GLADE), "wp_1223_enter");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_WIDOW), "12_wp_widow");

	// 1300 OOW Defaults
	SetDefaultDestination(GetHotspotNameFromNumber(HS_OOW_A1), "NG_From_Tavern");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_BG_APPROACH), "1303_enter");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_IRONFIST), "13_Bonegnash2_To_Bugapproach");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_EG_APPROACH), "13_Casavir_To_EGApproach");

	// 1600 Githyanki Caves Defaults
	SetDefaultDestination(GetHotspotNameFromNumber(HS_GITHAPP), "wp_from_ambush");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_EMBER), "wp_from_patrol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_GC_SHANDRA), "wp_shandra_farm");
}

void SetupDefaultDestinationsAct2()
{
	SetDefaultDestination(GetHotspotNameFromNumber(HS_NWC_A2),"10_wp_city_to_flagon");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_NWC_BLACKLAKE), "wp_from1013_to1024");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_NWC_MERCHANT), "10_wp_docksi_to_merchant");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_CK_COURT ),"wp_CKA2_start");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_PL_A2 ),"2200_wp_entrance");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_PL_EMBER ),"2210_wp_entrance");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_PL_DUSKWOOD ),"2211_wp_entrance");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_CKA_FARM ),"23_wp_pc_ritual_start");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_CKA_TUNNEL), "23_wp_tunnel_ext");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_IR_OGRUINS ),"2410_wp_entrance");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_AJ_EXTERIOR ),"2650_wp_pc");	
}

void SetupDefaultDestinationsAct3()
{
	SetDefaultDestination(GetHotspotNameFromNumber(HS_PARTY),"wp_30_overland_enter");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_HIGHCLIFF_A3),"wp_3010_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_LIZARDMEN),"wp_3014_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_IRONFIST_A3),"wp_3030_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_GALARDRYM),"wp_3031_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_COT_MERE),"wp_3040_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_REAVER_A),"wp_3050_pc");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_REAVER_B),"wp_3050_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_NWC_MERCH),"wp_3063_enter");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_SH_FARM_A3),"wp_3070_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_PORT_LLAST),"wp_3080_from_ol");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_WENDER),"wp_3081_enter");	
	SetDefaultDestination(GetHotspotNameFromNumber(HS_CK_COURT_A3 ),"wp_21_enter_ck");
	SetDefaultDestination(GetHotspotNameFromNumber(HS_NOLALOTH ),"wp_3090_from_ol");
}

void SetupDefaultDestinations(int nAct = -1)
{
	switch(nAct)
	{
	case 1:
		SetupDefaultDestinationsAct1();		
		break;
	case 2:
		SetupDefaultDestinationsAct2();
		break;
	case 3:
		SetupDefaultDestinationsAct3();
		break;
	
	default:
		SetupDefaultDestinationsAct1();
		SetupDefaultDestinationsAct2();
		SetupDefaultDestinationsAct3();
		break;
	}
}

string GetAct1HotspotNameFromNumber(int nAreaNumber)
{
	string sName = "";
	switch(nAreaNumber)
	{
	// 1000
	case HS_NWC_A1 :
		sName = "1001flagon";
		break;

	// 1700
	case HS_MQ :
		sName = "1013merchant";
		break;
	
	// 1800
	case HS_GROBNAR :
		sName = "1003grobnar";
		break;
	case HS_SKY :
		sName = "1040sky";
		break;
	
	// 1100
	case HS_WH_RUINS :
		sName = "1120whruins";
		break;
	case HS_WEST_HARBOR :
		sName = "1100harbor";
		break;

	// 1200
	case HS_WILLOW :
		sName = "1202willowinn";
		break;
	case HS_LIZARD1 :
		sName = "1206Lizard1";
		break;
	case HS_FORTLOCKE :
		sName = "1209FortLocke";
		break;
	case HS_GRAVEYARD :
		sName = "1211Graveyard";
		break;
	case HS_BANDITCAMP :
		sName = "1214BanditCamp";
		break;
	case HS_HIGHCLIFF :
		sName = "1217Highcliff";
		break;
	case HS_HC_SHANDRA :
		sName = "1208ShandraFarm";
		break;
	case HS_HC_RUINS :
		sName = "1218HC_Castle";
		break;
	case HS_LIZARD2 :
		sName = "1220Lizard2";
		break;
	case HS_GLADE :
		sName = "1223glade";
		break;
	case HS_WIDOW :
		sName = "1225widow";
		break;
	
	// 1300
	case HS_OOW_A1 :
		sName = "1302OldOwlWell";
		break;
	case HS_BG_APPROACH :
		sName = "1303Bonegnasher";
		break;
	case HS_IRONFIST :
		sName = "1308Ironfist";
		break;
	case HS_EG_APPROACH :
		sName = "1314Eyegouger";
		break;

	// 1600
	case HS_EMBER :
		sName = "1616ember";
		break;
	case HS_GITHAPP :
		sName = "1620approach";
		break;
	case HS_GC_SHANDRA :
		sName = "1610shfarm";
		break;
	
	default: 
		sName = "";
		break;
	}
	return sName;
}
string GetAct2HotspotNameFromNumber(int nAreaNumber)
{
	string sName = "";
	switch(nAreaNumber)
	{
	case HS_NWC_A2 :
		sName = "2000Neverwinter_A2";
		break;
	case HS_NWC_MERCHANT :
		sName = "2013MerchantQuarter";	
		break;
	case HS_NWC_BLACKLAKE : 
		sName = "2024Blacklake";	
		break;
	case HS_CK_COURT :
		sName = "2100CrossroadKeep";
		break;
	case HS_PL_A2 :
		sName = "2200PortLlast";
		break;
	case HS_PL_EMBER :
		sName = "2210Ember";
		break;
	case HS_PL_DUSKWOOD :
		sName = "2211Duskwood";
		break;
	case HS_CKA_FARM :
		sName = "2300CKAdventure";
		break;
	case HS_CKA_TUNNEL :
		sName = "2340TunnelExt";
		break;
	case HS_IR_OGRUINS :
		sName = "2410OvergrownRuins";
		break;
	case HS_AJ_EXTERIOR :
		sName = "2600AJExterior";
		break;
	default: 
		sName = "";
		break;

	}
	return sName;
}
string GetAct3HotspotNameFromNumber(int nAreaNumber)
{
	string sName = "";
	switch(nAreaNumber)
	{
	case HS_PARTY :
		sName = "0000PartyCentral";
		break;
	case HS_HIGHCLIFF_A3 :
		sName = "3010Highcliff";
		break;
	case HS_LIZARDMEN :
		sName = "3014Lizardmen";
		break;
	case HS_IRONFIST_A3 :
		sName = "3030Ironfist";
		break;
	case HS_GALARDRYM :
		sName = "3031MtGalardrym";
		break;
	case HS_COT_MERE :
		sName = "3040Mere";
		break;
	case HS_REAVER_A :
		sName = "3050ReaverA";
		break;
	case HS_REAVER_B :
		sName = "3051ReaverB";
		break;
	case HS_NWC_MERCH :
		sName = "3063MerchantQuarter";
		break;
	case HS_SH_FARM_A3 :
		sName = "3070ShandrasFarm";
		break;		
	case HS_PORT_LLAST :
		sName = "3080PortLlast";
		break;
	case HS_WENDER :
		sName = "3081Wendersnaven";
		break;
	case HS_CK_COURT_A3 :
		sName = "2100CrossroadKeep";
		break;
	case HS_NOLALOTH :
		sName = "3090Nolaloth";
		break;
	default: 
		sName = "";
		break;

	}
	return sName;
}

string GetHotspotNameFromNumber(int nAreaNumber)
{
	string sName = "";

	// Divide and conquer by act
	if(nAreaNumber < 2000)
	{
		return GetAct1HotspotNameFromNumber(nAreaNumber);
	}

	else if (nAreaNumber < 3000)
	{
		return GetAct2HotspotNameFromNumber(nAreaNumber);
	}

	else
	{
		return GetAct3HotspotNameFromNumber(nAreaNumber);
	}
}

int GetHotspotNumberFromName(string sAreaName)
{
	return StringToInt(GetStringLeft(sAreaName, 4));
}
	
string GetModuleEncounter(string sModule, string sHotspot)
{
	int nModule = StringToInt(GetStringLeft(sModule, 4));

	PrettyMessage("nModule = " + IntToString(nModule));

	SetGlobalString("KA_HOTSPOT_DEST_MODULE",sModule);
	SetGlobalString("KA_HOTSPOT_DEST_HOTSPOT",sHotspot);	
	
	string sDestination;
	switch(nModule)
	{
	case 1000:
		sDestination = Get1000Encounter(sHotspot);
		break;
	case 1700:
		sDestination = Get1700Encounter(sHotspot);
		break;
	case 1100:
		sDestination = Get1100Encounter(sHotspot);
		break;
	case 1200:
		sDestination = Get1200Encounter(sHotspot);
		break;
	case 1300:
		sDestination = Get1300Encounter(sHotspot);
		break;
	case 1600:
		sDestination = Get1600Encounter(sHotspot);
		break;		
	case 2000:
		sDestination = Get2000Encounter(sHotspot);
		break;
	case 2100:
		sDestination = Get2100Encounter(sHotspot);
		break;
	case 2200:
		sDestination = Get2200Encounter(sHotspot);
		break;
	case 2300:
		sDestination = Get2300Encounter(sHotspot);
		break;
	case 2400:
		sDestination = Get2400Encounter(sHotspot);
		break;
	case 2600:
		sDestination = Get2600Encounter(sHotspot);
		break;
	case 3000:
		sDestination = Get3000Encounter(sHotspot);
		break;
	case 3100:
		sDestination = Get3100Encounter(sHotspot);
		break;
	case 3400:
		sDestination = Get3400Encounter(sHotspot);
		break;
	case 3500:
		sDestination = Get3500Encounter(sHotspot);
		break;
	default:
		PrettyMessage("kinc_worldmap: invalid module string given to GetModuleEncounter()");
		sDestination = "";
	}

	return sDestination;
}
	
string GetSpecialEncounter(string sModule, string sHotspot)
{
	int nModule = StringToInt(GetStringLeft(sModule, 4));
	string sDestination;
	switch(nModule)
	{
	case 1000:
		sDestination = Get1000SpecialEncounter(sHotspot);
		break;
	case 1700:
		sDestination = Get1700SpecialEncounter(sHotspot);
		break;
	case 1100:
		sDestination = Get1100SpecialEncounter(sHotspot);
		break;
	case 1200:
		sDestination = Get1200SpecialEncounter(sHotspot);
		break;
	case 1300:
		sDestination = Get1300SpecialEncounter(sHotspot);
		break;
	case 1600:
		sDestination = Get1600SpecialEncounter(sHotspot);
		break;		
	case 2000:
		sDestination = Get2000SpecialEncounter(sHotspot);
		break;
	case 2100:
		sDestination = Get2100SpecialEncounter(sHotspot);
		break;
	case 2200:
		sDestination = Get2200SpecialEncounter(sHotspot);
		break;
	case 2300:
		sDestination = Get2300SpecialEncounter(sHotspot);
		break;
	case 2400:
		sDestination = Get2400SpecialEncounter(sHotspot);
		break;
	case 2600:
		sDestination = Get2600SpecialEncounter(sHotspot);
		break;
	case 3000:
		sDestination = Get3000SpecialEncounter(sHotspot);
		break;
	case 3100:
		sDestination = Get3100SpecialEncounter(sHotspot);
		break;
	case 3400:
		sDestination = Get3400SpecialEncounter(sHotspot);
		break;
	case 3500:
		sDestination = Get3500SpecialEncounter(sHotspot);
		break;
	default:
		PrettyError("kinc_worldmap: invalid module string given to GetModuleEncounter()");
		sDestination = "";
	}

	return sDestination;
}

string GetRandomEncounter(string sModule, string sHotspot)
{
	return "";
}

void ShowEncounterMessage(string sDestination, string sModule)
{
	// so the callback knows where to jump the player to.
	SetGlobalString(LAST_DESTINATION, sDestination);
	SetGlobalString(LAST_MODULE, sModule);
	SetLocalObject(GetModule(),PC_CLICKER, OBJECT_SELF);
	SetCommandable(FALSE);	//freeze player until the callback is clicked.
	DisplayMessageBox(OBJECT_SELF, STRREF_ENCOUNTER_MESSAGE, "", "gui_map_transition");
}

void SetWorldMapLocked()
{
	SetGlobalInt(WORLD_MAP_LOCKED_DAY, GetCalendarDay());
	SetGlobalInt(WORLD_MAP_LOCKED_HOUR, GetTimeHour());
	SetGlobalInt(WORLD_MAP_LOCKED_MINUTE, GetTimeMinute());
	SetGlobalInt(WORLD_MAP_LOCKED_SECOND, GetTimeSecond());
	
	SetGlobalInt(WORLD_MAP_LOCK_INITIALIZED, TRUE);	//so we know the timer is initialized
	
	PrettyMessage("World map locked at time " + IntToString(GetTimeHour()) + ":" + IntToString(GetTimeMinute()) + ":" + IntToString(GetTimeSecond()));
}

int TimeToSeconds(int nHour, int nMinute, int nSecond)
{
	//for ease, we just convert the time into seconds -- 60 for 60 seconds in a minute, 3600 for number of seconds in an hour.
	return nSecond + nMinute * 60 + nHour * 3600;
}

int GetWorldMapLocked()
{
	if(GetIsSinglePlayer())
	{
		return FALSE;
	}

	if(!GetGlobalInt(WORLD_MAP_LOCK_INITIALIZED))
	{
		return FALSE;
	}

	int nLockedHour = GetGlobalInt(WORLD_MAP_LOCKED_HOUR);
	int nLockedMinute = GetGlobalInt(WORLD_MAP_LOCKED_MINUTE);
	int nLockedSecond = GetGlobalInt(WORLD_MAP_LOCKED_SECOND);
	
	int nCurrentHour = GetTimeHour();
	int nCurrentMinute = GetTimeMinute();
	int nCurrentSecond = GetTimeSecond();
	
	int nTotalLockedSeconds = TimeToSeconds(nLockedHour,nLockedMinute,nLockedSecond);
	int nTargetTime = nTotalLockedSeconds + WORLD_MAP_LOCK_COOLDOWN;	//10 sec cooldown
	
	int nCurrentSeconds = TimeToSeconds(nCurrentHour,nCurrentMinute,nCurrentSecond);
	
//	PrettyDebug("Target time for unlock = " + IntToString(nTargetTime));
//	PrettyDebug("Current time in seconds = " + IntToString(nCurrentSeconds));		
	
	//same day
	if(nTargetTime < nCurrentSeconds)
	{
//		PrettyDebug(IntToString(nCurrentSeconds - nTotalLockedSeconds) + " seconds passed since the last transition.");
		return FALSE;
	}		
	
	//we've rolled to the next calendar day
	int nLockedDay = GetGlobalInt(WORLD_MAP_LOCKED_DAY);
	int nCurrentDay = GetCalendarDay();
	
	//!= is the check here because the day change could roll the month
	//so going from month 1 day 28 to month 2 day 0 should still register as a day having passed.
	if(nCurrentDay != nLockedDay && nCurrentSeconds > WORLD_MAP_LOCK_COOLDOWN)
	{
		return FALSE;
	}
		
	return TRUE;
}

gtr_world_map_cl

If you paint down a new map transition, you'll notice that it has an onClick script of gtr_world_map_cl. You'll also noticed that this script doesn't actually exist in new modules. I think what happened is that this script started as a global, but at some point ended up with some code specific to the OC and was removed. Here the script, pulled from 1000_Neverwinder_A1.mod (The Docks).

// gtr_world_map_cl
//
// Transition to the world map

// EPF

// EPF 2/2/06 -- modifying to have a default map for each act if no other map is specified.
// EPF 3/24/06 -- this is now an OnClicked event
// BMA-OEI 6/24/06 -- Added gather party check
// BMA-OEI 8/11/06 -- Autosave before transition
// ChazM 8/21/06 -- updated constant CAMPAIGN_SWITCH_REMOVE_DOMINATED_ON_TRANSITION
// BMA-OEI 8/22/06 -- Replaced auto save w/ AttemptSinglePlayerAutoSave()

#include "ginc_debug"
#include "ginc_autosave"
#include "ginc_transition"

void main()
{
object oPC = GetClickingObject();
if ( GetIsPC( oPC ) == FALSE )
{
return;
}

string sMap = GetLocalString(OBJECT_SELF, "sMap");
string sOrigin = GetLocalString(OBJECT_SELF, "sOrigin");

if(sMap == "")
{
int nAct = GetGlobalInt("00_nAct");

switch(nAct)
{
case 1:
sMap = "Highcliff";
break;
case 2:
sMap = "Act 2";
break;
case 3:
sMap = "Act 3";
break;
default:
sMap = "Highcliff";
break;
}
}

// BMA-OEI 7/04/06 - Check if using remove dominated campaign flag
if ( GetGlobalInt(CAMPAIGN_SWITCH_REMOVE_DOMINATED_ON_TRANSITION) == TRUE )
{
int nRemoved = 0;
object oFM = GetFirstFactionMember( oPC, FALSE );
while ( GetIsObjectValid(oFM) == TRUE )
{
nRemoved = nRemoved + RemoveEffectsByType( oFM, EFFECT_TYPE_DOMINATED );
oFM = GetNextFactionMember( oPC, FALSE );
}

if ( nRemoved > 0 )
{
// Abort transition if dominated effect was found and removed
return;
}
}

// BMA-OEI 6/24/06
if ( GetGlobalInt( VAR_GLOBAL_GATHER_PARTY ) == 1 )
{
if ( IsPartyGathered( oPC ) == FALSE )
{
ReportPartyGather( oPC );
return;
}
}

// BMA-OEI 8/22/06 -- Autosave before transition
AttemptSinglePlayerAutoSave();

ShowWorldMap( sMap, oPC, sOrigin );
}

ka_hotspot_click_force

The script ka_hotspot_click_force gets called when the devs needed to make sure a certain NPC is along for the ride. Otherwise, it seems to work very similar to ka_hotspot_click.

I've removed a number of the plot checks to avoid spoilers.

// ka_hotspot_click_force
//
// Action script for when a hotspot is clicked on the worldmap.  Determines the location to send
// the party to.  This variant checks a global variable sCompVar, and if it's equal to nCheckValue, 
// fires a message box instead of sending the player on.  That message box is defined in this file 
// as well, in DisplayForceCompanionMessage.  The nMessage parameter chooses what message box to use.

// EPF 1/10/06
// TDE 1/31/06 - Added messages for Act 3, and scripting for if any one of a list of companions is required.
// EPF 1/31/06 - Using IsInParty instead of GetIsRosterMemberAvailable().
// TDE 3/23/06 - Fixed a bug in the companion list script
// EPF 3/29/06 -- uses JumpPartyToArea now
// BMA-OEI 4/12/06 - replaced LoadNewModule() with SaveRosterLoadModule()
// TDE 4/25/06 - Added support for excluding companions using "-" instead of ","

#include "kinc_worldmap"
#include "ginc_debug"
#include "ginc_companions"
#include "ginc_transition"

// Each case here needs to do the following, in this order:
// 1. Set a global string "00_sLastForcedCompanion" to be the roster name of the companion you're forcing to join.
// 2. Display a message box.  Callback script is always gui_force_comp.
//
// TDE - Eric, if this becomes a permanent solution rather than temp, these strings will need to be 
//		 added to dialog.tlk and called with SpeakStringByStrRef(nNum)

void DisplayForceCompanionMessage(int nMessage)
{
	object oPC = OBJECT_SELF;
	switch(nMessage)
	{
	case 1:
		//You must have xin your party in order to travel to y. Proceed?
		SetGlobalString("00_sLastForcedCompanion", "sand");
		DisplayMessageBox(oPC,178912, "", "gui_force_comp","",TRUE,"SCREEN_MESSAGEBOX_DEFAULT",66,"",67);
		break

        // PLOT CHECKS REMOVED HERE!!!!

	}
}
	
void main(string sModule, string sHotspot, int nProbSpecial, int nProbRandom, string sCompanion, string sCompVar, int nCheckValue, int nMessage)
{
	string sDestination;
	object oDestination;
	int nRoll;
	object oPC = OBJECT_SELF;
	object oFirstPC = GetFirstPC();
	object oFM;
	
	if(!GetIsSinglePlayer())
	{
		if(GetWorldMapLocked())
		{
			SendMessageToPC(oPC, GetStringByStrRef(STRING_REF_MAP_LOCKED));
			return;
		}
		else
		{
			SetWorldMapLocked();
		}
	}
		
	//companion is supposed to be forced at this point
	if ( GetGlobalInt(sCompVar) == nCheckValue ) 
	{	
		// Added by TDE: to allow passing in a list such as "zhjaeve,ammon_jerro"
	    int iLen;
	    int iCommaPos = FindSubString( sCompanion, "," ); //find first comma
	    int iMinusPos = FindSubString( sCompanion, "-" ); //find first minus
		int bDisplayMessage = TRUE; //Display the message if is a required companion is NOT in party or an excluded companion is in the party

		if ( iCommaPos == -1 && iMinusPos == -1 )
		{
			//only checking for one companion
			if(IsInParty(sCompanion))	
			{
				bDisplayMessage = FALSE;
			}
		}
		else
		{
			//Checking for multiple companions
			//PrettyMessage("Checking for multiple companions");
			string sNewString = sCompanion;
			int iPosEnd;
			int iPosStart;
			int bExclude;
	
		    while ( iCommaPos != -1 || iMinusPos != -1 )
		    {
			//	PrettyDebug("Trying to find " + sNewString);

		        // determine length
		        iLen = GetStringLength(sNewString);

			    // get next comma or - position (returns -1 if not found)
		        iCommaPos = FindSubString(sNewString, "," );
				iMinusPos = FindSubString(sNewString, "-" );
				bExclude = FALSE;

				if ( iCommaPos == -1 && iMinusPos == -1 )
				{
					iPosStart = 0;
					iPosEnd = iLen;
				}
				else
				{
					if ( iMinusPos != -1 && (iCommaPos == -1 || iCommaPos > iMinusPos) ) 
					{
						PrettyDebug("Minus Pos = " + IntToString(iMinusPos));

						bExclude = TRUE;
						iPosStart = iMinusPos + 1;	// Minus is the next in the sequence
						if (iCommaPos > iMinusPos) 
							iPosEnd = iCommaPos - 1;
						else iPosEnd = iLen;
					}
					else
					{
					//	PrettyDebug("Comma Pos = " + IntToString(iCommaPos));
						iPosStart = 0;
						iPosEnd = iCommaPos;	// Comma is the next in the sequence
					}
				}
	
		        // get companion name in string
		        string sTempString = GetSubString(sNewString, iPosStart, iPosEnd);

				PrettyMessage("Getting " + sTempString);	

				// If this companion is in the party, set flag
				if ( IsInParty(sTempString) )
				{
					//PrettyDebug(sTempString + " is in the party.");
					if ( bExclude )
					{
					//	PrettyDebug(sTempString + " should NOT be in the party.");
						// Make sure they are selectable, so they can be removed from the party
						SetIsRosterMemberSelectable(sTempString,TRUE);
						bDisplayMessage = TRUE;
						break;
					}
					else 
					{
						PrettyDebug(sTempString + " should be in the party.");
						bDisplayMessage = FALSE;
					}
				}
				else PrettyDebug(sTempString + " is NOT in the party.");	
	
		        // drop first tag and comma
				if ( bExclude )
				{
				//	PrettyDebug("Getting index between zero and" + IntToString(iMinusPos));
			        sNewString  = GetSubString(sNewString, 0, iMinusPos);
				}	
		        	
				else 
				{
				//	PrettyDebug("Getting index between " + IntToString(iPosEnd + 1) + " and " + IntToString(iLen));
		        	sNewString  = GetSubString(sNewString, iPosEnd + 1, iLen);
				}
		    }
		}

		if( bDisplayMessage )
		{
		//	PrettyDebug("Displaying Force Companion Message.");
			DisplayForceCompanionMessage(nMessage);
			return;
		}
	}
	
	//we only want one map encounter per player attempt to travel --
	//prevents the player getting barraged by module cutscenes
	//when he just wants to get to point B.
	if(!GetGlobalInt("bPlayedEncounterOnThisClick"))
	{
		 sDestination = GetModuleEncounter(sModule, sHotspot);
	
		if(sDestination == "")
		{
			nRoll = Random(100);
	
			if(nRoll < nProbSpecial)
			{
				sDestination = GetSpecialEncounter(sModule, sHotspot);	
			}
			else if(nRoll < nProbSpecial + nProbRandom)
			{
				sDestination = GetRandomEncounter(sModule, sHotspot);
			}
		}
	}
	if(sDestination == "")
	{
		SetGlobalInt("bPlayedEncounterOnThisClick",FALSE);
		sDestination = GetDefaultDestination(sHotspot);
	}
	else	//we're doing an encounter
	{
		SetGlobalInt("bPlayedEncounterOnThisClick",TRUE);
		// unless our present encounter overrides the message with a global variable, we play it 
		// and return.
		if(!GetGlobalInt(ENCOUNTER_MESSAGE_OVERRIDE))
		{
			ShowEncounterMessage(sDestination, sModule);
			return;
		}
		SetGlobalInt(ENCOUNTER_MESSAGE_OVERRIDE, FALSE);		
	}
	
	//this variable handles origin-dependent redirection, like changing the point of
	//entry in the docks district depending on whether you came from blacklake
	//or the merchant quarter.  We reset it to its default here.  It is set in the 
	//cliententer scripts of applicable areas.
	SetGlobalInt("OriginArea",0);	
	
	oDestination = GetObjectByTag(sDestination);
		
	if(GetIsObjectValid(oDestination))
	{
		ForceRestParty( oPC );
		// BMA-OEI 6/14/06
		SinglePartyTransition( oPC, oDestination );
		//JumpPartyToArea(oPC, oDestination);
	}
	else
	{
		ForceRestParty( oPC );
		PrettyDebug("Unable to find waypoint in current module.  Initiating module transition.");
		//LoadNewModule(sModule, sDestination);
		SaveRosterLoadModule(sModule, sDestination);
	}
	
}

ka_hotspot_show

This simple script can be placed on a conversation node to make a certain hotspot visible at some point in the plot.

// ka_hotspot_show
//
// Set as visible the hotspot with name sHotspot

#include "kinc_worldmap"
		
void main(string sHotspot)
{
	ShowHotspot(sHotspot);
}

kc_hotspot_show

The following function checks to see if a hotspot has been found. It is meant to be placed on the ConditionalScript field of a world map.

// kc_hotspot_show
//
// global conditional script for world map hotspots.  Returns TRUE if this hotspot should be displayed
// on the world map.
	
// EPF 12/8/05
	
#include "kinc_worldmap"
	
int StartingConditional(string sHotspot)
{
	return GetIsHotspotVisible(sHotspot);
}

kinc_module1000

This script is an example of one of the encounter scripts that kinc_worldmap includes. It's worth noting that none of the OC module includes seem to do anything with the SpecialEncounter() function.

// kinc_module1000
//
// global include file for the module.
	
// EPF 12/8/05
// DBR 02/22/06 - if I havn't had the Sand intro, don't warp to the Sunken Flagon.
// DBR 08/03/06 - Initiate Olov ambush if player tries to leave Old Owl Well

#include "ginc_debug"

//const string OLOV_CS_FLAG = "13gb_olov_ambush";
//const string OLOV_CS_WP = "13_Cascamp_To_Olov";

	
string Get1000Encounter(string sDestHotspot)
{
	int nOrigin = GetGlobalInt("OriginArea");

	if (GetGlobalInt("13gb_olov_ambush") == 1)	//Olov ambush should occur, don't leave Old Owl Well without Ambush occurring.
	{
		SetGlobalInt("13gb_olov_ambush",2);
		PrettyMessage("Time for Olov to appear");
		return "13_Cascamp_To_Olov";
	}
		
	if ((sDestHotspot=="1001flagon")&&(!GetGlobalInt("10_arrival_done")))
		return "10_wp_cs_arrival_elstop";
	
	//Sydney/Johcris scene
	if (GetGlobalInt("00b_ReadyJocrisNataleCS")==1)
	{
		SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
		return "1025_wp_player";		
	}	
		
	if (sDestHotspot == "1001flagon" || sDestHotspot == "2000Neverwinter_A2")
	{
		PrettyMessage("Calling redirection script");
		
		switch (nOrigin)
		{		
			case 1013: //Player coming from Merchant Quarter
			{
				SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
				PrettyMessage("Entering from Merchant Quarter");
				SetGlobalInt("district_redirect", 1);
				return "10_wp_docksi_to_dockso";
			}
			break;
			case 1600: // Player coming from Blacklake
			case 2024:
			{
				SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
				SetGlobalInt("district_redirect", 1);
				return "10_wp_docksi_to_dockso";
			}
			break;
			case 1900: // Player coming from Back Alley
			{
				SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
				SetGlobalInt("district_redirect", 1);
				return "10_wp_alley_to_docks1_st_exit";
			}
			break;
		}
	}
	return "";
}
	
string Get1000SpecialEncounter(string sDestHotspot)
{
	return "";
}

kinc_module1700

 The world map include file for the Merchant Quarter shows how the origin variable is used to redirect to a different waypoint, based on which direction the party is coming from.

// kinc_module1700
//
// global include file for the module.

// JYL 04/17/06
// DBR 08/03/06 - Initiate Olov ambush if player tries to leave Old Owl Well
// DBR 08/16/06 - Changed waypoint override to a tag that is not also in the Docks

//const string OLOV_CS_FLAG = "13gb_olov_ambush";
//const string OLOV_CS_WP = "13_Cascamp_To_Olov";

string Get1700Encounter(string sDestHotspot)
{
int nOrigin = GetGlobalInt("OriginArea");

if (GetGlobalInt("13gb_olov_ambush") == 1) //Olov ambush should occur, don't leave Old Owl Well without Ambush occurring.
{
SetGlobalInt("13gb_olov_ambush",2);
//PrettyMessage("Time for Olov to appear");
return "13_Cascamp_To_Olov";
}



if (sDestHotspot=="1013merchant" || sDestHotspot=="2013MerchantQuarter")
{
switch (nOrigin)
{
case 0: // Player entering from outside city
{
SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
SetGlobalInt("district_redirect", 1);
return "10_wp_oow_spawn";
}
break;
case 1000: // Player entering from Docks
{
SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
SetGlobalInt("district_redirect", 1);
return "10_wp_docksi_to_merchant";
}
break;
case 1600: // Player entering from Blacklake
case 2024:
{
SetGlobalInt("00_bOverrideEncounterMessage", TRUE);
SetGlobalInt("district_redirect", 1);
return "wp_from1024_to1013";
}
break;
}
}
return "";
}

string Get1700SpecialEncounter(string sDestHotspot)
{
return "";
}

Custom Content

Here are some basic links dealing with custom content.

Deployment and Installation of Custom Content in NWN2

Heed submitted a great walkthrough of how custom content should be installed and deployed in NWN2.

There are several ways to get custom content into the game, but not all are equal. Some have advantages over others and some can actually break your game install making you unable to patch your game. This document will describe various methods and highlight best practices.

Head over to the Vault and give it a read:
http://nwvault.ign.com/View.php?view=NWN2Tutorials.Detail&id=56%3Cbr%3E

Using hak files

Hak files are the preferred way to distribute and use custom content.

Use the tools listed below to create hak files for NWN2.

ERFinder

tani's ERFinder is a great tool for creating hak files.

ERFinder is a small tool like the old hak-packer of nwn1. it can open/import/export/save any ERF-formatted files for nwn2, especially HAK, MOD, PWC and ERF itself. it uses OEIShared.dll from your nwn2-installation for all file-io (so it should be placed in your nwn2-folder) and needs .net 2.0 (like all nwn2 tools). it complies to the new ERF v1.1 format, thus allowing filenames to be 32 charakters long (hak-packer from nwn1 only supports v1.0, limiting filenames to 16 chars).

Get it from the vault:
http://nwvault.ign.com/View.php?view=NWN2Tools.Detail&id=9

Encapsulated Resource File Editor

Another tool for creating hak files is Ranmanu's Encapsulated Resource File Editor.

Edits, imports or exports data from Encapsulated Resource File files also known as ERF files (.HAK, .MOD, .ERF and .NWM).

Can be used for NWN1 (ERF version 1.0) as well as NWN2 (ERF version 1.1).

Get it from the vault:
http://nwvault.ign.com/View.php?view=NWN2Tools.Detail&id=30

Adding music to your module

A lot of people have been asking about this and I found a post here:

http://nwn2forums.bioware.com/forums/viewtopic.html?topic=526432&forum=115

Maria Caliban has the following advice:

How To...
Add music to your toolset

There are three parts to this:
1. Placing and labeling your music
2. Editing dialog.tlk
3. Editing amdiantsounds.2da

EDITING YOUR MUSIC FILE

1) Find the folder entitled 'Music' in your My Documents/Neverwinter Nights 2 directory
2) Rename it to fit the naming convention, which is mod_mus_[title]. For instance, for my Company of Blasphemous Ravens mod, I'm using Brunete's Amicus Meus, which was originally Brunete-Amicus_Meus.mp3. I change it to mod_mus_amicus.bmu
3) Change the .mp3 file to a .bmu. I use this utility: Click Here

EDITING DIALOG.TLK
1) Open the dialog.tlk directory of Neverwinter Nights in your install directory with a tlk editor, I use this one: Click Here You'll need to update your browser to Java 5 to use it.
3) Scroll to the bottom and find the last number used, in my tlk file that's currently 184757 but yours may be different. Click on EDIT -> RESIZE TABLE.
4) Add one to whatever number appears and hit 'ok.' This should create a blank line at the bottom.
5) In this line, type in the name of song as you want it to appear in your toolset. I put in Amicus Menus
6) Hit save. (Make sure your toolset is closed when you do this) You can exit now but remember the number of the row you typed the title in.

EDITING YOUR AMBIANTMUSIC.2da

1) Open up your toolset, at the very top is a menu item called VIEW. Click on VIEW and then 2DA FILEs...
2) A list of your 2DA files pops. Scroll down to the one called AMBIANTMUSIC and open it.
3) Scroll down to the last, unused row.
4) In the first column, place the number from the dialog.tlk file that you created earlier. In the second, place the name of the music file without the extension. So I would enter and 184758 in the first column and mod_mus_amicus in the second.
5) Hit the 'Save' button for this file. (It's the one near the 'Add Row' button)

I'd like to add a note to the above post. It gives instructions on how to do two things one should rarely do. First, it tells you to alter the dialog.tlk in your install directory. This is typically a bad idea as most patches will overwrite this. For the majority of your modifications, you should copy your dialog.tlk into your My Documents/Neverwinter Nights directory and edit that one. Secondly, it's typically best to add a new row to the bottom of a .2da file instead of overwriting padding, however, I found that caused an error with amdiantmusic.2da.

>>

There's also been talk concerning the issues with importing voice over and music files in 1.02 that are supposed to be addressed as of 1.03.

Anduraga's guide to adding a custom mountain placeable

Anduraga recently posted an excellent guide to creating a custom mountain placeable for use as a background element in a module on his blog. Here's a quick teaser:

We'll be creating a two-dimensional backdrop of a mountain for NWN2. This placeable will be no different than the Tree Cards in the toolset. Throughout this tutorial, I will be saying Photoshop and Max. If you're using a different program, then Once you have those programs (Photoshop and Max installed), we can finally begin making our textures.

Read the full post here:
http://thayviannights.blogspot.com/2008/12/from-image-to-nwn2-mountains....

It's a long post but a great read if you are interested in exploring custom placeables or need a specific placeable like this. Thanks Andurag!

Loading screen tips

WhoIsEvilTurnip posted this explanation of how to add custom tips to the loading screens:

I figured this out a day or two ago. There didn't seem to be anywhere it was actually written plainly.

First make a custom TLK. It should start with StrRef numbers 0, 1, 2, etc. Make it as long as you like with custom strings in each one.

Next, either make a new nwn2_tips.2da from scratch or copy the default one. If you copy the default one, go ahead and delete all of the lines except the first one.

I don't know why the nwn2_tips.2da has two "Row No." columns, but it works. Change the String for row 0 to reference 16777216, and set row 1 to reference 16777217, and so on, for as many random tips as you want.

Stick your custom TLK in your main NWN2 directory, the same one that the dialog.tlk is in.

You can put the nwn2_tips.2da in a custom hak if you like. I used TlkEdit to make my hak and put it in the My Documents\Neverwinter Nights 2\hak directory. Then go ahead and open your module in the toolset, and in the module properties, add your custom hak, and set your custom tlk as the one this module uses. Save the module, and try it out. When changing areas, your custom tips will appear! For some reason, when you are entering the module for the first time, the default tips show, but every area change after that brings up a custom tip from the custom tlk file.

Hope this helps. I looked for a long time for straightforward instructions for noobs on this subject before using trial and error to get it to work.

See the full thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=596848&forum=115 

Prestige Class Creation

ladydesire posted a great tutorial on how she made custom prestige classes for Waterdeep.

Check it out here:
http://nwcitadel.com/forums/showthread.php?t=1138

Also, you may get some benefit in Kaedrin's post where he was exploring this issue:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=596753&forum=115

 

Rogue Dao: Custom Terrain Types

Montgomery Markland over at Rogue Dao Studios has posted some great information concerning custom terrain types:

I've been playing around with terrain textures, learning about how to properly format them with all of the assorted miscellany that's required.

I didn't know a .dds from a dvd until a week ago, so take all of this information as an exploratory process. Also, feel free to add your own comments.

Read the full post here:
http://www.roguedao.com/phpBB2/viewtopic.php?p=1428#1428

TLK files

There is currently a stickied post the official forums concerning tlk files:

Current word from Obsidian programmer Erik Novales is:

Custom TLK support in the toolset will be in the next patch. In addition, specifying string refs as hex values in 2DAs will also work. This works similarly to how it did in NWN1 -- flipping the high bit on a string ref signifies usage of the module-specific TLK.

The talk tables are indeed UTF-8.

pfb files

These are prefab files. Place them in your overrides directory.

User Interface

Information for creating custom user dialogs.

Machinations: Change your name

BetterThanLife posted a tutorial concerning custom interface screens. This tutorial guides you through the creation of your own custom user interface screen for Neverwinter Nights 2. The screen is responsible for allowing the user to change their characters name. This is an illustrative example but you could easily extend it for a variety of other purposes. A sample module is included that allows you to ask a gnomish 'name changer' to change your name for you, this just shows one use of such a script and screen.

Download the zip file with the module showing how he did it from his site:
http://nwvault.ign.com/View.php?view=NWN2Tutorials.Detail&id=25

OEI: UI Customization blog posts

Rob McGinnis has been posting a series of posts in the Obsidian Entertainment NWN2 Developer Blog. There's a ton of information in there, and they seem to be posting one a week. Here is the link to the full category of posts:

http://forums.obsidianent.com/index.php?automodule=blog&blogid=2&&cat=7

And here are some of the topics included at the time of this writing, along with the basic introductions he included:

  • UIScene - The UIScene tag at the top of the XML files defines certain global parameters about the entire GUI window being defined in the file.
  • UIPane - UIPane is the generic 'container' for other UI Objects. Panes can't be rendered, but they can contain 'child' objects which can be renderable objects.
  • UIObject - UIObject is the 'base' GUI object. You can't actually define it in XML, but it contains attributes that are common to many different UI Objects, so I'm starting here.
  • Special Screens - Most XML files are loaded as default UI Scene, which implies no special behaviors. There are, however, several XML files that will get special handling in code and most conform to specific rules in order to even be loaded.
  • UIObject - hideoverride - In 1.05 there is a new attribute that all UI Objects handle called hideoverride. If true, this attribute sets a UI Object hidden and keeps it that way until a script says otherwise via the SetGuiObjectHidden() script function.
  • UIText - UIText is the GUI object used for containing and rendering text. It is one of the more complicated UI Objects to work with.
  • UIButton - UIButton is the generic, clickable object one expects to find on any PC game interface. It also acts as a 'restricted' container of sorts, as it can contain specific UI objects within it.
  • Multiple Callbacks Per Event - In 1.06, it will be possible to set up multiple GUI callbacks on a single UI event in XML. The syntax will be to use the event name and append a number to it. The engine will read in the callbacks until it fails to find the next sequential number.
  • Couple new GUI script functions for 1.06 - 1.06 will have a number of new script functions that will give improved control over custom GUIs. SetGUIProgressBarPosition(); and SetGUITexture();
  • New UI Callback Parameters - In 1.06, callbacks can take 2 new 'variable' parameters in addition to global:# and local:#.
  • UIObject_Misc_ExtractData - A new callback in 1.06 is: IObject_Misc_ExtractData( sourceobject, datatype, index, destinationvar )
  • UIObject_Input_ActionTargetScript - New in 1.06, will let you make 'GUI actions' similar to the 'actions' that are created when you click on a spell or feat button to cast it, or on a button in the DM Choser that then has you select a target to do the action to.
  • UI Listbox - UIListBox is a container similar to UIPane and anything listed under UIPane that makes sense for UIListBox probably does the same thing under UIListBox. So I'm going to stick to discussing the attributes that are unique to UIListBox. Refer to UIPane for the basic attributes (Like X, Y, Height, Width, etc).

 

Lists

Here are some useful lists for builders. As the chapters of the Resources for Builders book get better defined, these will be moved into more appropriate locations.

Complete Lootable Items Lists

McGavin has posted some complete lists of lootable items in the OC.

Complete List of Armors, Weapons and Miscelaneous Items that are lootables including unique and special edition weapons (NWN2 Campaign Plot Only Weapons are not included).

Head over to the vault to grab it.
http://nwvault.ign.com/View.php?view=NWN2Other.Detail&id=41

Patches

See the full list of patches for download at the vault:
http://nwvault.ign.com/View.php?view=NWN2Other.Detail&id=19

Shock Wolf has a good post about how to deal with the risk of updating here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=669984&forum=109

 

Patch 1.13

See the official 1.13 thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=643393&forum=1...

Fixes

Neverwinter Nights 2 Game Update 1.13
Patch Notes - June 2, 2008

Bug Fixes
---------------

General

  • The toolset and game now load hak files in the same order.
  • Skills such as Search will no longer broadcast multiple messages to the chat window while in use. A single message will be displayed when turning the skill on or off.

Multiplayer

  • The chat channel will no longer revert to Local when a player transitions to a new area or module.

DM Client

  • Fixed an issue where DMs would not receive messages on the DM channel if they were filtering out the shout channel.
  • The console command dm_setfaction will no longer cause crashes.

Toolset

  • The toolset and game now load hak files in the same order.
  • Fixed an issue where you could not tint multi-selected tiles.
  • Light spheres shall now display properly.
  • Sound spheres shall now display properly.
  • The creature cache in Area Properties shall now work as intended.

Scripting

  • The GetNextItemInInventory() script function should now work properly with stores.

Custom Content

  • The Skills.2da file will now accept up to 100 rows of data.

New Features
---------------
Multiplayer

  • The chat system now has a /r command for replying to the last private message a player receives. After receiving a private message, the player can enter "/r" into the chat system which will automatically address a private message to the person that sent the previous private message.
  • The ability to send a private message by right clicking on a character's portrait in the party bar has been added to the DM and player client.

Toolset

  • The ItemPropertyActivationPreference property for items is now accessible through scripting.

DM Client

  • DMs can now jump to object when right clicking on a portrait in the party bar.
  • DMs can now jump a player to the DM's location when right clicking on a portrait in the party bar.
  • DMs can now examine the character sheet of a player in the same area when right clicking on a portrait in the party bar.
  • DMs can now shift the alignment of a player in the same area when right clicking on a portrait in the party bar.
  • DMs can now toggle the invulnerability of a player in the same area when right clicking on a portrait in the party bar.
  • DMs can now force players to rest when right clicking on a portrait in the party bar.
  • DMs can now Give/Take gold to/from players when right clicking on a portrait in the party bar.
  • DMs can now Give/Take XP to/from players when right clicking on a portrait in the party bar.
  • DMs can now Give/Take levels to/from players when right clicking on a portrait in the party bar.
  • Character names will now display when you mouse over a character's portrait in the party bar.
  • The ability to send a private message by right clicking on a character's portrait in the party bar has been added to the DM and player client.

Scripting

  • A SetCollision(object oTarget, int bCollision) function has been made available. This will allow builders and DMs to turn the collision of a creature or placeable object on or off dynamically. This function is only useful on creatures/players/placeables that already have collision and will set collision to NONE if called on an object that never had collision in the first place.
  • A GetCollision(object oTarget) function has been added. This function will return the collision Boolean for an object.
  • The ItemPropertyActivationPreference property for items is now accessible through scripting.
  • A GetBicFileName function has been made available. This function will return the file name of a .bic file in a server vault.
  • New List Box functionality has been added to the game. This includes the following script commands:

o ClearListBox
o AddListBoxRow
o RemoveListBoxRow
o ModifyListBoxRow

  • A SetScrollBarRanges(object oPlayer, string sScreenName, string sScrollBarName, int nMinSize, int nMaxSize, int nMinValue, int nMaxValue) function has been added to the game. This function will allow you to set custom values to a scrollbar.
  • A SetFactionLeader(object oNewLeader) function has been added to the game. This allows you to set a companion to be the speaker in a conversation.
  • A GetFirstSubArea(object oArea, vector vPosition) function has been added to the game. This function lets you iterate over the ‘subareas’ at a given position in an area. A subarea would be a trigger, an encounter, or a AoEEffect.
  • A GetNextSubArea(object oArea) function has been added to the game.
  • A GetMovementRateFactor(object oCreature) function has been added to the game.
  • A SetMovementRateFactor(object oCreature, float fFactor) function has been added to the game. This function sets the creature's movement factor to that value. This movement factor is also modified by effects, encumberance, etc

 

Patch 1.21

This patch came out November 5, 2008 in conjunction with SoZ being released.

Issues

I've seen two major issues that affect builders:

Area OnEnter scripts not working

Seems like some builders were having problems with Area OnEnter scripts not firing correctly after they updated the game. Seems the problem tends to be an incorrect use of OnEnter instead of OnClientEnter.

From Rob McGinnis in this thread about OnEnter and 1.21:

The way OnEnter works is that it fires off before the client is fully loaded into the game. This means that when you call the OnEnter function to fire off a conversation or other script, such as giving an item to a character, it may seem like the scripts/conversation is not working, when in fact it is. It is just happening BEFORE the client enters the game fully.

We will not be changing this behavior because there are benefits to this, but we are looking for ways to make it so modders do not need to change their mods.

Moving forward, we suggest you use OnClientEnter as it should handle these things properly.

Speaker triggers not firing correctly

There also seems to be an additional issue where some speaker triggers are not firing correctly. In the same thread Rob suggests making sure the speaker field is set on the dialogs as opposed to leaving this as the default blank for OWNER. I'm unsure if this is a solve for the problem.

Discussion

See the official thread at:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=656414&forum=109

Neverwinter Nights 2 Game Update 1.21 Patch Notes

November 5, 2008

The following list contains the majority of fixes and features added in the 1.21 Game update. All spoilers for Storm of Zehir have been removed from this list.

Bug Fixes

General
* Item costs in the game should match the costs in the toolset.
* Party members that have wands with 0 charges will now attack and use spells normally.
* When dropping an item, characters will now use the appropriate "drop" animation.
* Fixed an issue with opening two bags at once. You will now only be able to open one bag.
*The tool tip for the Player Chat menu item will now say Player Chat.
* Fixed an issue that caused freecam (console command) to not work properly.
* Made several corrections to the Doomgude class description.
* Snake's Swiftness, Mass will now affect the entire party.
* Hellfire Shield should now play an appropriate sound effect when activated.
* Hellfire Blast should now play an appropriate sound when activated.
* The description of Hellfire Shield has been changed to appropriately reflect it is an Area of Effect shield.
* Weapon Focus: Warmace will now be available to all qualified characters.
* The ability score descriptions in character creation have been changed to be more informative and reflect changes to the game.
* Fixed an issue that was causing certain AI behavior feedback to be displayed, even after being deactivated.
* When the game is paused, a much more noticeable message is displayed.
* Aura of protection will no longer provide "No Stacking" feedback.

Toolset
* Item costs in the toolset should match the costs in game.
* Changing checkboxes with multiple objects selected will no longer cause the toolset to crash.
* Changing dropdown lists with multiple objects selected will no longer cause the toolset to crash.
* Fixed an issue where resizing a creature may not have resized the collision spheres.
* Fixed an issue where the creature cache was not working properly.
* Dropdowns generated from 2DAs will no longer start with the wrong row selected.
* Redesigned the fields associated with setting Tints to no longer be collapsed controls.
* Fixed an issue that caused light and sound spheres to not render at their proper size.
* Fixed an issue that caused ceiling tint changes to not show up in the toolset.

New Features

General
* Playable races now have a proper stealth animation.
* Added in the AI functionality from TonyK's AI.
* In a peer-to-peer multiplayer session, the hosting player may now unpause the game unconditionally.

Toolset
* Added properties associated with the overland map, including camera positioning and the flag to mark the area as an overland map.
* Added camera positioning functionality settings in the area properties to support overland maps created by the community.
* Added a flag in the area properties to set an area to be an overland map.
* Added Campaign flags for Unrestricting NPC level ups (Lets them chose any class at level up)
* Added Campaign flags for Conversation Distance limit override.
* Added Campaign flags to turn off party-control character swapping for dialogs on a global level.
* Added Campaign flags to enable Party Creation and setting what the size of the party should be.
* Added Campaign flags to toggle the new death system.

Scripting
* PlaySound() now takes an optional parameter: bPlayAs2D. This parameter will default to FALSE. Setting this parameter to TRUE will force the engine to play the sound you specified as a 2D sound rather than 3D Positional audio, regardless of what the engine would normally do before.
* BeginConversation() now has a parameter that allows you to block the character's 'Greeting' VO from playing.
* Added a script function SetScrollBarValue()
* Added a script function SetPause()
* Added a script function GetPause()

Additional items that will be int he patch, but are not listed int he patch notes are:

* Added in the authentication system to support the Adventure Pack system.

* Fixed issues that would cause the Arcane Scholar of Candlekeep to crash on transition if they had certain items or metamagic spells in the quickbar.

* Use Magic Device will no longer supersede a character's caster class or level, when that caster level is higher than the UMD skill.

* Fixed an issue that caused high level items to be used when a character had a single point in Use Magic Device.

Patch 1.22

Neverwinter Nights 2 Game Update 1.22 - December 19, 2008 

I've attempted to compile links, known issues, patch notes and 2da changes from the forums.

Official forum thread is here: http://nwn2forums.bioware.com/forums/viewtopic.html?topic=669454&forum=1...

Available on the vault here: http://nwvault.ign.com/View.php?view=NWN2Other.Detail&id=212

Known Issues

  • Hard core difficulty setting - AOE spells only hurt caster, not entire party. Some notes from this conversation: http://nwn2forums.bioware.com/forums/viewtopic.html?topic=669443&forum=109&sp=0
    • Tony K - I think the source of the problem is the switch from GetCurrentMaster to GetCurrentRealMaster. For companions GetCurrentRealMaster will now return the companion instead of the PC. GetCurrentMaster returns the PC. Companions are not friends of the PC, but their factions are the same. Similar results should also occur if you switch to another party member – PC is now the currently controlled party member, companion is the original PC.
    • Rob McGinnis - I have asked that this get looked at again.

      What has been presented to me is that party damage was supposed to be based on the PvP setting for an area, regardless of the difficulty setting.

      So, on hardcore difficulty, in most cases in NWN2 OC, your party will not take damage. However, on a PW, or in a module where areas are set to be full PvP, then the party will take damage.

      If there is a bug in all this, it will probably wait to be fixed in 1.23

  • ActionCastSpellAtLocation() function from spell.2da got changed parameters (noted by rpgplayer1). New parameter is added, nDomainLevel, but it's between 2 existing parameters.
    • Implication: Any script that uses ActionCastSpellAtLocation() function, and has more then 4 arguments will give unpredictable behavior.
    • Rob McGinnis - I am going to have a hotfix created for this. We don't expect that this issue will impact things too much, but there could be some wonky AI behavior (no comment).
  • Just to make sure... The triggers' OnEnter script on module/area load hasn't been fixed yet? (by Mazena86)
    • It is fixed. However the problem you experience may not be the same as what was reported.
  • Attempting to compile nx2_s0_hlfrblst.nss results in an error; it seems that EffectHellfireBlast() is no longer defined anywhere that the compiler can find it (by ladydesire).
    • rpgplayer1 - nx2_s0_hlfrblst is actually obsolete script, not used in the game by anything (there is no complied version in scrips_x2.zip either). EffectHellfireBlast isn't defined anywhere because such effect doesn't really exist in the code.
  • I got all excited about greater fang and jagged tooth working on the shapeshifted druids, but DENIED! (by DTHWSH)


Bug Fixes

General

  • Spell focus feats are no longer available for Warlocks during character creation or level-up
  • The class description of Stormlord has been changed to reflect the skills available.
  • Weapon switching has been enabled for enemies, but not party members.
  • Fixed an issue that allowed players to get the dinosaur companion for free.
  • The item &quotStone of Alarm&quot will now work as intended.
  • Yuan-ti Purebloods now gain Alertness and Blind-Fight instead of Snakeblood, per PnP rules. Race description has been altered accordingly.
  • The Flurry of Blows feat description has been altered to more accurately reflect which weapons can be used to gain the benefit of this feat.
  • The Default Swashbuckler package will no longer choose Luck of Heroes at level 1.
  • Familiars will always follow their masters, unless told to stand their ground.
  • Fixed an issue that caused the 2d/3d bias option setting to not save.
  • &quotAlchemist's Fire&quot will now add a damage bonus when applied to a weapon
  • The Eldritch Lore feat description has been revised to reflect that its use is automatic, not selected.

Toolset &amp Custom Content

  • Fixed an issue that was causing conversations to abort when no speaker is designated (the PC was designated as the speaker by default).
  • A single TLK file is now required for custom content and module building. It must have a TLK extension to be seen by the toolset and the game.
  • Two new module properties are available to designate a module as needing NX1 (Mast of the Betrayer), or NX2 (Storm of Zehir).

Scripting

  • DespawnRosterMember() will no longer cause a crash when used.

Multiplayer

  • Action queues will no longer be cleared when a player toggles hostile/friendly in the player list. (In process).

Spells

  • Animate Dead now randomly summons a 5 HD skeleton or zombie warrior.
  • Create Undead now randomly summons an 11 HD mummy, wraith, or ghast.
  • Create Greater Undead now randomly summons a 15 HD vampire fighter or warlock, but only for 1 round/level to prevent it from being too powerful.
  • The druid elemental wildshape form will now properly categorize the druid as an elemental.
  • The Polymorph spell's gargoyle form will now properly categorize the caster as a monstrous humanoid.
  • The Shapechange spell's nightwalker form will now properly categorize the caster as undead.
  • Aura of Glory will no longer apply Charisma bonus to party members
  • Cacophonic Burst: damage applied to first target won't be used when calculating damage to other targets (will roll damage separately for each target)
  • Cacophonic Burst: will be properly maximized if having caster level below 15 (will not do full 90 points of damage anymore)
  • Made adjustments to the number of enemies that Chain Lighting will affect.
  • Made adjustments to the number of enemies that Wail of the Banshee will affect.
  • Fixed Cloud of Bewilderment, so the Empower and Maximize metamagic abilities properly increase duration of effects on the target.
  • The constitution damage of the Cloudkill spell now stacks properly and can no longer be dispelled.
  • Color Spray: Blindness will no longer affect creatures immune to mind affecting spells.
  • Color Spray: Will no longer trigger a spell resistance check on caster in some situations.
  • Fixed Curse of Impending Blades (including Mass version), so it will check for spell resistance properly.
  • Fixed Delayed Blast Fireball, so only enemies can trigger explosion.
  • Fixed Doom, so saving throw isn't rolled if spell is blocked by spell resistance or immunity.
  • Fixed Extract Water Elemental, so only non-living creatures are immune to it (Constructs and Undead), and not everyone who has immunity to Death magic (just like Horrid Wilting).
  • Fire Storm is now capped properly at 20d6 damage.
  • Fixed Flame Weapon, so it doesn't cancel out spells or abilities that add non-fire elemental damage to the weapons.
  • Glyph of Warding spell will now check for spell resistance.
  • Glyph of Warding spell will now allow a Reflex save for half damage.
  • Glyph of Warding spell will now be properly affected by Empower or Maximize metamagic abilities.
  • Glyph of Warding spell will no longer affect creatures outside its area of effect (vfx_persistent.2da change).
  • Fixed Haste (including Warpriest version), so it can affect proper number of allies (enemies won't be counted anymore).
  • The Jagged Tooth spell will now work when used on magical beasts or dragons (Dragon Companion and Druid epic wildshape forms included). (Work in progress - does not affect dragon companions).
  • The Magic Fang spell will now work when used on magical beasts or dragons (Dragon Companion and Druid epic wildshape forms included).
  • The Greater Magic Fang spell, will now work when used on magical beasts or dragons (Dragon Companion and Druid epic wildshape forms included).
  • Critical hits from the Meteor Swarm spell will now double fire damage, not just blunt damage.
  • Creatures immune to critical hits will no longer receive doubled damage on critical hits from a Meteor Swarm spell.
  • Mind Fog will now properly check for spell resistance.
  • Remove Fear now properly removes shaken effects caused by fear auras.
  • Fixed Shades (Self), so that depleting damage reduction won't end its other effects.
  • Critical hits caused by the Shocking Grasp spell will now be calculated properly.
  • The Solipsism spell will now bypass paralysis immunity.
  • The Solipsism spell will no longer be removed by spells that cancel paralysis.
  • The Solipsism spell will be removed by Greater Restoration or the Mind Blank line of spells.
  • The visual effects of the Solipsism spell have been changed.
  • Stone Body, will no longer add electricity immunity, if same is already applied by the Stormlord class (prevents a bug with getting no immunity at all).
  • The Storm of Vengeance spell will now calculate damage for each affected creature.
  • The stun effect of the Storm of Vengeance spell is now removed properly if a target successfully saves.
  • The effects of the Swamp Lung spell will no longer stack.

Creature Abilities

  • Fixed the Angel Protective Aura used by Planetars and Solars, so it affects all his allies. Also, it will give proper +4 bonus to saves and AC.
  • Fixed Blindness/Deafness spell-like ability of Deep Gnome, so it has consistent save DC (always Cha based, with +4 racial modifier).
  • Fixed Dragon Breath for all Dragons (including companions), so that damage is rolled for each target, instead applying the same value to all targets.
  • Fixed Dragon Breath for Black Dragons, so it won't affect targets outside the &quotline of effect.&quot
  • The visual effect for the dragon companion's breath weapon will now display properly.
  • The dragon companion's breath weapon will now have a proper save DC.
  • The dragon companion's breath weapon damage output has been adjusted.
  • The damage caused by the fire genasi's Reach to the Blaze ability has been adjusted.


Class Abilities

  • Fixed Dragon Breath ability of Red Dragon Disciples, so that damage is rolled for each target, instead applying same value to all targets.
  • Fixed Favored Soul and Warpriest Haste ability, so it affects multiple targets correctly if targeted on caster himself.
  • Fixed the Warpriest Implacable Foe ability, so it will not trigger attacks from companions if allied NPCs get affected by it.

Neverwinter Nights 2 Campaign Fixes

  • Fixed an issue that was causing a crash when exiting the Sunken Flagon.
  • Fixed various conversation issues in the Skymirror area.
  • Storm of Zehir Campaign Fixes
  • Reduced the spawn rate and maximum number of encounters on the overland map.
  • The NPC Redfeyer will no longer simply sing in combat.
  • The difficulty of the Priory of the Depths puzzle has been adjusted.
  • Losing the deed to Parrum's Rock will no longer block quests.
  • Resolved an issue where the Team Rush feat would cause the game to crash on module transition.
  • Fixed an issue that caused Adreum to repeat his conversation.
  • Fixed various text and misspelling issues in conversations and quests.
  • Fixed a sequence issue with the &quotWrath of Umberlee&quot quest.
  • Fixed an issue that was causing the quantity of trade bars being carried to be misreported.
  • Fixed an issue that was causing the players' demise to be reported prematurely.
  • Fixed various issues with the Priory of the Depths puzzle.
  • Septimund has been made unkillable in Port Llast.
  • Fixed an issue that caused the undead to remain in Port Llast after you raise the army of the dead.
  • Fixed an issue that was causing certain conversations to be presented as cutscenes.
  • Players can now access rare resources stored in the warehouses.
  • Septimund should now have the proper level.
  • Fixed an issue with unlimited loot in some areas.
  • Fixed an issue that allowed the scrying orb to give unlimited XP.
  • Creature parts are no longer forced into the bounty bag and must be manually placed. This only applies to any new creature parts the player picks up. Existing parts in inventory still suffer under the old blueprints.
  • Fixed issues related to customizing a character's package in the party editor.
  • Fixed a sequence issue with the &quotPrice of a Song&quot quest. The quest will now update properly.
  • Chir's familiar will no longer be nameless.
  • The NPC Soraevora has been improved.
  • &quotShipwreck Survivor&quot epithet feat is now granted to all player-made characters.

SoZ Crafting

  • Sound effects have been added to crafting

Changed 2da files 

(Thanks Senalaya)

\2DA\classes.2da
\2DA\cls_feat_archer.2da
\2DA\cls_feat_arctr.2DA
\2DA\cls_feat_bard.2da
\2DA\cls_feat_cler.2da
\2DA\cls_feat_dradis.2da
\2DA\cls_feat_druid.2da
\2DA\cls_feat_eknight.2da
\2DA\cls_feat_harper.2da
\2DA\cls_feat_pal.2da
\2DA\cls_feat_palema.2da
\2DA\cls_feat_rang.2da
\2DA\cls_feat_sorc.2da
\2DA\cls_feat_wiz.2da
\2DA\cls_feat_wprst.2da
\2DA\des_crft_spells.2da
\2DA\feat.2da
\2DA\packages.2da
\2DA\polymorph.2da
\2DA\spells.2da
\2DA\vfx_persistent.2da
\2DA\visualeffects.2da
\2DA_X1\classes.2da
\2DA_X1\cls_feat_bard.2da
\2DA_X1\cls_feat_cler.2da
\2DA_X1\cls_feat_dradis.2da
\2DA_X1\cls_feat_druid.2da
\2DA_X1\cls_feat_eknight.2da
\2DA_X1\cls_feat_favored_soul.2da
\2DA_X1\cls_feat_harper.2da
\2DA_X1\cls_feat_pal.2da
\2DA_X1\cls_feat_palema.2da
\2DA_X1\cls_feat_rang.2da
\2DA_X1\cls_feat_sacredfist.2da
\2DA_X1\cls_feat_scholar.2da
\2DA_X1\cls_feat_sorc.2da
\2DA_X1\cls_feat_spiritshaman.2da
\2DA_X1\cls_feat_stormlord.2da
\2DA_X1\cls_feat_wprst.2da
\2DA_X1\feat.2da
\2DA_X1\iprp_spells.2da
\2DA_X1\packages.2da
\2DA_X1\polymorph.2da
\2DA_X1\spells.2da
\2DA_X1\vfx_persistent.2da
\2DA_X1\visualeffects.2da
\2DA_X2\classes.2da
\2DA_X2\cls_feat_doomguide.2da
\2DA_X2\des_crft_spells.2da
\2DA_X2\feat.2da
\2DA_X2\iprp_spells.2da
\2DA_X2\packages.2da
\2DA_X2\packftswash1.2da
\2DA_X2\race_feat_yuanti.2da
\2DA_X2\spells.2da
\2DA_X2\vfx_persistent.2da
\2DA_X2\visualeffects.2da
\GUI\chargen_appearance.xml
\GUI\chargen_appearancex1.xml
\GUI\chargen_appearancex2.xml
\GUI\noticewindow.xml
\GUI\playerlogin.xml
\GUI\playerloginx1.xml
\GUI\playerloginx2.xml

Patch 1.23 notes

As BeyondthePale pointed out on nwvault, the 1.23 patch notes were posted in this forum thread by Rob McGinnis. Apparently the patch is coming very soon. Here are the notes:

Bug Fixes

General

  • Fixed an issue that was causing the "Character has too many feats" error message to display when attempting to cross-class a level 5 Sorceror with a level of Cleric with the Earth or War domain.
  • Players can no longer remove the last living party member from the party.
  • Fixed an issue that was causing enemies to remain highlighted if they died while being highlighted.
  • Fixed crash on exit to Desktop when hak pak(s) are in use
  • Infinite items in stores should no longer lose focus after purchasing.
  • Fixed an issue that was causing creatures to show as "Effortless" when Show CR was enabled.

Toolset & Custom Content

  • The UI Atlas system has been removed so that UI objects that are not 1:1 will no longer appear blurred.
  • Hook points should now appear properly in the toolset.
  • Compile All Scripts now compiles campaign scripts too
  • Hovering over a property sheet value in the toolset will now correctly display any truncated text as a tooltip.
  • A more friendly message is displayed when plugins fail to load, telling the user which files are not loading in a single messagebox.
  • Fixed an issue with settings that was causing hook points to not display properly.
  • Fixed 'out of bounds' issues that were causing toolset crashes.

Scripting

  • Fixed the ActionCastSpellAtLocation() script so that the nDomainLevel parameter is in the right place.
  • SetCollision() has been changed to work with placeables. However it will only turn collision on if the blueprint for the object has collision already.
  • Removed the setmaterialtype limitation, which required you to limit materials to predefined GMATERIAL consts.
  • Fixed an issue where compiling all scripts would dump the .ncs files into the mod folder and would ignore the campaign folder.

Multiplayer

  • Fixed an issue that was causing servers to crash when a polymorphed character would attempt to transition.
  • Players possessing their familiars will no longer lock up when transitioned by a DM
  • The Missing File error message, when attempting to connect to a server, now reports the file that is missing.
  • When examining other players and creatures, CR will no longer be displayed twice.

Spells & Invocations

  • Warlock Invocations are now properly marked as somantic in the spells.2da file.
  • Fixed an issue that was causing you to damage your own party members, on Normal difficulty setting, with AOE spells.
  • Casting invisibility will now make the affected character silent, as well as invisible. There will no longer be an opaque appearance on invisible creatures, which should reduce confusion.
  • Concentration check for Warlock invocations is now DC10+DamageDealt+SpellLevel.
  • Fixed an issue that was causing Vampiric Regeneration to work intermittently.
  • Animal Trance has been fixed to allow for certain types of metamagic.
  • Hammer of the Gods has been fixed to allow for certain types of metamagic.
  • Animalistic Power has been fixed to allow for certain types of metamagic.
  • Blades of Fire has been fixed to allow for certain types of metamagic.
  • Bladeweave has been fixed to allow for certain types of metamagic.
  • Conviction has been fixed to allow for certain types of metamagic.
  • Living Undeath has been fixed to allow for certain types of metamagic.
  • Nightshield has been fixed to allow for certain types of metamagic.
  • Reduce Person has been fixed to allow for certain types of metamagic.
  • Reduce Animal has been fixed to allow for certain types of metamagic.
  • Greater Reduce Person has been fixed to allow for certain types of metamagic.
  • Mass Reduce Person has been fixed to allow for certain types of metamagic.
  • Arc of Lightning has been fixed to allow for certain types of metamagic.
  • Blood to Water has been fixed to allow for certain types of metamagic.
  • Castigate has been fixed to allow for certain types of metamagic.
  • Dehydrate has been fixed to allow for certain types of metamagic.
  • Healing Sting has been fixed to allow for certain types of metamagic.
  • Animal Trance will now make the proper spell resistance check.
  • Healing Sting will now make the proper spell resistance check.
  • Casting the spell Avasculate will now cause the caster to become visible.
  • Casting the spell Bestow Curse will now cause the caster to become visible.
  • Casting the spell Death Knell will now cause the caster to become visible.
  • Casting the spell Hypothermia will now cause the caster to become visible.
  • Casting the spell Moon Bolt will now cause the caster to become visible.
  • Casting the spell Swamp Lung will now cause the caster to become visible.
  • Casting the spell Deep Slumber will now cause the caster to become visible.
  • Casting the Curse of Despair Invocation will now cause the caster to become visible.
  • The Bestow Curse spell is now considered supernatural and may no longer be dispelled.
  • Blade Barrier will now be properly dispelled.
  • Blades of Fire now provides a benefit for two rounds.
  • Blood to Water will now properly check for spell resistance.
  • The Constitution damage caused by Blood to Water may no longer be dispelled.
  • The effects of the Camouflage and Mass Camouflage spells will no longer stack.
  • Mass Camouflage will now affect characters within a targeted area.
  • Castigate will now properly check for spell resistance.
  • Castigate will no longer affect creatures with the same alignment as the caster.
  • Gray Orcs will now be affected by the Charm Person spell.
  • Gray Orcs will now be affected by the Daze spell.
  • Gray Orcs will now be affected by the Dominate Person spell.
  • The Dehydrate spell will now properly check for spell resistance.
  • The Dehydrate spell will now be negated by a successful Fortitude save.
  • The Constitution damage caused by the Dehydrate spell will now stack.
  • The Constitution damage caused by the Dehydrate spell may no longer be dispelled.
  • The duration of the Deep Slumber spell has been reduced.
  • The Devour Magic invocation will now properly grant temporary hit points when an area effect is dispelled.
  • The Devour Magic invocation will no longer attempt to dispel temporary hitpoints granted by the use of devour magic.
  • Negative levels granted by the Enervation spell may no longer be dispelled.
  • The effects of Enlarge Person will no longer stack on a Duergar already affected by Entropic Husk.
  • The duration of the Flame Weapon spell has been reduced to one minute per level.
  • Fixed the duration of the Foundation of Stone spell to match its description.
  • Casting Lesser Visage of the Deity will no longer cause the caster to become visible.
  • Casting Greater Visage of the Deity will no longer cause the caster to become visible.
  • The gust of wind spell will no longer remove auras.
  • The Living Undeath spell will now impart a proper Charisma penalty.
  • Mass Blindness will now only effect enemies on hardcore difficulty setting.
  • Mass Deafness will now only effect enemies on hardcore difficulty setting.
  • Mass Curse of Impending Blades will now only effect enemies on hardcore difficulty setting.
  • Mass Reduce Person will no longer affect enemies.
  • Mass Reduce Person will no longer be canceled if there are non-humanoids in the area.
  • Nightshield will now provide the proper +3 bonus to saving throws for casters 9th level or higher.
  • Slay Living will no longer trigger a spell resistance check if the melee attack fails.
  • Tasha's Hideous Laughter will now be properly affected by dispel spells.
  • The Magic Fang spell has been changed from the Conjuration spell school to the Transmutation spell school.
  • The Greater Magic Fang spell has been changed from the Conjuration spell school to the Transmutation spell school.
  • The Mind Fog spell has been changed from the Illusion spell school to the Enchantment spell school.
  • The Shroud of Flame spell has been changed from the Transmutation spell school to the Evocation spell school.
  • The Bless Weapon spell can no longer be maximized.
  • The Death Armor spell can no longer be maximized.
  • The Elemental Shield spell can no longer be maximized.
  • The Flame Weapon spell can no longer be maximized.
  • The Heal Animal Companion spell can no longer be maximized.
  • The Mage Armor spell can no longer be maximized.
  • The Mass Snake Swiftness spell can no longer be maximized.
  • The Poison spell can no longer be maximized.
  • The Rejuvination spell can no longer be maximized.
  • The Cocoon spell can no longer be maximized.
  • The Tortoise Shell spell can no longer be maximized.
  • The Creeping Cold spell can no longer be extended or made persistent.
  • The Greater Creeping Cold spell can no longer be extended or made persistent.
  • The Cause Fear spell can no longer be made persistent.
  • The Lesser Dispel spell can now be made silent.
  • The Scare spell can now be made silent.
  • The Greater Resistance spell can now be cast with Still metamagic.
  • The Superior Resistance spell can now be cast with Still metamagic.
  • Fixed various issues that prevented the use of certain metamagic feats with the Animal Trance spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Animalistic Power spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Arc of Lightning spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Blades of Fire spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Bladeweave spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Blood to Water spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Castigate spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Conviction spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Dehydrate spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Healing Sting spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Living Undeath spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Nightshield spell.
  • Fixed various issues that prevented the use of certain metamagic feats with the Stabilize spell.
  • The Blindness spell will no longer have a somatic component.
  • The Deafness spell will no longer have a somatic component.
  • Changed the range for the Crushing Despair spell from medium to short.
  • Fixed an issue with Lesser Planar Binding that was preventing its use on hostile outsiders in SoZ.
  • Fixed an issue with Planar Binding that was preventing its use on hostile outsiders in SoZ.
  • The Castigate spell will now properly be centered on the caster.
  • Fixed an issue that was preventing Mordenkainen's Disjunction from targeting enemies.

Feats

  • Increased the duration of Divine Might and Divine Vengeance feats for one round, to compensate for inability to attack in same round when those abilities are activated
  • Fixed the Divine Vengeance bonus, so it gives extra 2d6 damage against undead, and not some random value between 2-12
  • AI Controlled characters with the Two-Weapon Fighting feat will no longer unequip off-hand weapons.

Racial Abilities

  • Fixed Cause Fear, Charm Person and Entangle spell-like abilities of Yuan-Ti Purebloods, so that duration and DC are not based on first class taken at character creation. Instead, as per PnP rules, DC is Charisma based and duration depends from total character level.
  • Fixed the aura used by Drowned undead, so it does not affect creatures with Iron Body, which gives immunity to drowning.
  • Fixed the Howl of Fear ability used by Shadow Mastiffs, so it will no longer affect the casting creature when part of the player's faction on Hardcore difficulty.
  • Fixed the Summon Gale ability of Air Genasi, so it will not remove auras from other creatures anymore.

Class Abilities

Bard

  • Fixed an issue that was causing the Chorus of Heroism to not work properly when used by NPC AI.
  • Fixed an issue with Legionnaire's March Song so the increased attack bonus is calculated properly.

Cleric

  • Turn Undead will no longer include previously turned outsiders in the Hit dice calculation for new turning attempts.
  • The 'Turning Failed' message will no longer display for a creature that cannot be turned.

Druid

  • Fixed an issue that was causing the game to crash if a druid, with a sling attached, casts Elemental Shape > Air.

Neverwinter Nine

  • The duration of the Furious Assault ability has been increased by one round.
  • Fixed an issue with Guarding the Lord so that its duration is now properly based on the character's level.
  • Fixed an issue that was preventing the concurrent use of a persistent aura from multiple creatues and characters of the same type, in the same area.
  • Fixed an issue that was causing icons for persistent aura effects to not display properly.

Paladin

  • Fixed an issue that was preventing the concurrent use of a persistent aura from multiple creatues and characters of the same type, in the same area.
  • Fixed an issue that was causing icons for persistent aura effects to not display properly.

Ranger

  • Ranger abilities will no longer be disabled when equipping mithral chainmail armor.

Blackguard

  • Fixed an issue that was preventing the concurrent use of a persistent aura from multiple creatues and characters of the same type, in the same area.
  • Fixed an issue that was causing icons for persistent aura effects to not display properly.

Doomguide

  • Fixed an issue that was preventing the concurrent use of a persistent aura from multiple creatues and characters of the same type, in the same area.
  • Fixed an issue that was causing icons for persistent aura effects to not display properly.

Hellfire Warlock

  • Fixed an issue that was preventing the concurrent use of a persistent aura from multiple creatues and characters of the same type, in the same area.
  • Fixed an issue that was causing icons for persistent aura effects to not display properly.

Warlock

  • Imbue item will now properly substitute for any spell needed in SoZ Crafting.

Warpriest

  • Fixed an issue that was preventing the concurrent use of a persistent aura from multiple creatues and characters of the same type, in the same area.
  • Fixed an issue that was causing icons for persistent aura effects to not display properly.

Items

  • Improved versions of Alchemist's Fire will now provide the correct damage bonus when applied to weapons.
  • Fixed an issue with electrical traps that was causing neutral creatures to be affected by the secondary damage.
  • Electrical trap damage will now arc to other creatures when the trap is set with the Set Trap skill.
  • Fatal sonic traps will no longer damage neutral faction creatures.
  • Epic sonic traps will no longer damage neutral faction creatures.
  • Fixed an issue that was causing gas traps to apply poison twice to the same target.
  • Fixed an issue that was preventing gas traps from damaging enemies when placed with the Set Trap skill.

New Features

General

  • New client command line option: -home. Allows user to specify an alternative location to "My Documents\Neverwinter Nights 2"
  • New INI file option "Pause On Lose Focus". A setting of 1 will cause the game to pause when losing focus. A setting of 0 will not pause the game when it loses focus.

Multiplayer

  • New server ini option: HideChallengeRatingInExamine
  • New server ini option: HideEffectListInExamine
  • Files located in the C:\Users\<username>\Documents\Neverwinter Nights 2\hak (Vista) and in the C:\Documents and Settings\<username>\My Documents\Neverwinter Nights 2\hak directories will now load prior to character creation.
  • Added support for Server to Server transitions through the function ActivatePortal() - Currently the parameter for seemless transition must be set to TRUE
  • A new .ini option has been added to allow server admins (hosts) to toggle the auto-heal feature on or off for player login. With the feature turned off, when a player rejoins a server, they will be in the same condition as when they logged off (HP, Spells per day, etc.).
  • A new Content Autodownloader system has been added to Neverwinter Nights 2 Multiplayer. It is designed to be used with the dedicated server. Changes have been made to the Dedicated Server, Game Client and Toolset to accommodate this new feature. Two documents, Autodownloader Server Admin Guide.pdf and Autodownloader Toolset User Guide.pdf, can be downloaded separately.
  • Server admins now have the ability, as an option, to preempt the use of the override folder on clients
  • New server command line option: -home. Allows user to specify an alternative location to "My Documents\Neverwinter Nights 2"
  • New server command line option: -cs 0/1 <- turn off/on downloader (defaults to no downloader behavior)
  • New server command line option: -du 0/1 <- turn off/on custom UI on the client (defaults to allow custom UI)
  • New server command line option: -do 0/1 <- turn off/on override folders on the client (defaults to allow override)

Scripting

  • Added script function int GetVariableValueInt(object oObject, int nIndex); Get the value of a local int stored at the index provided. 0 if no var is present.
  • Added script function string GetVariableValueString(object oObject, int nIndex); Get the value of a local string stored at the index provided, empty string if no var is present there.
  • Added script function float GetVariableValueFloat(object oObject, int nIndex); Get the value of a local float stored at the index provided. 0.00 if no var is present there.
  • Added script function location GetVariableValueLocation(object oObject, int nIndex); Get the value of a local location stored at the index provided. Invalid location no var is present there.
  • Added script function object GetVariableValueObject(object oObject, int nIndex); Get the value of a local object stored at the index provided. OBJECT_INVALID if no var is present there.
  • Added script function int GetVariableCount(object oObject); Get the number of local variables stored on this object.
  • Added script function void SetBaseAbilityScore(object oCreature, int nAbilityType, int nScore); EXPERIMENTAL! Note that any changes to skill rank will NOT be lost if the character is de-leveled. IMPORTANT: Most usages of this will cause characters to fail 'enforce legal character' restrictions.
  • Added script function void SetBaseSkillRank(object oCreature, int nSkill, int nRank, int bTrackWithLevel = TRUE); EXPERIMENTAL! set bTrackWithLevel = TRUE if you wish for the skill change to be associated with the character's level. In other words, should the character lose the skill change if they lose their current level? IMPORTANT: Most usages of this will cause characters to fail 'enforce legal character' restrictions.
  • Added script function void SendChatMessage(object oSender, object oReceiver, int nChannel, string sMessage, int bInvokeCallback = FALSE); This function is used to send a chat message, as if spoken by a PC or by the server. Except for 'CHAT_MODE_SERVER', oSender must be a PC or nothing will occur. oSpeaker - the PC who will speak, OBJECT_INVALID if channel is CHAT_MODE_SERVER. This must be a valid PC object for CHAT_MODE_PARTY to work. oReceiver - if nChannel is CHAT_MODE_TELL or CHAT_MODE_SERVER, then this must be the PC who will be receiving the message. nMode - CHAT_MODE const indicating the type of message to be sent. Only the CHAT_MODE_* values provided are accepted. sMessage - actual message text bInvokeCallback = the module's nChat script will be invoked to filter this message, if this is TRUE. WARNING: use extreme caution if setting bInvokeCallback to TRUE from within the OnChat handler itself -- this could lead to an infinite loop and hang your module!
  • Added script function int GetIsLocationValid(location lLocation); Returns TRUE if the location is a valid, walkable location.
  • Added script function int GetSurfaceMaterialsAtLocation(location lLocation); Returns a bitmask composed of 0 or more SM_* values.
  • Added script function int GetSpellKnown(object oCreature, int nSpell); EXPERIMENTAL! Returns if the spell is known to this creature under any class or level.
  • Added script function int GetItemBaseMaterialType(object oItem); returns the GMATERIAL_* const to get the base material type of the item specified. At this time, only the pre-defineid base material types work.
  • Added script function void SetItemBaseMaterialType(object oItem, int nMaterialType); EXPERIMENTAL! Set the base material type of oItem to nmaterialType, which must be a valid GMATERIAL_* const value.Added instant feat support. New column "Instant" in feats.2da
  • GetClassLevelByPosition and related script functions will now recognize custom classes. (This also applies for anything internally that performs calculations based on class level, and in particular should correct custom classes not being used in spell caster level calculations. )
  • New script function: void SetGlobalGUIVariable( object oPlayer, int nVarIndex, string sVarValue ); Sets global GUI variable, available to all UI screens as global:x. globals can be used in most places that locals can be used. This can also be used to work with the new UI callback UIRadialNode_OnInit_TestGlobalVar, which allows you to display/hide radial nodes based on global variable values. This value is available to all screens. oPlayer - player whose GUI will have the variable. nVarIndex - variable index, from 100 - 400 (values outside of this range will be ignored). sVarValue - the value to set.
  • Added support for reading texture and terrain 2da files from hak packs.
  • Added script function int FindSubString(string sString, string sSubString, int nStart = 0); // modified to add nStart
  • Added script function void SetSpellKnown(object oCreature, int nClassPosition, int nSpell, int bKnown = TRUE, int bTrackWithLevel = TRUE);
  • Added script function object GetLimboCreatureCount(object oCreature);
  • Added script function object GetCreatureInLimbo(int nTh);
  • Added script function void SendCreatureToLimbo(object oCreature);
  • Added script function void SetSkillPointsRemaining(object oPC, int nPoints);
  • Added script function int GetSkillPointsRemaining(object oPC);
  • Added script function int GetSpellSchool(object oPC, int nClassSeq);
  • Added script function void SetGender(object oCreature, int nGender);
  • Added script function void SetTag(object oObject, string sNewTag);
  • Added script function int GetArmorRulesType(object oItem);
  • Added script function void SetArmorRulesType(object oItem, int nType);
  • Added script function void SetItemIcon(object oItem, int nIcon);
  • Added script function object GetObjectByTagAndType(string sTag, int nObjectType, int nTh);
  • The following new script functions work together as a group:
  • void AddScriptParameterInt(int nParam);
  • void AddScriptParameterString(string sParam);
  • void AddScriptParameterFloat(float fParam);
  • void AddScriptParameterObject(object oParam);
  • int ExecuteScriptEnhanced(string sScript, object oTarget);
  • int ClearScriptParams();

Toolset & Custom Content

  • A new Content Autodownloader system has been added to Neverwinter Nights 2 Multiplayer. It is designed to be used with the dedicated server. Changes have been made to the Dedicated Server, Game Client and Toolset to accommodate this new feature. Two documents, Autodownloader Server Admin Guide.pdf and Autodownloader Toolset User Guide.pdf, can be downloaded separately.
  • Files located in the C:\Users\<username>\Documents\Neverwinter Nights 2\hak (Vista) or in the C:\Documents and Settings\<username>\My Documents\Neverwinter Nights 2\hak (WinXP) directories will now load prior to character creation.

User Interface

  • UIObject_Misc_ExecuteServerScript no longer truncates data that contains apostrophes
  • There is now a Close option on transition doors for players. (Used to be that if a door was a transition, they could only use it - not close it.)
  • New UI callback: UIRadialNode_OnInit_TestGlobalVar(global-index,test-type,rvalue, action)
    • This UI callback allows modders to control when menu nodes are hidden or displayed, based on the results of comparing a global UI variable against a specified value. All tests are performed as int values if both values are valid ints; otherwise they're perform as case-insensitive string comparisons.
    • Parameters are as follows
      • global-index: global var index in format of global:x
      • test-type: test to perform (all tests are done as as int if both values are int, else as case-insensitive strings)
        • EQ = two values are equal
        • NEQ = two values are not equal
        • LT = global value is less than the comparision value
        • LTE = global value is less than or equal to the comparison value
        • GT = global value is greater than the comparison value
        • GTE = global value is greater than or equal to the comparison value
      • rvalue: a constant value that you are comparing the global variable to.
      • action: SHOW or HIDE.
        • The menu node will be displayed or hidden based on the value given:
          • if the expression evaluates true and the action is SHOW, then the node will be shown
          • if the expression evaluates false and the action is SHOW, then the node will be hidden
          • if the expression evaluates true and the action is HIDE, then the node will be hidden
          • if the expression evaluates false and the action is HIDE, then the node will be shown

2DA File Changes

Neverwinter Nights 2

  • Added Henchspells.2da
  • Spells.2da - Various spell changes
  • Feat.2da - added an "Instant" column.

Neverwinter Nights 2: Mask of the Betrayer

  • Added Henchspells.2da
  • Spells.2da - Various spell changes
  • Feat.2da - added an "Instant" column.

Neverwinter Nights 2: Storm of Zehir

  • Spells.2da - Various spell changes
  • Feat.2da - added an "Instant" column.

Recipes, all of them

ImmortalPob posted a list of crafting recipes in the OC form.

Because I had way too much time on my hands I have copied and pasted the descriptions from all of the crafting books, merged the, removed duplicates, and broken them down by type.

Check it out in the forum, and watch out for the 25+ pages of discussion afterwards:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=511016&forum=110

Thieves Guild: Resources for SoZ

Sir Chet recently announced a few helpful resources over at thieves-guild.net that will be useful for NWN2: SoZ modules.

I just wanted to let everyone in on what we've done over at The Thieves Guild.

We finally finished our Walk-through for SoZ. I've also listed a few very helpful links to other great resources for OEI's second expansion to NWN2.

I hope y'all find these guides useful.

Thanks SirChet!

Links

Here you can find links to other sites concerning nwn2. If you have a link that you would like to be here, let me know using the contact form, or consider becoming a contributor.

Additional Resources for builders

Here are some great additional sites meant for builders.

http://www.nwn2toolset.dayjo.org/
Neverwinter Nights 2 Toolset Site

http://www.nwscript.com/
Neverwinter Nights 2 scripting tutorials

http://www.nwn2mods.com/
NWN2 Mods - prefabs and modules

http://www.nwnwiki.org/Neverwinter_Script_directory
Searchable collection of Neverwinter Nights Scripts.

http://www.nwcitadel.com/forums/forumdisplay.php?f=77
The Forgotten Realms Weave: "A project by SP/MP module designers to create a series of interconnectable modules that all support the major canon of the Forgotten Realms and allow cross module compatibility for players of the modules."

http://www.forgottenrealmsweave.org/wiki/tiki-index.php
The Forgotten Realms Weave wiki site

http://forgottenrealms.wikia.com/wiki/Main_Page
The Forgotten Realms wiki

http://en.wikipedia.org/wiki/Forgotten_Realms
Wikipedia entry on the Forgotten Realms

http://www.systemreferencedocuments.org/35/sovelior_sage/home.html
d20 System Reference Document v3.5: Open Source documentation of the 3.5 d20 rules. Contains a quick reference of all rules that end up in the PNP rule books.

 

Forums

Here are a number of links to forums with useful information concerning the Toolset.

http://nwn2forums.bioware.com/forums/viewforum.html?forum=113
The official NWN2 Toolset forum.

http://www.dladventures.net/vB/forumdisplay.php?f=87
The DLA Toolset Forum.

http://www.nwn2.pwp.blueyonder.co.uk/index.html
The Neverwinter Nights 2 Toolset Site forum.

http://www.roguedao.com/phpBB2/index.php
Rogue Dao Studios forum index

http://www.nwn2mods.com/forums/index.php?s=e6766d6b4858155332909a2862d8c...
NWN2 Mods forum

General information about nwn2

Here are a number of links concerning nwn2:

http://www.nwn2.com
The official site.

http://nwn2forums.bioware.com/forums/index.html
The nwn2 forums.

http://nwvault.ign.com
The vault.

http://nwn2.warcry.com/
NWN2 WarCry

http://nwn.stratics.com/
NWN2 Stratics

http://www.nwn2hq.com/
NWN2 news and updates

http://www.thieves-guild.net/
ThievesGuild.net

Project Websites

Here are some notable sites and blogs of nwn2 module authors.

http://adamandjamie.com/nwn2/
Adam Miller's Dark Water nwn2 site.

http://www.roguedao.com/PlanescapeTrilogy.html
Rogue Dao Studios' Planescape Trilogy

http://www.forgottenrealmsweave.org/wiki/tiki-index.php
The Forgotten Realms Weave wiki: "To allow builders to create coordinated campaigns set in the Forgotten Realms while retaining a high level of autonomy for their individual projects."

http://www.nwcitadel.com/blog/index.php?blogId=5
The Rusty Spike
Jaks design diary of sorts for his upcoming NWN2 DM led campaign.

Bringing it all to life

Information on pulling it all together to create a great experience. Generally, this section is all about what makes a good game and how you can apply that to your NWN2 module.

Choice vs. Linear Plot in CRPGs

anobody posted a complaint about the linear aspect of the NWN2 OC on the boards, which spawned an interesting debate about the linear aspects of Computer Role Playing Games.

BW022 made some good points with his post:

In the game all modules and pre-written campaigns have predetermined plot arcs. It simply isn't possible to write a module which covers every conceivable choose.

Imagine a DM writes a module for her group. About twelve hours consisting of a small town, a murder, and an assassin's complex. Maps, stat blocks, NPC descriptions, etc. The module starts out with a gnome coming into the bar and asking to speak with the PCs.

What do you think happens if the PCs say "We kill the gnome."? Well, maybe the DM scrambles a bit and lets the PCs find a note on the gnome talking about a murder. What then happens if the PCs say "We burn the note and leave the village."

Eventually the DM will say, "Fine. Nothing happens." She no longer has anything prepared. Perhaps the DM is good enough to ask what you plan on doing and then writing a specific adventure for you next week. Is the DM supposed to repeatedly spend dozens of hours on stuff you never do?

Kale Kross made an interesting counter point (which really highlights the importance of a DM):

The best DMs (and I've had the privilege of playing with several like this) don't run their sessions by planning out everything that could happen in a module. Rather, they construct their world and retain a clear picture of it and its inhabitents in their minds. They add some more major NPCs who will have their own agendas within the world as well. Naturally and fluidly, the world will continue to operate, even if the PCs decide to sit on their butts in the local tavern and do nothing. The DM creates a sort of "ecology" that is self-sustaining.

Actions the PCs take as well can have ripple effects within the world. The DM does not have to plan entire adventures or even sesssion. Only a continued sense of what is going on in the world and what will happen is necessary (with a few add-ons as the DM sees fit to throw into his/her world).
Using only these guidelines, the best DMs can do it all on the fly, allowing for true freeform roleplaying and stories that go in any direction.

In this sense, planning a whole quest isn't what's really required. Just planning of the world itself and the NPCs. It's the DM's choice to have an overarcing connection between sessions, but sometimes it's just fun to play for the journey of it.
While adventurers can be heros, not all adventurers are. And the reason we play is for the journey of it all anyway, not to "reach the end." After all, that's why DnD can be freeform and neverending in the first place, so long as the DM keeps it going.

Check out the full thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=526710&forum=1...

Creating a Villain

SCARLETTHORN posted this article about villains over at the Citadel. This first appeared in issue #23 of The Orc.

(Author unknown)

Speculative Fiction is a genre full of villains, from the truly evil ones like The Big Bad Wolf or Tolkein's Dark Lord, through the deranged ones like Misery's Annie Wilkes or Batman's Harley Quinn, to the tragic ones like Darth Vader or Magneto.

In this article I'll attempt to review a few points and tips that should be taken into consideration when creating such an antagonist for an ongoing campaign, an antagonist that would be a little more interesting than a bored dragon lying on his pile of gold, waiting for a group of hardy adventurers to come and turn him into an impressive collection of breast plates.

Like any other issue to be addressed in roleplaying, or at all, for that matter, before asking yourself "how?", you must first ask yourself "what?". Before we start designing our villain, we must first define what exactly we are attempting to create. Is he going to be an ongoing villain, forever lurking in the shadows of our campaign, or just a local antagonist for a single scenario? The villain's powers and motives, his interaction with the characters and the influence he'll have on them and the rest of the campaign will all derive from the answer to this simple question.

Once we've understood the role we want our villain to take, we can move on to creating the villain himself. The first question we should ask ourselves is why he's doing what he's doing, or in other words, what is his motive. Only a handful of villains are truly evil, and they can usually be found only in one of two genres - epic fantasy and horror. Most villains of most campaigns will be driven be much more earthly motives, such as an unquenchable thirst for riches or power (and a complete disregard to the welfare of those who stand in their way), revenge or even an ideological or political agenda which places the characters on the wrong side.

Another issue directly connected to the two previous ones is the relationship between the villain to the characters. Generally speaking, all villains can be roughly divided into two categories - those related to the characters' past, and those who aren't.

The first type of villain is the classic comic-book villain, the villain whose entire existence as a villain, or perhaps even whose entire existence is focused on the characters and on taking his vengeance on them and undoing their efforts. There's nothing wrong with creating such a villain, but in doing so, be careful to avoid the two classical mistakes of over-focusing on one character and of over-using the related villain motif. The first mistake is creating a villain opposing a single character, for a specific reason concerning that character alone, and not the other members of the group. It is possible to create such a villain, but be careful not to draw the campaign's focus to a certain character and not to steal the other characters' spotlight. The second mistake is self explanatory. There's nothing wrong with creating a villain who embarked on his evil career after a past confrontation with the characters, but if every kid who lost a tic-tac-toe game to one of the characters when he was in third grade will later return as a powerful villain - you're doing something wrong.

The other type of villain is the distant and faceless villain, existing only to serve his own cause. He isn't interested in the characters and does not actively seek to defeat or harm them - he simply wants to get them out of his way so they stop interfering in his plans. Or, as General Bison, a mediocre villain in a mediocre movie, once put it: "For you, the day Bison graced your village was the most important day of your life. But for me... it was Tuesday".

Another issue to address is the villain's powers. In order for our villain to be interesting, he must be able to defeat the characters. In other words, for a villain to be interesting, he must have some distinct advantage over the characters. But before you open your Dungeon Muster's Guide or Keeper's Companion and start searching it for interesting spells, formidable magic items and witty catch-phrases, stop and think. Any major villain will physically confront the characters only when all other options are exhausted, usually at the end of a lengthily campaign.

A real villain will lurk in the shadows and attempt to harm the characters in a variety of indirect methods - from various spells and curses that will make the character grow a rat's tail or develop an acute allergy to carrot juice to dirty politics that could cause the characters an insurmountable amount of trouble, from harassment by various law-enforcement agencies, through shop owners refusing to do business with the characters to closing down the characters' favorite tavern. Use your imagination and try to think of different and unique ways to empower your villain. Like any other subject in roleplaying games, there are no "rights" or "wrongs" here - even a close friendship with one of the characters' romantic interest could be considered as an advantage the villain has over that character.

One last issue to think about is the way you use the villain. If every scenario would start with the villain attempting to destroy the characters and would end with the characters defeating the villain, you're well on the way to a glorious yawn-fest. To ensure that your villain remains effective, he must be allowed to hurt the characters in a manner that is noticeable, but not fatal. Destroying valuable equipment, impairing abilities or abducting friends and allies are all great ways to remind the characters that the villain is still there, lurking in the shadows, waiting for an opportunity to strike. And of course, not every scenario needs to revolve around that villain. Even the most vicious villains are allowed to sit out a scenario or two, just to return to the hassle the characters at the least convenient time.

Creating an installer

PIPBoy3000 posted something a while ago about how to create a self-extracting installer. He even posted the script he used for Pirate Cards.

Check it out:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=534921&forum=115

Download the NSIS here:
http://nsis.sourceforge.net/Download

Once you have it installed, copy his script to a txt file, change the extension to nsi, and update it to reference your project and files instead. Drag and drop it into the compiler window and it will do everything for you.

Drow

For those of you wanted to use Drow and looking to give your NPCs a bit more life, here are some resources:

Descent Into Darkness {Drow Campaign resources set in the Forgotten Realms}.
http://drowcampaign.roleplaynexus.com/

Eilistraee’s Drow Translator
http://www.eilistraee.com/chosen/language.php

The Realm's of Otara: Drow Names
http://www.angelfire.com/rpg2/vortexshadow/drownames.html

Most of these were posted in this language thread over at the Citadel:
http://nwcitadel.forgottenrealmsweave.org/showthread.php?t=634

 

Elysius: Story Writing

Frank Perez, aka Elysius, recently posted four articles on how to write a story for NWN. You can see all four posts here:

Story Writing, Part 1: Storming the Brain

To decide on our story premise (in other words, the general idea of what the story is about), Dirtywick, Anduraga, and I agreed to hold a brainstorming session. We gave ourselves twenty minutes to generate as many ideas as we could, during which no idea would be criticized. We allowed ourselves to suggest any idea, even those that were deliberately silly, in the hope that these may lead to better ones. Afterward, we voted on three of the ideas that we liked best. We then picked the idea that was chosen by most of us.
> Read more

Story Writing, Part 2: The Plot Thickens

I once wrote in this blog that regardless of a story’s length, I find it useful to structure its plot as a three-act outline. In fact, I have a specific formula for how the acts are written.

Act 1. The hero (that is, the PC) becomes aware of a problem to be resolved.

Act 2. The hero tries to attain an objective, to which a strong antagonist is opposed. At this point, the hero gets a complication that makes it more difficult to attain the objective.

Act 3. It seems that the hero has no chance to defeat the antagonist. Nevertheless, the hero can still prevail, but only with the help of one or more third parties that tip the balance in the hero's favor.

> Read more

Story Writing, Part 3: Little Computer People

Entire books have been written on developing fictional characters, but I won’t even begin to touch the surface of this topic. Instead, I’ll provide only a couple of tips on character design. Don’t be misled by this seemingly meager offering, however. When applied properly, these tips will add considerable depth to any character concept.

Here’s my advice to beginning writers on how to create characters:

1. Write a back story for each significant character with a focus on the emotional problems that the character faces, how and why these emotional problems came to be, and what it would take for the character to resolve them.

2. Put your characters in situations that force them to confront their emotional problems in a way that will advance the story.

> Read more

Story Writing, Last Remarks: Where to Go from Here

It helps to read a lot of fiction with an eye toward studying what the authors did that makes their work effective. Even if you aspire to write exclusively in the science fiction or fantasy genre, include a lot of mainstream fiction in your diet of books. My favorite novels include Bel Canto by Ann Patchett, Life of Pi by Yann Martel, Shella by Andrew Vachss, The Name of the Rose by Umberto Eco, The Last Samurai by Helen DeWitt (not to be confused with the movie of the same name), and Wuthering Heights by Emily Brontë (a surprisingly brutal novel from a 19th century country girl). In the fantasy and science fiction genre, my favorite books include Lord of the Rings by J.R.R. Tolkien and American Gods by Neil Gaiman. Doubtless, you’ll have your own list of favorite books. One can learn much by studying the works of the writers you admire.

Reading will not get aspiring writers anywhere unless they set themselves working on their own fiction. Don’t worry if your first stories are amateurish. Even the masters started with baby steps on their path to greatness. They got better with practice, and you can too. So dust off your favorite game toolset and start making the interactive stories that you’ve been wanting to write.
> Read more

Frank Perez is the creator of the NWN2 module "Battle of the Builds" and is currently working on his next module called "Faithless." See more at his blog: Faithless: The Making of an NWN2 Module.

Estimating how long it will take

Kulharin posted a good question in the official forums: On average, how long does it take to create an average module.

I was curious. I don't know a heck of a lot about the toolset beyond the basics... But I think I am interesting in creating an average sized module with a few areas. maybe a town or two, a few outdoor areas and a few dungeons ... With a bit of custom 2DA content and monsters .... How long roughly would it take to create a basicly average module.

Rob McGinnis was kind enough to give a quick answer based on their experiences:

For the layout of areas (art only, including props)

Exteriors:
Tiny - 3 days (24 hours)
Small - 5 days (40 hours)
Medium - 8 days (64 hours)
Large - 15 days (120 hours)

Interiors:
Tiny - 1 day (8 hours)
Small - 2 days (16 hours)
Medium - 4 days (32 hours)
Large - 6 days (48 hours)

For Design (writing the story, working out encounters), here are our numbers for Mask of The Betrayer.

Module A (The Barrow)
Avg. Gameplay (minutes) - 75
Implementation Time - 59 man days
# Tiny Areas - 0
# Small Areas - 3
# Medium Areas - 2
# Large Areas - 0
# Designers - 1

Module B (Mulsantir)
Avg. Gameplay (minutes) - 240
Implementation Time - 112 man days
# Tiny Areas - 6
# Small Areas - 4
# Medium Areas - 2
# Large Areas - 2
# Designers - 3

FRW: Treasure guidelines

Here are the treasure guidelines as determined in this thread on the FRW forums:

http://nwcitadel.com/forums/showthread.php?t=853

Using this as a guideline will help create a balanced module. This is something I'm always looking for an can never find. Here it is reproduced for your convenience.

 

 I posted the following in another thread since the question came up. These are some very loose guidelines (they could be a lot more detailed) for handing out magic items and wealth in modules. Feel free to discuss, since nothing is set in stone yet.

The two basic guidelines for handing out gold and items are to:

#1 Use the following table of magic weapon (and equivilant) per level
#2 Use a modified version of table 5--1 from the DMG to gauge how much wealth a player of a given level should have. This wealth number is the total value of all items and gold possessed by the player.

Phoenixus magic weapon guidelines

1-3rd = Masterwork weapons
4-6th = no better than +1 weapon/armor or equivilant
6th-9th = no better than +2 weapon/armor or equivilant
10-13th = no better than +3 weapons/armor or equivilant
14-17th = no better than +4 weapons/armor or equivilant
18+ = no better than +5 weapon/armor or equivilant

Note: Also remember that adding special abilities to weapons or armor beyond the enhancement bonus makes them equivilant to more powerful weapon. For a general idea, look at the base gold cost of a weapon with the next powerful enhancement bonus to the one you are handing out and make sure that your weapon or armor is not equal to or greater than that value.

For items like potions, scrolls, and wands, the general idea is only give the player access to items that can cast spells that an equivilant level spell caster could cast, with an occsional item that gives them temporary access to next level higher of spell (but with very limited charges). So, for example, if a first level cleric can only cast cure light wounds, you shouldn't be giving first level character of any class access to potions of cure moderate wounds, except possibly as an extremely rare one-time case.

DMG Table 5--1: Character Wealth By Level (modified to 1/2 vaule)

Level Gold
2nd 450
3rd 1,350
4th 2,700
5th 4,500
6th 6,500
7th 9,500
8th 13,500
9th 18,000
10th 24,500
11th 33,000
12th 44,000
13th 55,000
14th 75,000
15th 100,000
16th 130,000
17th 170,000
18th 220,000
19th 290,000
20th 380,000

Note: One thing to remember is that players will actually spend gold and resources during adventuring, so ou have to make sure they recieve enough gold per encounter to both cover this expenditure and also ensure they have the proper wealth level. One way to easily figure this out is to make the bulk of magic items they acquire expendable items like potions and scrolls, then ensure that they have to use those items to defeat encounters instead of saving them up and selling them.

Merchant markups 

Further down, Seryn made the following point:

I checked some of the OC merchants just out of curiousity, and the four or so that I looked at all had 100% markups with 40% markdowns, just as an fyi.

Gamasutra: The Ecology of Game Design

Styraxian pointed out this article by Kevin Carter that talks about the placement of NPC/Creatures and their relationship to the environment.

I have a great time playing through all sorts of game worlds—blasting randomly placed enemies, collecting scattered power-ups, earning points, gaining levels, all en route to some nefarious “main boss.” Usually the game world is very transparent though, meaning I can tell I’m in a game from the moment I pick up a controller to the moment I put it down again. As a player, I’m not exploring environments, I’m beating levels. I’m not fighting aliens, I’m defeating scripting.

This isn’t always the case. Sometimes I can forget I’m playing a game. Sometimes I feel I really am crawling through an air vent in the Black Mesa Facility. Sometimes I think I’m actually looking for the orc chieftain who has been leading the attacks on my village. Sometimes I—

Check out the full article Living Worlds: The Ecology of Game Design by clicking the link below:
http://www.gamasutra.com/features/20...arter_01.shtml

Names

Coming up with interesting names that won't have your players rolling their eyes can be difficult. At least it is for me. Here are some good resources to keep you come coming up with another name like "Hard Goodman."

Kobold Names

Don't ask my why, but I needed to come up with Kobold names and started looking around. It's an odd subject to do a google search for and the results are even stranger.

My favorite, and probably the most useful, was this:

The Kobold Namer
http://www.dungeonraiders.com/files/kamb/

Just keep hitting refresh for more names.

And speaking of niche needs, try this amusing conversation if you're bored:
http://www.treasuretables.org/2006/07/itty-bitty-niche-products-how-much...

Name generators at Grey's Castle

Grey Starr and Dimitria Night-Starr over at Grey's Castle have several quick name generators based on articles in Dragon Magazine. Here's their description from the page:

"All generators here-in are created from the works of Owen KC Stephens from the pages of Dragon Magazine... They follow the exact rules and no changes or modifications were made to the information used."

At the time of this post, they have the following generators:

Random Male Elf Names

Random Female Elf Names

Random Male Drow Elf Names

Random Female Drow Elf Names

Random Halfling Names

Random Gnome Names

Random Male Dragon Names

Random Female Dragon Names

Random Male Dwarf Names (with Stronghold name)

Random Female Dwarf Names (with Stronghold name)

Random Dwarf Cusses (Swear like a Dwarf)

Visit the site here:
http://grey-starr.ca/index.html

Samuel Stoddard's Fantasy Name Generator

Another good name generator I've found is Samuel Stoddar's Fantasy Name Generator. From his introduction:

One of the perks of creating fantasy stories -- whether by writing a story or game or by role-playing -- is you get to make up the names. Some people relish the task while others are frustrated by it. Some like it but can't seem to create names that are diverse enough. Fantasy Name Generator is a tool that can help you. It can generate an endless number of random names (of people, places, or anything) that would be suitable for use in a fantasy setting. It can generate names on its own, or you can tell it what kind of name you're looking for. Feel free to use this tool and any name that comes out of it (assuming it doesn't accidentally generate a legally protected trademark or something).

Check it out here:
http://www.rinkworks.com/namegen/

 

Seventh Sanctum: Name Generators

There's a fun suite of name generators over at Seventh Sanctum that has a lot of good resources.

Check it out here:
http://www.seventhsanctum.com/index-name.php

Here are some of the more useful generators listed:

Tavern Namer - Where's the next drink, next clue, or next bar fight coming from? Inns and tavers are such an integral part of the average fantasyscape that naming them can be difficult (or boring). Skewed towards fantasy-style names, obviously.

Angel/Demon Namer - A mix of latin and hebrew-sounds, this is a generator for Judeo-Christian style Angels and Demons (just don't expect them to actually translate to anything). 

Dark Elf Namer - Not all elves are nice, after all.

Dwarf Namer - Need a name for your latest bearded burrowing buttkicker? Come here! Generates names, full names, and clan names.

Elf Namer - Names for both Tolkeinesque elves, Wild Elves, and general fantasy.

Evil Deity Generator - Dark gods, evil spirits, basphemous amorphous horrors - all in one easy package!

Goblin Namer - Need to name members of your Rampaging Hordes of Vaguely Humanoid Evil? This is the place to do it - from first names to last names.

Kaiju Name Generator - Generates names for your general Rampaging Giant Monster.

Tree-Being Namer - Call them Ents, Treants, Treemen, what you will, this generator gives you something specific to call individuals.

Vampire Namer - From "common" sounding names to outrageous fantasy, it's all you need to name your latest bloodsucker!

Ship Namer - Generates ship names in a variety of style - perfect for anything from a personal craft to a starship, just spend some time generating to get one that fits.

 

The Realm's of Otara: Drow Names

I found this handy table to help create drow names that seems to be parked on The Realm's of Otara Role Playing group's site.

http://www.angelfire.com/rpg2/vortexshadow/drownames.html

I'm not sure what the source is, but it's a quick handy way of throwing some names together.

Puzzles

Good puzzles give the players a chance to overcome obstacles on their own terms. They can be a nice change of pace, but they can also be a dead end that kills the action.

Examples

It's always good to review what has been done in the past, so this section contains examples, both good and bad, of puzzles in NWN1, NWN2, and similar games.

NWN1: HotU Puzzles

Mikar posted a FAQ for all puzzles in NWN1: Hordes of the Underdark. It's a great reference for when you are planning our your own puzzles in NWN2.

I made this FAQ because I'm seeing so many questions about the puzzles in HOTU in this forum. I hope that this FAQ will reduce the numbers of threads where people ask for advice on the puzzles.

Check it out:
http://nwn.bioware.com/forums/viewtopic.html?topic=319245&forum=82

Tea Leaves: Puzzles

I ran across a post by peterb over at Tea Leaves talking about the state of puzzles in video games.

In a video game context, I'm speaking of puzzles as being parts of games. The typical puzzle implementation is self-contained ("Solve this puzzle to advance past this door,") but that is a matter of habit, not a requirement. A puzzle can have a scope that encompasses all of the non-narrative parts of a game, or can even be intimately intertwined.

Further down her gives four general guidelines for making good puzzles in games:

1. The puzzle has to have a reason for existing.

2. The existence of the puzzle should move the narrative forward somehow, even if only by a little bit.

3. The more integrated into your game world the puzzle is, the better.

4. This one is debatable, but I believe that where possible, the puzzle should be to figure out what the puzzle is. That is, if you have to explain the rules to the player when they start, you've already lost. Ideally, once the player recognizes that they have encountered a puzzle, they should be able to solve it within moments of figuring out how to solve it.

Check it out:
http://www.tleaves.com/weblog/archives/000031.html

Tea Leaves: There and back again

I came across a post by by peterb over at Tea Leaves where is examines physical locations in games how what makes for a consistent and engaging experience.

The question then is: if you are describing a space that doesn't signify a real-world space, how do you make the player care? How do you increase the power of the virtual space you've created so that, when she is done playing your game, the player thinks of it, on some level, as a "real" place? In this article, I'm going to discuss three techniques: familiarity and reuse, signifiers such as maps and text, and geometric and logical consistency.

Check it out:
http://www.tleaves.com/weblog/archives/000026.html

Things to avoid

Arcane Fury posted a message in the modules forum asking what puts people off a mod. Here's a quick list:

  • A lame story
  • Bad Grammar
  • Bad spelling
  • Absurd design decisions
  • Too-large maps that have mostly nothing in them.
  • Illogical alignment shifts
  • Authors using settings not their own (such as the Forgotten Realms) but not trying hard enough, or at all, to follow established lore.
  • Dialogue that railroads the PC into a specific personality.
  • Overly difficult combat.
  • Grinding monsters for XP and too much combat for the sake of combat.
  • Endlessly fightingfightingfighting the same battle over and over and over again.
  • Tedious things you have to do which do not aid the storytelling.
  • Editing enemy stats to just flat out stupid levels
  • Making things overly complicated or trying to emulate life too closely (i.e. - Having to worry about food, actual weight for coins)
  • Quest rewards that do not match the difficulty of said quest
  • Totally useless quest rewards (i.e. - plate armor for a mage type character)
  • Monty Haul campaigns (overabundance of money and magic items)
  • Unrealistic merchants (magic weapons/armors for sale, full plate or exotic weapons for sale on a village smith)
  • Magic items with no history to them
  • Unrealistic treasure placement
  • Too many exp and a resulting fast level progression
  • Standing helplessly by (e.g., in dialog mode) while something important happens.
  • Limited dialog choices, especially when dialog has an impact on alignment and influence. Apparently, there are only two alignments in Faerun: Lawful Tight@$$ and Chaotic Stupid.
  • Uninspiring conversations.
  • Stagnant background. Townsfolk who just stand in the same spot all day and night, having the same non-conversation, until the end of time.
  • Experience Penalties
  • Impossible to solo.
  • Too many instant death situations and attacks
  • Too restrictive resting

Check out the full thread:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=536202&forum=111

Wiki: Abeir-Toril

If you are considering placing your module in Abeir-Toril, the fictional planet of The Forgotten Realms on which Faerûn is located, be sure to check out the wiki.

Abeir-Toril main entry:
http://en.wikipedia.org/wiki/Abeir-Toril

The Faerûn entry:
http://en.wikipedia.org/wiki/Faer%C3%BBn

WotC: Adventure Builder Archive

While digging around looking for some ideas, I came across the Writing Your First Adventure article By Wolfgang Baur on the Wizards of the Coast site. It's a fun read and can help stretch your brain:

If you are ready to design your first RPG adventure, or learn how to improve the adventures you've already got, you've come to the right place. The "Adventure Builder" will cover all the bases, from hooks to background to traps and treasures.

This time out, we'll cover the foundation you need to build a great adventure. It's not the background, the stat blocks, or even the main villain. It's monster selection, and figuring out the size and style of the adventure.

Of particular note is the section on balancing encounters. While this it's a bit different from PnP, it's still worth a look.

While this breakdown is good advice, it's not complete. You'll want to be sure that your ... encounters include encounter variety by class as well as by EL. That is, make sure to include each of the following types of encounters, to give every class and every player a chance to shine.

1) Two Skill Encounters: These are creatures or obstacles that can be defeated by stealth or skill, such as guards, castle walls, cliffs, informants, or low-hp creatures that can fall to a single sneak attack.

2) [Eight] Pure Combats: You need some no-negotiation, straight-up combats that play to the fighter classes. Think orcs, wolves, ogres, giants -- or dragons. Consider tactics first here: ambushes, charge, bull-rush, something to make it more than just attack rolls and damage rolls.

3) Two Magical Challenges: Include two magical challenges that require a knock, a fireball, or whatever other strengths your arcane spellcasters have. They might be lore-based challenges, such as knowing the weaknesses of an extraplanar creature, or they might require the use of Concentration or Spellcraft to manipulate a magical object or unravel a mysterious warding.

4) One Divine Challenge: The divine caster in the party is more than just a medic, so give him or her something to do with at least one undead turning, Knowledge (Religion), or nature-knowledge encounter (if your divine caster is a druid).

5) One Puzzle or Trap: This could be as simple as finding the key to a tough lock, deciphering an ancient script, or finding a secret door with Search, but you should include traps and puzzles for your party to solve. If the party doesn't have a rogue in it, use Knowledge skill checks as a substitute.

6) Two Roleplaying Encounters: Social skills play an important part of the game too, and bards don't like to just sit and do their stuff in the background. Provide at least two roleplaying encounters that can be defeated by the right social skills, bribes, exchange of services, or clever conversation. Examples include a scholar with a clue that the party needs to bypass some defenses or wardings, or a devil who will ally with them against a common foe.

7) One Mook Encounter: This should be against foes of at least 2 CR less than the party, and ideally 3 or 4 less. Think kobolds, bandits, skeletons, wild animals, or any other group of many foes that play to Cleave and area-effect spells. It's fun to see heroes cutting a swath through hordes of foes.

8) One Polder: "Polder" is a Dutch word describing land reclaimed from the sea, but here it's a more general term. As described in detail in Dungeon 135, polders are safe havens for adventurers, places where the party can regain strength. Think Rivendell in Lord of the Rings. Your polder could be a xenophobic elven tree city, a magical rope that generates rope trick spells as a charged item, a bound archon who wards a treasure, or a dwarven merchant caravan. If the party wishes, they can heal up to full strength and level up.

9) One Bigger Fish: To keep the blood flowing, you should have one overwhelming encounter that the party can't handle without serious risk of a total party kill. This could turn into a roleplaying bit of Diplomacy, a chase, or a stealth challenge, depending on how the party handles it -- but they should see that not every encounter in every adventure should be fought.

10) Big Finish: A grand finale encounter with all the trimmings: villain, minions, and a room or terrain that provides interesting combat options.

Note that for the sake of increased combat in a CRPG, I've doubled the combats from four to eight. That's a total of 19 encounters, 11 of them involving combat. Whether that's enough for a full level of play is up to you as a builder, but at least Baur's list will get you thinking about balance.

Check out the article here:

http://www.wizards.com/default.asp?x=dnd/ab/20060728a

Check out the full Adventure Builder Archive here:

http://www.wizards.com/default.asp?x=dnd/arch/ab

3.5 Ruleset

Sometimes I find that I need to reference some minor factiod about the 3.5 ruleset. Here are some links dealing with this.

Encounter Calculator

If you need to get a rough idea on how much XP a party will get from an average encounter for a certain level, consider the Encounter Calculator v3.5.

http://www.geocities.com/edymnionii/EPLvsEL.html

It's a great way to figure out how many encounters a party might need. Remember to divide by 10 (assuming your experience slider for the module is set to 10%).

Credits: Tiera Starr, John Dells, arcady, Maladaar.

Thanks to dirtywick for pointing this out.

 

The experience formula

I know I forget this every few months, so here it is thanks to kevinodie and Jassper who posted this on the official forums:

(Current Level * NextLevel)*500 = XP needed for next level.

So level 1 = 0xp,
(level 1 * Level 2)*500 = (1*2)=2*500= 1000 xp for level 2
(level 2 * Level 3)*500 = (2*3)=6*500= 3000 xp for level 3
ect.

This can also be expressed:

N*(N-1)*500 is the minimum XP needed to get to Nth level.

Originally posted here:
http://nwn.bioware.com/forums/viewtopic.html?topic=470745&forum=46

DMFI

The Dungeon Master Friendly Initiative has been helping build the multiplayer experience since the NWN1.

Players

If you want to explore modules that are Dungeon Master friendly, start at the DMFI modules page:
http://nwvault.ign.com/View.php?view=NWN2ModulesEnglish.DMFM

If you're looking to be a DM for a session, check out the DM 101 module for NWN2:
http://nwvault.ign.com/View.php?view=NWN2ModulesEnglish.Detail&id=296

For more advanced topics on how to bring NPCs to life in a DM'ed module, see Carlo's article "Creating Believable and Memorable NPCs":
http://dmfi.slightlysilly.net/modules.php?name=Content&pa=showpage&pid=9

DM forum
http://nwn2forums.bioware.com/forums/viewforum.html?forum=117

Find others to play with at NWNConnections
http://www.neverwinterconnections.com/

Find others to play with at NWNCampaigns
http://nwncampaigns.com/

Builders

Builders who wish to make their modules Dungeon Master friendly can check out the following resources:

DMFI Developer Package
http://nwvault.ign.com/View.php?view=NWN2Scripts.Detail&id=38 Official

The Dungeon Master Friendly Initiative Guild:
http://nwn.bioware.com/guilds_registry/viewguild.html?gid=20

DMFI's Guide: Building a DM-Friendly Module
http://dmfi.slightlysilly.net/modules.php?name=Content&pa=showpage&pid=7

 

Issues with the DM client as of 1.10

weby posted this list of known issues with the DM client as of patch 1.10.1116. It was posted on Monday, 22 October 2007.

Check the thread here:
http://nwn2forums.bioware.com/forums/viewtopic.html?topic=543448&forum=1...

  1. Bug: Multi-select, multiselected creatures cannot be given any commands besides walk. Should have atleast attack, run available like in 1.06
  2. Missing feature Multi select - chooser actions should affect whole selection
  3. Missing feature Remote Inventory Access is not available
  4. Annoyance unposessing creatures: clumsy when it is on submenu and the creatures do not have it on quickbar, requiring rightclick, click on creature commands and click on unposess. suggested fix: autoadd the unposess to the quickbar on posession and do not clear the quickbar on full posession.
  5. Bug Quickslots empty when the DM possess something with full posession. Should have the DM's quick bar contents.
  6. Bug Players can see the dm at times even when the dm is dm invisible. Happens with cutscene convos mostly
  7. Feature request Cannot get the list of creatures selected by DM by script.(this is the multi-select)
  8. DM posessed creatures are in wrong faction. They should be in the correct faction for the creature, but are neutral to PCs for actions like spellcasting by the DM and attacking.
  9. Bug: Dms block pathfinding(since 1.06)
  10. Missing feature Inability to select creatures from the party bar outside current area makes porting PCs difficult.
  11. On posessing a creature with not full posession, it's special bilities and spells should fill the quickslots
  12. Missing feature -the DM cannot easily jump to a PC from party bar when not in same area
  13. Missing feature Cannot see the area a PC is in from the party bar
  14. Missing feature Creator Tree needs subcategories badly for speed of finding
  15. Feature request Cannot Clear the personal reputation of creaures from the DM client.
  16. Missing feature not being able to group creatures and then recall groups is very annoying..
  17. Missing feature Not being able to set variables from DM client is annoying. (Could not find this in console if there due to broken listing there)
  18. Missing feature No way directly as dm to destroy placeables that are not usable.
  19. Missing feature DMs cannot destroy waypoints
  20. Missing feature No feedback when actions occur is a big hassle.
  21. Feature request DMs cannot adjust the detection radius of PC tracking skill. a Scripting command to set a range multiplier would be best
  22. Feature request Cannot jump a party to the DM
  23. Missing feature Inability to scale things. effects allow scaling of creatures by script, but inability to scale placeables makes using them difficult.
  24. Bug Chooser and Creator close on area transit.
  25. Featur request: allow Dms to see all creatures in the area on the minimap/map (like someone who is trackging) with different factions indifferent colors.
  26. Feature request Cannot change factions without extra tools.
  27. Missing feature DM's can't view player descriptions
  28. Annoyance chooser when openend does not go to current area, instead to top of list in larger modules where most needed
  29. Missing feature Inability to do text macros for sayings
  30. Missing feature Inability to do text macros for console commands
  31. Missing feature DMs cannot change identified status of items from identified to non identified
  32. Annoyance ESC key closing chooser and creator
  33. Feature request set Names or descriptions. Would be good if one could right click and object and edit it's name and description
  34. Missing feature Being able to Ban from the dm client
  35. Feature request Cannot disable/enable only destroy encounters from the DM client.
  36. Feature request store/play vfx sequences: can store sequence of speciaal effects persistently and then play them back.
  37. Feature request store/retrieve object: stores the object to a DB and then you can retrieve any stored object
  38. Feature request Allow setting of all area lighting and such settings. (Fergus demoed this at some point in the past with nice looking sliders)
  39. Feature request Speak as NPC without posession: selection speaks the given text
  40. Feature request transitions: able to set tag, destination, name
  41. Feature request Creating things: Able to create more types of objects: doors, transitions,waypoints,triggers
  42. Feature request ChangeItems: Name, tag, icon, look, description, powers
  43. Feature request Cannot copy objects
  44. Feature request store/play emote sequences: can store sequence of emotes persistently and then play them back
  45. Feature request waypoints: able to set tag,name,mapnote mapnote enabled
  46. Feature request changing time of day
  47. Feature request Specify what class the creature should raise in when doing resetlevel
  48. Feature request Change Creatures: should be able to click an edit button and then change any creature value like:Name, Attributes, Hitpoints, level, classes, saves, appearance factors, aligment, skills, tag, description, hitpoints, scaling
  49. Feature request Doors: able to set tag, destination, lock, key,lock dc
  50. Missing feature Not even Dms can close transit doors
  51. Feature request traps: able to trap doors, placables
  52. Feature request Dm healing is not signalled to server in any way -> make script so that we can edit it and add our own functions like death tracking
  53. Feature request SetLocalObject and SetLocalLocation that have a mark and then store the marked place or object in the target.
  54. Feature request Change Placeables: scaling, look, name, facing, description, script for manipulate, plot/not plot, hp

FAQ

Here are some basic questions I had when I first started. For now these are just listed in FAQ form, but will be organized into the book later:

How do you delete a blueprint (a creature, an item, etc.) after you have created it in the toolset?

Click on the item in the blueprints window and just press the DEL key on your keyboard. Make sure the properties windows is not open. otherwise nothing will happen. You can minimize the properties window by clicking on the little pin.

How do you stack placeables in the toolset?

Set the Stackable property to True on both of the placeables, then raise the placeable you want to stack on top using ALT-LeftMouse and press Spacebar to have it drop to the bottom placeable. If you don't enable stacking, objects just fall to the ground when hitting spacebar. (thanks Miserere from the forums) The "s" key is a hotkey for turning the stacking flag on. You can also set the height of the placeable and then lock the height. (thanks to knightsubzero from the forums)

What's the difference between scroll direction and scroll angle for water layers

It seems the scroll direction x,y is either off (zero), or on (greater than zero), and this defines what angle of zero is. So if scroll direction is y = -1, and x=0 then angle zero is north. you can then use the scroll angle to control direction, so 90 would be east, 180 would be south, etc. (thanks to evalcarcel from the forums)

How do people create those screenshots where you can see the whole area without that foggy limit?

Look under Vew > Options > Graphics for an entry under FarPlane. Change this to something higher (like 500 or 1000 instead of 100).

How do I create an area that is always night?

MuLmbo has a great answer in the Toolset Q&A thread:

# Fire up the editor.
# Open your module.
# Open the area you want to make eternally night.
# Highlight the area in the areas pane to see its properties.
# Under environment:
* Set the 'Day/Night Cycle' value to false.
* Set the 'Is Always Night?' value to true.
# Under Appearance:
* Expand '7' (Default)
* Customize the colour/lighting however you wish

Why won't my creatures equip or wear items.

Make sure the creature has the appropriate feats to wear the armor or use the weapon you want them to have. If not, they won't be able to equip the item in the game.

How do I use scripting when a PC first enters and leaves my module?

EPOlson has a good answer from this thread in the forums: http://nwn2forums.bioware.com/forums/viewtopic.html?topic=528278&forum=1...

When a PC logins in, the first events to fire are the OnAcquireItem and OnPlayerEquipItem events. At that point, the PC object exists and can have inventory. But it has no location.

Then OnClientEnter fires. The PC object is complete, but still has no location. (the lack of location is what causes most scripting issues)
Once the PC has been assigned an area, OnPCLoaded is called.

Then OnEnter and OnClientEnter are called for the area the PC ends up in. (OnEnter is called for all creatures entering an area - including NPC right after onModuleLoad, OnClientEnter is just for PCs)

A trigger would be called last.

Similarly, when the PC logs out OnClientLeave gets called. At that time, the client information is no longer associated with the object, just the physical characteristics. (which is another scripting issue) Then OnExit for the area is called (unless the PC logs out dead, then it is not called)

One more thing I noticed: when you transition to a new module in a campaign (StartNewModule and LoadNewModule), OnPCLoaded is not called. OnClientEnter is called, and so are the area's OnEnter and OnClientEnter. (onClientLeave is also not called)

OnPCLoaded is called when a PC logs out and back in.

Do heartbeats fire when the PC is not around?

Abby_ suggested in a post on the forums (http://nwn2forums.bioware.com/forums/viewtopic.html?topic=531431&forum=114) that there is an option on the creature properties called "Disable AI while hidden" that might cause heartbeats to fire when a PC is not around.