These files represent scripted actions. .bcs files are scripts attached to anything other than the player characters. (Or are creatures also limited to .bs files?)
.bs files are scripts which drive a characters actions automatically (AI scripts) based on criteria in the environment. Thanks to Dmitry Jemerov
for clarifications regarding this format, particularly with regard to Torment.
Just as the files from which they are compiled, these script files make use of the concept of "triggers" and "responses". A trigger is a condition which causes a response with a certain probability.
A response is one or more calls to functions they have exposed to the script. I believe this to be the difference between .bcs and .bs files. (They are assigned different
resource types in the resource management code, too.
The format will be given in a top-down sense: i.e. I will describe the formatting of top-level blocks, and then I will describe the contents of the blocks. The process will proceed recursively until the whole format is described. The top-level block is the script file.
First, a brief word on "function parameters". Both triggers and actions are essentially calls to functions inside the Infinity Engine. Triggers can take up to 7 arguments, and actions can take up to 10 arguments. There are three allowable forms of arguments: strings, integers, and objects. The different function calls are defined in TRIGGER.IDS and ACTION.IDS. There are also functions defined in SVTRIOBJ.IDS, which are a {sub|super}set of of the function calls defined in TRIGGER.IDS. They are probably used for {insert spiel here}. String arguments are simply quoted strings (i.e. ASCII strings delimited by the double quote character "). The format of these descriptions is given below, by way of an example (from BG's TRIGGER.IDS):
0x401D Specifics(O:Object*,I:Specifics*Specific)
The first thing on the line is the ID (in hex. IDs in scripts are typically in decimal). Next is the name of the function. Inside the parentheses, similarly to C/C++, is a comma-delimited list of argument type and argument name. The argument types are:
There is always a tag after the : and before the *. I believe the tag is used only for expository function -- i.e. simply an argument name to help
discern the purpose. There is, however, one minor complication. Actions only have space for 2 string parameters. There are actions taking anywhere from 0 to 4 strings. Some of
the actions which take strings (usually either 2 or 4 strings) actually concatenate the strings. In this case, it is always an "Area" and a "Name" parameter, (though the parameter names vary somewhat). The
only surefire way to tell which is which is to hardcode the values of the actions which concatenate strings. When the strings are concatenated, the "Area" is always the first part of the resulting string,
and always takes exactly 6 characters. It works, in most respects, just like a namespace qualifier in, for instance, C++. An aside: The functions which actually concatenate the strings
are typically the ones which access "global variables", i.e. Global, SetGlobal, IncrementGlobal, et cetera. I am not certain, at present, how "action" type parameters are stored. This will require some investigation.
The final detail in the above example is the bit following the *. This occurs (I believe) only in integer arguments; the string following the asterisk is the name of an IDS file. The
values in the IDS file are the only allowed values for that parameter; moreover, it is extremely probable that the parameter can be accessed using the symbolic names given in the IDS file, though this is
merely speculation. Each trigger can use up to 2 (3?) integer arguments, up to 2 string arguments, and one object argument. These seven arguments are always specified in each trigger, even if they are not
all used. If an argument is not used, it is assigned a dummy value. Finally, the arguments are used in order when they are listed in the scripts. For instance, two integer parameters always occupy the
first two "integer parameter" slots in the trigger or action. A trigger has an additional "flags" field, in which, for instance, a bit is either set or cleared to indicate whether the trigger is to be
negated or not. (i.e. whether the success of the trigger should return true or false).
SC (newline)SC (newline)This can be interpreted as "if condition, then response set". A response set is a set of actions, each of which is performed with a certain probability.
CR (newline)CR (newline)This should be interpreted as the AND of all the "trigger" conditions. The condition is true iff all triggers inside are true.
This format is slightly hairier. First, it has a "trigger ID", which is an ID in the TRIGGER.IDS file. Essentially, each trigger corresponds to a call to one of the functions listed in there. See the section on parameters for details.
TR (newline)TR (newline)Each response in a reponse set has a certain weight associated with it. Usually, this is 100%, but if not, then the response is only played with a certain probability. To find the chance of a particular
response being chosen, sum the probabilities of all the responses in the response set. Each response Rn has a probability Pn/Sum(P) of being chosen, if the response set is to be played.
A response is simply the concatenation of a probability and an ACTION.
RE (newline)RE (newline)This format is slightly hairier. First, it has a "action ID", which is an ID in the action.IDS file. Essentially, each action corresponds to a call to one of the functions listed in there. See the section on parameters for details.
AC (newline)x y) (no newline)AC (newline)Objects represent things (i.e. characters) in the game. An object has several parameters. These parameters have enumerated values which can be looked up in .IDS files. Planescape: Torment has more parameters than BG did.
The specific format of an object is as follows:
OB (newline)OB (newline)Object coordinates can be specified as either a point, a rectangle, or a circle. Coordinate values which are -1 indicate that the specified part of the coordinate is not used. (Also as a wildcard?)
A point is represented as:
[x.y]
A rectangle is represented as:
[l.t.r.b]
A circle is represented as:
[cx.cy.r]
[ back to index ]