Technical / NWN2 GUI Information

This article discusses the Graphical User Interface (GUI) available in NWN2. A GUI is defined as a series of nested XML objects with specific properties in an XML file in much the same way that a webpage is defined by various HTML objects in an HTML document. Most of the game interfaces in NWN2 are defined by these XML files, located in the UI\default game folder (some are not purely for game performance reasons as explained by OE). GUIs can also be assigned specific callback functions to trigger scripted actions in the game.

An explanation of each object and a description of the attributes, events, and callback functions pertaining to them are provided in the respective articles below:

Creating Custom GUIs

You can safely create your own custom GUIs in a couple of ways:

One option is to create a set of GUIs for a specific campaign. You can do this by creating a custom campaign directory within the Campaign game folder and adding a UI directory under it to store your XML files. For example, Campaign\ALFA\UI. This will allow you to automatically associate a set of GUIs to a campaign so those GUIs will load each time you play the campaign.

A second option is to create a set of GUIs to serve as new defaults. You can do this by creating a custom UI directory within the main UI game folder and storing your XML files there. For example, UI\ALFA. You can then change your default GUIs by editing the CurrentGUI line (under [UI Options]) in your nwn.ini file and referencing your new UI directory. In our current example, we would set CurrentGUI=ALFA. This will load your new custom GUIs each time you start the game. Campaign GUIs will still override a custom default.

