View Full Version : Scripting?

10-18-2007, 02:29 PM
I might be an idiot, but I'm really getting nowhere with this!

What is a script?

I've been trying to make a new Force power, a new character, a new crystal ... and everytime I'm told I need to script something. But I don't know what it is! All I find is blue boxes filled with lots of numbers and symbols, but I don't know where to write them, how to write them, or why to write them! Am I supposed to write them in WordPad, or something? And how should I save it?


10-18-2007, 03:31 PM
I might be an idiot, but I'm really getting nowhere with this!

What is a script?

Scripting is a pretty big, broad area which can be pretty difficult to wrap your head around if you have no prior computer programming experience. There should be some tutorials here in the Holowan forum about the basics of scripting, but other than that the easiest way to get in on scripting is learning by doing in my experience. If there is a specific script you need you can ask in this forum and I'm sure someone will be able to help with it, if what you want to do is possible. Then, when you have a script that you know what it will do, try looking at it and try to figure out what the different parts of it is doing. That's how I learned it at least. :)

Anyway, a script is a set of instructions that tell the game to do something. What "something" is can vary quite a bit. Warning, slight information overload follows. :)

Examples of common things that are controlled by scripts is what actions NPCs take during combat, what happens when you use a force power on someone, when an NPC says different things when you start conversation with them (e.g. "Welcome back..." greetings when you've already spoken to them before), and when characters move around and do things in cutscenes.

In very broad terms you can categorize scripts into groups like:
Event scripts - These are scripts that are run by the game engine when a certain event triggers on an object. An event can be such a thing as when a character is attacked, when a character sees another character, when dialog is started, or "heartbeat" events that run repeatedly every 3 seconds. Combat AI scripts, trigger scripts (i.e. something happens when the player walks in a specific spot in the game world), random loot for containers, scripts that run when the player enters an area (spawning/removing npcs etc), and so on, fall into this category. Event scripts are usually used for When this happens, do this reactive situations to something is occurring in the game world.

Dialog conditional scripts - These are scripts that are used to block out or conversation nodes in a dialog when certain conditions are met. They can check things like if a specific quest is active, if the player is Good/Evil, if the player is a certain level, just to mention a few examples.

Dialog action scripts - These scripts are fired from DLG files when a certain conversation node is reached in dialog. They are usually used for things such as setting that a certain stage has been reached (i.e. the "Welcome back" example when you've already spoken to them), and are also used for moving characters around and making them do things in cutscenes.

Spell/force power impact scripts - These are scripts that are triggered when a force power or other "spell" effect (grenades, shield armbands, medkits, droid beam weapons etc) is used. These scripts usually modify characters, either the user, the party or enemies. They are responsible for things like showing visual effects (explosions, pretty lights etc), dealing damage, healing damage and applying status effects (like stun, fear, stasis, damage resistances, extra speed etc) to a creature.

The common theme for all scripts are that they need to be fired from somewhere, either an event, a spell/force power, from a dialog, or by another script. A script does not run automatically just because you put it in the override folder.

Scripts are written as text files, you can write them in Notepad or the built-in text editor in KotorTool. These human readable "source code" files should be saved with a .NSS file extension. The script will then need to be translated into byte code that the game engine can understand, since it will not do anything with the source code files. This process is called compiling, and the easiest way of doing it is using KotorTool's built-in text editor, it should have options in the menu bar for compiling scripts. Compiling a script produces a file with the .NCS extension, which is byte code that the game can use.

A script needs to always contain a start function, which is run when the script is triggered. A function is essentially a group of instructions that perform a desired task. In all script types mentioned above except dialog conditional scripts the start function is called main. In the dialog conditional scripts, the function is called StartingConditional instead.

The difference between these two start functions, other than the name, is that the main() function does not return any value (void), while StartingConditional() returns an integer (int), that is a non-decimal number. This difference exists since a dialog conditional script needs to return either true (any value other than 0) or false (the value 0) to the dialog file that runs the script. If a conditional script returns true, the dialog node it is set on becomes available, while if it returns false the dialog node will be hidden/unavailable.

Here are two very simple examples, one of each type:

1. normal script:

void main() {
SendMessageToPC(GetFirstPC(), "Hello World!");

2. dialog conditional script:

int StartingConditional() {
return (GetGender(GetFirstPC()) == GENDER_FEMALE);

Looking at these examples, the first script, if run, will show the text Hello World! in the Feedback log at the journal screen in-game. This script uses the main() start function, with void set as return data type (i.e. it returns no value at all). The paranthesises following the function name is where any parameters (settings or other data it requires to work) should be set, but neither the main() or StartingConditional() functions take any parameters. Finally the block delimiters, { and } signify that any instructions that occur between them belong to the function.

It then calls the standard script function (a function is instructions to do a specific task) SendMessageToPC(), which will show some text on a character's Journal Feedback log screen in the game.

This functions will take two parameters (basically settings to instruct the function how to work), which you specify within the paranthesises following the function name. The first parameter needs to be set to an object reference for the character who should receive the message. An object is essentially a character, scenery or item in the game world. In this case we use another function, GetFirstPC(), which returns an object reference to the player's character. (This function does not require any parameters to be set, but you still need to put the paranthesises after the function name when you call it.) The second parameter is a string value (text) that should be displayed, in this example Hello World!. Each instruction in a script need to be ended with a semicolon, so that follows the function call.

The second script, when run from a dialog, would enable the dialog node it is attached to if the player's character is female. It works similarly to the first, with the differences that the return data type is set to int (integer, a number) instead of void (nothing). This type of function need to return a value, which is what the return directive does. The script then calls the standard function GetGender(), which checks the gender (Male, Female) of the character you specify as parameter. Again, we use the GetFirstPC() to get an object reference to the player's character. We then compare the value the GetGender() function returns to the value of the GENDER_FEMALE constant. If they match, the script will return true, otherwise it will return false.

The standard functions (like GetFirstPC(), GetGender() and SendMessageToPC()), and standard constants (like GENDER_MALE and GENDER_FEMALE) are listed in a text file named nwscript.nss which you can extract with KotorTool from the scripts.bif data file. This file usually contains comments (lines of text starting with // are comments and not part of the script itself) that describe roughly what a function does. This file is a very handy reference for looking up things when you write scripts, and to try to figure out what the functions used in scripts are doing.

Those are just a few basic examples, scripts can be a lot more complex than that. :)

If you have no prior programming experience all this is probably rather confusing. It took me quite a while to figure out how things worked when I first started looking into scripting for KOTOR and Neverwinter Nights. I don't know if there are any real shortcuts I can offer.

If you want to learn the best advice I can offer, beyond checking out the "getting started with scripting" tutorials posted here in holowan, is to look at existing scripts and try to figure out how they do the things they do. You can find many of the game's existing scripts in the scripts.bif data file with KotorTool, or you can ask for scripts that do specific things in this forum and then have a look at the scripts people here offer. :)

Also ask in this forum if there is something specific you need explained or don't understand, people are generally very helpful around here.

10-19-2007, 03:49 AM
I didn't quite understand all that, but I guess it'll all make sense once I start scripting. Thanks for explaining it to me. :)