It is highly recommended that you do not edit the default GUI XML files in the UI\default game folder. This is because you can either end up losing the default GUI entirely (if you sufficiently edit the GUI where it's not trivial to revert) or lose your edits if a patch overwrites one of these files. Use the default GUI XML files only as examples to create your own custom versions.

Note: There are two ini files (located in the UI folder) which make GUI XML files accessible to the game: pregamegui.ini (screens you see when not playing) and ingamegui.ini (screens you see when playing). These ini files are to GUIs much like what nwscript.nss is to scripts; They serve as a layer of abstraction between the XML files and scripts. Each ini file defines the relevant SCREEN constants that reference all the available or usable GUI files. If you intend to create an entirely new GUI, you'll have to add it to the appropriate ini file.

Special Screens

Most XML files are loaded as default UI Scene objects, which implies no special behaviors are attached. 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. All of these scenes are distinguished by their identifying name in ingamegui.ini (or the screen tag given to them when being loaded via script). The actual XML file name doesn't matter.

Note that if a screen name below ends with a * symbol, that means that only the text up to the * is required and that the name may be unique after it.

The following are special GUI screens that are loaded differently than most XML files:

SCREEN_FADE The full screen 'fade' effect. It gets loaded like a normal XML file at first. After loaded, the first UI Icon object found (The one highest up in the file) becomes the engine's 'Fading' icon. The rest of the contents of the file will behave normally. In our default SCREEN_FADE, we include just the full screen icon. But there may be other things one would want to include on the fade, such as custom images, etc.

SCREEN_QUICKCHAT The NWN1 style dialog box. First it is loaded like a normal XML file, then the following UI objects are searched for in order for the engine to use them:

  • npclistbox - Listbox of NPC spoken text
  • npctext - Text field for NPC spoken text (Contained by npclistbox generally)
  • replieslistbox - Listbox of Player Reply options
  • skipdialogbutton - Button for skipping through the NPC spoken nodes
  • speakername - Text field for containing the speaker's name
  • portrait - UIPortrait object

All but the speakername and portrait fields are necessary or the window will not be loaded.

SCREEN_CUTSCENE The fill screen cutscene view with the black bars on the top and bottom. This window is loaded like any other, then the following objects are searched for by the engine:

  • topbar - UIFrame for the top black bar
  • bottombar - UIFrame for the bottom black bar
  • FULLSCREEN_IMAGE - UIIcon used for full screen images.
  • toplistbox - Listbox to contain the text shown on top
  • toplistboxtext - Textfield contained by toplistbox
  • bottomlistbox - Listbox to contain the text shown on the bottom. Spoken by NPCs
  • bottomlistboxtext - Text field contained by bottomlistbox
  • replieslistbox - Listbox to contain the replies available to a player.
  • skipdialogbutton - Fullscreen button for clicking through the dialog

Failure to locate any of the above objects will result in the screen not loading.

SCREEN_CONTEXTMENU The rightclick menu system. Technically, this gets loaded like any other XML file. I'll make another post later about the syntax and format of the contextmenu.xml file.

SCREEN_MINIMAP The in-game minimap GUI. I don't know a lot about how the Minimap works. If further documentation is requested for it, I can research it further later.

SCREEN_AREAMAP The in-game area map that can be brought up. I don't know a lot about how the Area Map works. If further documentation is requested for it, I can research it further later.

SCREEN_MESSAGEBOX_SPLITSTACK* Scene used for splitting stacks of items in inventory. The only gui element required is 'inputbox'.

SCREEN_MESSAGEBOX_SPLITSTACKSTORE* Scene used for splitting stacks of items for stores. It's actually loaded identically to the SCREEN_MESSAGEBOX_SPLITSTACK and only requires the 'inputbox' object to exist. I'm not sure why it got made into a seperate entry.

SCREEN_MESSAGEBOX* This is used for the generic message box popups. I'll probably have to write up more on them another time as they can be used effectively by scripts as well. The required elements for these are:

  • messagetext - Text field that contains the message.
  • okbutton - Button that will execute the OK callback
  • cancelbutton - Button that will execute the Cancel callback
  • messageboxlb - Listbox for containing the message text in case the text gets long.
  • MSGBOX_BACKGROUND - Frame used for the background, this one is optional.

SCREEN_STRINGINPUT_MESSAGEBOX* Message boxes that prompt for user string input. They are identical to normal Message boxes, except that they also require a 'inputbox' text field.

SCREEN_MESSAGE* Chat boxes, pretty much. Note that currently the engine only supports loading the hard coded ones in ingamegui.ini. I hope to change this to be a lot more flexible down the line. The required elements are:

  • messagelistbox - Listbox containing the scrollback text. If it is not found, the engine searches for messagelistbox2 instead. If neither is found, the screen is not loaded.
  • inputbox - Text field used for user input.
  • IMEREadingWindow - Used for IME support.
  • IMEReadingWindowBG - Used for IME support.
  • IMEComposeWindow - Used for IME support.
  • IMEComposeWindow - Used for IME support.
  • IMECandidateWindow - Used for IME support.
  • IMECandidateWindowBG - Used for IME support.
  • INPUT_CONTAINER - Used by the engine for easily hiding/unhiding the input related objects.

SCREEN_HOTBAR SCREEN_HOTBAR_2 SCREEN_HOTBAR_V1 SCREEN_HOTBAR_V2 All the hotbars built into the game. There are no required or special UI elements needed to load these.

If a Screen Tag doesn't match to any of the above screens, then a normal UI Scene gets created with all the default behaviors associated with it.

Scripting with Callbacks

GUI callbacks can be assigned to UI Objects to fire off scripts on a server. There are some 650 callback functions available in NWN2 for use with GUIs. These callback functions are triggered by specific events for UI Objects defined in an XML file. Multiple callbacks can be defined for the same event by appending a sequential numeric suffix (starting with 0) on subsequent callback events (ie OnLeftClick=..., OnLeftClick0=..., OnLeftClick1=..., etc).

Data can be stored on a GUI for use by callback scripts or functions. There are two types of parameters: local - data which is available to a specific user interface - and global - data which is available to any user interface. This data is referenced using the following syntax, local:# or global:#, where # is the index (starting with 0) of the data.

For listboxes, selected rows can also be referenced using listboxrow:listboxname, where listboxname is the name of the desired listbox. This will provide the row number that is currently selected in the listbox named listboxname. In addition, data in a selected row can be retrieved using listboxtext:listboxname[.textfieldname], where listboxname is the name of the desired listbox and textfieldname is the name of a text field within that listbox. This will insert the text contained by the selected row in the listbox named listboxname. The textfieldname parameter is only necessary for dealing with complex UI Panes and is used to specify which object within the pane contains the text we want.

To execute a server side script from a GUI, you must use the UIObject_Misc_ExecuteServerScript() callback function and pass in the script by name. The GUI script will be executed on the player interacting with the UI Object and is thus referenced as OBJECT_SELF in the executing script.

To launch or update a GUI screen from a script, the UIScene defined for that GUI must possess the scriptloadable=true attribute.

Note: Scripts can only be executed from a GUI if they are prefixed with gui_. Requests to fire callback scripts that are not prefixed with gui_ will be rejected by the server. This will help prevent clients from firing off scripts on the server simply by knowing their name (so non GUI scripts the game uses for things like awarding XP or GP can be protected), but script writers themselves still need to make sure that GUI scripts are written in such a way as to prevent abuse by clients.

A few script functions currently exist to give some basic control over the GUI:

  • Display a message box. Allows you to define the message text, the text for the 'okay' button, the text for the 'cancel' button, whether or not cancel is displayed, and the scripts to execute if the user clicks okay or cancel. Scripts must again be prefixed with gui_.

    DisplayMessageBox( oPlayer, nMessageStrRef, sMessage, sOkCallback, sCancelCB, bShowCancel, sScreenID, nOkStrRef, sOkString, nCancelStrRef, sCancelString );
  • Bring up a GUI on the client. In order for a GUI to be accessible from a script, it has to be defined as a screen (which points to the actual XML file that defines the GUI) in the pregamegui.ini or ingamegui.ini files.

    DisplayGuiScreen( oPlayer, sScreenID, bModal );
  • Close the screen on the client. Again, there are restrictions on which GUIs you can affect with this.

    CloseGUIScreen( oPlayer, sScreenID );
  • Spawn a GUI panel for the client that controls oPC. Nothing happens if oPC is not a player character or an invalid panel is given.

    PopUpGUIPanel(object oPC, int nGUIPanel);
  • Spawn in the Death GUI. The default (as defined by BioWare) can be spawned in by PopUpGUIPanel, but to turn off the "Respawn" or "Wait for Help" buttons, this is the function to use.

    PopUpDeathGUIPanel(object oPC, int bRespawnButtonEnabled=TRUE, int bWaitForHelpButtonEnabled=TRUE, int nHelpStringReference=0, string sHelpString="");
  • Disable an object in a GUI.

    SetGUIObjectDisabled( object oPlayer, string sScreenName, string sUIObjectName, int bDisabled );
  • Determine if a specific object on a client UI is visible or not. This gives scripts some limited control over the appearance of a GUI window by toggling visibility. This has the same restrictions as 'DisplayGUIScreen' in that there are some restrictions on which GUIs you can affect with this function.

    SetGUIObjectHidden( oPlayer, sScreenID, sUIObjectName, bHidden );
  • Set GUI text. If StrRef is -1, then sText is used instead. Passing in -1 and "" will clear the GUI text.

    SetGUIObjectText( object oPlayer, string sScreenName, string sUIObjectName, int nStrRef, string sText );
  • Set the position of a progress bar on a client GUI. The progress can be a percentage between 0.0 and 1.0 (empty and full).

    SetGUIProgressBarPosition( object oPlayer, string sScreenName, string sUIObjectName, float fPosition );
  • Set the GUI texture. This script function sets the texture for an UIIcon, UIButton, or UIFrame. If the object is an icon, the texture is set as the icon's image. If the object is a frame, the texture is set as the frame's FILL texture. If the object is a button that has a base frame, the texture is set as the BASE frame's FILL texture. If the object is a button that has no base frame, the texture is set as the UIPane state's FILL texture. Texture names should include the extention (*.tga for example).

    SetGUITexture( object oPlayer, string sScreenName, string sUIObjectName, string sTexture );
  • Set a local variable on the GUI. This function is a bit more advanced in its use, but briefly, there is a set of 'local variables' on every GUI window. The GUI layer interacts with these variables at times, and with this function, scripts can as well. This function can be used in combination with certain GUI callbacks to achieve desired behaviors.

    SetLocalGUIVariable( oPlayer, sScreenID, nVarIndex, sVarValue );

    For example, there is a GUI callback for 'OnUpdate' that will display the contents of a local variable. So you can pipe strings across from the server that you want to appear in the player's GUI in a custom window you've made.

    Another example, there is a GUI callback that will set a UI Object as 'disabled' if a local variable contains a certain value. So you can disable a certain button on your custom screen if the local GUI variable on that screen has a certain value. And so forth.
  • Turn off client GUI. This script function will turn off a player's GUI, except for the FADE screen. Floating text will still be rendered. Note that if the player hits ESC, their GUI will come back up.

    SetPlayerGUIHidden( object oPlayer, int bHidden );