BAIN Wizards

Valid XHTML 1.0 Strict

 

Contents

•  Introduction

•  Dialogs

•  SelectOne

•  SelectMany

•  Versions

•  Cancel

•  Error

•  Finish

•  The language

•  Variables

•  Constants

•  Expressions

•  Strings

•  Comments (;)

•  Functions

•  CompareObVersion

•  CompareOBSEVersion

•  CompareOBGEVersion

•  CompareWBVersion

•  DataFileExists

•  GetEspmStatus

•  EditINI

•  Exec

•  str

•  int

•  float

•  len

•  endswith

•  startswith

•  lower

•  find

•  rfind

•  GetFilename

•  GetFolder

•  Keywords

•  SelectSubPackage

•  DeSelectSubPackage

•  SelectEspm

•  DeSelectEspm

•  SelectAll

•  DeSelectAll

•  SelectAllEspms

•  DeSelectAllEspms

•  RenameEspm

•  ResetEspmName

•  ResetAllEspmNames

•  Note

•  If-Elif-Else-EndIf

•  If

•  Elif

•  Else

•  EndIf

•  While-Continue-Break-EndWhile

•  While

•  Continue

•  Break

•  EndWhile

•  For-Continue-Break-EndFor

•  For

•  Continue

•  Break

•  EndFor

•  SelectOne

•  Case

•  Default

•  Break

•  EndSelect

•  SelectMany

•  Return

•  Cancel

•  RequireVersions

•  Operators

•  Assignment Operators

•  Assignment (=)

•  Compound Assignment (+=, -=, etc)

•  Math Operators

•  Addition (+)

•  Subtraction (-)

•  Multiplication (*)

•  Division (/)

•  Exponentiation (^)

•  Boolean Operators

•  And (&, and)

•  Or (|, or)

•  Not (!, not)

•  In (in)

•  Case Insensitive In (in:)

•  Comparison Operators

•  Equal (==)

•  Case insensitive Equal (==:)

•  Not Equal (!=)

•  Case insensitive Not Equal (!=:)

•  Greater Than or Equal (>=)

•  Case Insensitive Greater Than or Equal (>=:)

•  Greater Than (>)

•  Case Insensitive Greater Than (>:)

•  Less Than or Equal (<=)

•  Case Insensitive Less Than or Equal (<=:)

•  Less Than (<)

•  Case Insensitive Less Than (<:)

•  Case Insensitive Operators

•  Dot Operator

•  Indexing

•  Built-in Constants

•  True

•  False

•  Escape Sequences

•  Common Scripting Problems

•  Examples for Beginners

•  BAIN wizard Script Highlighter for NotePad++

•  BAIN Wizard Syntax for EmEditor

•  Create a Package Overview Readme

•  Yes/No Question?

•  Check for a Plugin

•  Use SVN features safely

•  Mods with Wizards

•  Wizard to OBMM Script Comparison

•  Functionality with direct correlation to OBMM Script

•  If <function> [...]

•  Else

•  EndIf

•  If DialogYesNo <Message> [Title]

•  If DataFileExists <FileName>

•  If ScriptExtenderPresent

•  If ScriptExtenderNewerThan <version>

•  If GraphicsExtenderPresent

•  If GraphicsExtenderNewerThan

•  If OblivionNewerThan <version>

•  If Equal <arg1> <arg2>

•  Select <Title> <Option1> [Option2] [...]

•  SelectMany <Title> <Option1> [Option2] [...]

•  Case <option>

•  Default

•  Break

•  EndSelect

•  For Count <Variable> <Start> <End> [Step]

•  Return

•  InstallPlugin <Plugin>

•  CopyPlugin <CopyFrom> <CopyTo>

•  EditINI <section> <key> <value>

•  FatalError

•  SetVar <Variable> <Value>

•  StringLength <Variable> <String>

•  iSet <Variable> <expression>

•  ExecLines <lines>

•  SubString <Variable> <String> <startfrom> [length]

•  Functions in OBMM that do not have a direct equivalent, but a similar effect can be achieved in Wizards

•  Message <Message> [Title]

•  DisplayImage <Image File Path> [Title]

•  DisplayText <Text File Path> [Title]

•  ConflictWith <ModName> [Comment] [Level]

•  DependsOn <ModName> [Comment] [Level]

•  DontInstallDataFile <FileName>

•  InstallDataFile <FileName>

•  DontInstallDataFolder <FolderName> [RecurseSubfolders]

•  InstallDataFolder <FolderName> [RecurseSubfolders]

•  CopyDataFile <CopyFrom> <CopyTo>

•  CopyDataFolder <CopyFrom> <CopyTo> [RecurseSubfolders]

•  For Each DataFolder <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

•  For Each DataFile <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

•  For Each PluginFolder <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

•  For Each Plugin <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

•  Functions in OBMM that do not have an equivalent in Wizards

•  SelectVar <Variable>

•  SelectString <Variable>

•  Goto <label>

•  Label <label>

•  LoadBefore <Plugin1> <Plugin2>

•  LoadAfter <Plugin1> <Plugin2>

•  UncheckESP <plugin>

•  SetDeactivationWarning <plugin> <warning>

•  ConflictsWith <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

•  ConflictsWithRegex <ModName> [Comment] [Level]

•  ConflictsWithRegex <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

•  DependsOn <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

•  DependsOnRegex <ModName> [Comment] [Level]

•  DependsOnRegex <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

•  RegisterBSA <FileName>

•  UnregisterBSA <FileName>

•  EditShader <ShaderPackage> <ShaderName> <BinaryObjectPath>

•  SetGMST <file> <Editor ID> <new value>

•  SetGlobal <file> <Editor ID> <new value>

•  SetPluginByte <file> <offset> <new value>

•  SetPluginByte <file> <offset> <new value>

•  SetPluginShort <file> <offset> <new value>

•  SetPluginLong <file> <offset> <new value>

•  SetPluginFloat <file> <offset> <new value>

•  GetFolderName <Variable> <path>

•  GetFileName <Variable> <path>

•  GetFileNameWithoutExtension <Variable> <path>

•  CombinePaths <Variable> <path1> <path2>

•  RemoveString <Variable> <String> <startfrom> [length]

•  InputString <Variable> [Title] [Initial]

•  ReadINI <Variable> <section> <value>

•  ReadRenderInfo <Variable> <value>

•  EditXMLLine <file> <line number> <new line>

•  EditXMLReplace <file> <text to find> <text to replace>

•  Functions in Wizards that do not have an equivalent in OBMM

•  Functions that have no meaning in Wrye Bash

•  If VersionGreaterThan <version>

•  If VersionLessThan <version>

•  PatchDataFile <NewFile> <FileToPatch> [Create]

•  PatchPlugin <NewFile> <FileToPatch> [Create]

•  AllowRunOnLines

Introduction

 

Starting with Wrye Bash version 278, wizards were added to make it easier to install BAIN packages. Wizards allow modders to include a simple configuration script with their packages. All that needs to be done is create a script file name wizard.txt and include it in the package. When run, the wizard will step through a series of dialogs to determine which sub-packages, esps, and esms should be selected. Afterwards, you can install the package using those selections.

 

Dialogs

These are the dialogs that are may be shown while running a wizard. The different ways you might encounter them are listed below.

 

SelectOne

This dialog gives you a list of options, with the option to select one of them. It will be shown when a SelectOne keyword is used. Each option can display an image associated with it, and a description as well. To see a larger version of the image displayed, either right click or middle click on the image. The wizard can specify a default answer, and if you are running it as an Auto-Wizard, then this page will be skipped, using the default option.

 

SelectMany

This dialog gives you a list of options, with the option to select one or more of them, or even none of them. It will be shown when a SelectMany keyword is used. Each option can display an image associated with it, and a description as well. To see a larger version of the image displayed, either right click or middle click on the image. The wizard can specify default options, and if you are running it as an Auto-Wizard, then this page will be skipped, using the default options.

 

Versions

This dialog will show up if the wizard specified minimum version requirements, and your system doesn't meet those requirements. It will be shown if a RequireVersions check fails. If you want to run the wizard anyway, you can override the warning by clicking the "Install Anyway." option, however this is not recommended. If you are running the wizard as an Auto-Wizard, this page will still be shown, but the "Install Anyway." option will already be checked for you.

 

Cancel

This dialog will be shown if the wizard cancels execution for some reason, activated by the Cancel keyword. If a reason is given, it will be displayed

 

Error

This dialog will be shown if the wizard encounters an error in the wizard file. The wizard will then quit.

 

Finish

This dialog will be shown at the end of the wizard, to show you which sub-packages, esps, and esms will be selected. It will be shown either when the end of a wizard file is reached, or if the Return keyword is used. It also shows what INI Tweaks will be applied, and also serves as a place for any extra notes from the mod auther to be displayed.

 

The language

BAIN wizards use a language similar to OBMM script, so modders familiar with OBMM should be able to quickly write BAIN versions of their scripts.

 

Wizards are case sensitive, so ensure you get the case right. The only exception to this is filenames.

 

Each line of the wizard contains one statement. If you want to continue the line onto the next one, just add a backslash ( \ ) to the end of the line. This will cause BAIN to read the next line as is it were part of the first.

 

Variables

You can use variables by assigning a value using an assignment operator. Just make sure you assign a value before using a variable, or it can cause undefined behavior. In the best case, the variable will just be treated as a string with the same value as its name, but this is not guaranteed.

 

Variable names can contain any alpha-numeric characters (a-z,A-Z,0-9) and underscores ( _ ), but cannot start with a digit. You also cannot create a variable with the same name (case sensitive) as a keyword, function, or constant. Variables can be used to hold any of the following types of data:

•  Integers

•  3

•  -1

•  0

•  Decimals

•  0.123

•  -3.5

•  7.0

•  Strings

•  "Hello"

•  'World!'

 

Constants

Constants are a sub-type of variables. They follow the same rules, only they cannot be changed. You cannot create constants yourself, but there are a few pre-defined constants in BAIN.

 

Expressions

BAIN will evaluate expressions following the correct order of operations. For example the expression:

 

3 + 6 * 2

 

Will evaluate to 15 as expected, not 18.

 

Strings

Strings can be denoted by enclosing the text in either single quotes ( ' ), or double quotes ( " ). If you need to include a special character in the string, use an escape sequence. Strings can be added and multiplied using the addition and multiplication operator. You can also test if one string is contained within another using the in operator.

 

Comments (;)

Comments are extra text ignored by the wizard engine, to explain what is going on in the code to other people who might read the wizard file. To start a comment, use a semi-colon; the comment will include everthing following the semi-colon until the end of the line.

 

Functions

 

Functions are called just like in any other language, using the function name followed by arguments inclosed in parenthesis. Arguments must be seperatred by a comma. For example:

 

DummyFunction(arg1, "Hello")

 

CompareObVersion

Used to test the installed version of Oblivion against one you specify.

 

•  Usage:

CompareObVersion(version_string)

•  Arguments:

•  version_string: a string formatted to hold a file version number, like "1.2.3.93". For example the current Oblivion version would be represented as "1.2.0.416"

•  Return:

•  -1: Installed Oblivion version is less than the version specified in version_string.

•  0: Installed Oblivion version is the same as the version specified in version_string.

•  1: Installed Oblivion version is higher than the version specified in version_string.

 

CompareOBSEVersion

Used to test the installed version of OBSE against one you specify.

 

•  Usage:

CompareOBSEVersion(version_string)

•  Arguments:

•  version_string: a string formatted to hold a file version number, like "1.2.3.93". For example OBSE v18 would be represented as "0.0.18.6"

•  Return:

•  -1: Installed OBSE version is less than the version specified in version_string.

•  0: Installed OBSE version is the same as the version specified in version_string.

•  1: Installed OBSE version is higher than the version specified in version_string.

 

CompareOBGEVersion

Used to test the installed version of OBGE against one you specify. If the new version of OBGE/OGE is installed, this will be used for the comparison. Otherwise, this will be compared to the old version or debugged version if installed.

 

•  Usage:

CompareOBGEVersion(version_string)

•  Arguments:

•  version_string: a string formatted to hold a file version number, like "1.2.3.93". For example OBGEv2 version 3 would be represented as "3.0.0.0", while the old OBGE would be "0.1.1.0"

•  Return:

•  -1: Installed OBGE version is less than the version specified in version_string

•  0: Installed OBGE version is the same as the version specified in version_string

•  1: Installed OBGE version is higher than the version specified in version_string

 

CompareWBVersion

Used to test the current version of Wrye Bash agains one you specify.

 

•  Usage:

CompareWBVersion(version_number)

•  Arguments:

•  version_number: a number representing the Wrye Bash version you want to check. For example Wrye Bash version 284 could be intered as either 284 or "284".

•  Return:

•  -1: Installed Wrye Bash version is less than the version specified in version_number.

•  0: Installed Wrye Bash version is the same as the version specified in version_number.

•  1: Installed Wrye Bash version is higher than the version specified in version_number.

 

DataFileExists

Tests for the existance of a file in the Data directory. If the file you are testing for is an ESP or ESM, this will also detected ghosted versions of the file.

 

•  Usage:

DataFileExists(file_name [, ..., file_name_n])

•  Arguments:

•  file_name: a string or variable holding a string, specifying the path relative to the Data directory to test. For example using "testesp.esp" would test for "...path to oblivion...\Data\testesp.esp"

•  Return:

•  True: All of the files exist.

•  False: One or more of the files do not exist.

 

GetEspmStatus

Tests the current status of an esp or espm in the Data directory. This function takes esp/m ghosting into account when testing the status.

 

•  Usage:

GetEspmStatus(file_name)

•  Arguments:

•  file_name: a string or variable holding a string, specifying the path relative to the Data directory for the esp or esm to test.

•  Return:

•  -1: The esp/m does not exist

•  0: The esp/m is not active, imported, or merged (Inactive)

•  1: The esp/m is not active, but has portions imported into the Bashed Patch (Imported)

•  2: The esp/m is active (Active)

•  3: The esp/m is merged into the Bashed Patch (Merged)

 

EditINI

Tells Wrye Bash to create an ini tweak file with some tweaks in it. If the file that you tell Wrye Bash to apply the tweak to is from the current installer or Oblivion.ini, then Wrye Bash will also automatically apply the tweak, otherwise, it will just be generated for the user to apply manually.

 

•  Usage:

EditINI(file_name, section, setting, value [,comment])

•  Arguments:

•  file_name: The name of the ini file you wish to edit, relative to the Data directory.

•  section: The section in the ini where setting resides, or 'set' or 'setGS' (see examples below)

•  setting: The setting you wish to change.

•  value: The value to set the setting to.

•  comment: Optional comment to include with this tweak.

 

•  Examples:

•  Setting an item in Oblivion.ini:

EditINI('Oblivion.ini', 'General', 'bBorderRegionsEnabled', 0)

  

[General]
bBorderRegionsEnabled=0

 

•  Setting an item in a script-like ini: Notice the use of set and setGS as the sections.

EditINI('TargetINI.ini', 'set', 'ANVars.UseEW', 1)
EditINI('TargetINI.ini', 'setGS', 'fPCBaseMagickaMult', 1)

  

set ANVars.UseEW to 1
setGS fPCBaseMagickaMult 1

 

Exec

This will cause the Wizard to execute lines that are passed to it. This is usefull for creating dynamically generated menus.

 

•  Usage:

Exec(lines)

•  Arguements:

•  lines: A string containing lines to execute, seperated by newline characters, or a variable containing such a string.

 

•  Example:

   Would be the same as:

SelectOne 'Do you like icecream?', \
    '|Yes', 'Select this if you like icecream!', 'icecream.jpg', \
    'No', 'Select this if you do not like icecream', 'ihateicecream.jpg'
Case 'Yes'
    Note 'You like icecream!'
    Break
Case 'No'
    Note 'Why don\'t you like icecream?'
    Break
EndSelect

•  Notice how the \\\' was interpreted as \' once the Exec was converted into lines. Remember to add two extra backslashes so the final statement has a backslash in it!

 

str

Used to convert a value into a string, for example when trying to concantenate a integer or decimal to a string.

 

•  Usage:

str(value)

•  Arguments:

•  value: any value. An integer, decimal, variable, constant, or another string.

•  Return:

•  String representation of value. For example, str(5) would return "5".

 

int

Used to convert a value to an integer, for example converting a value held in a string to a integer value.

 

•  Usage:

int(value)

•  Arguments:

•  value: any value. An integer, decimal, variable, constant, or string.

•  Return:

•  Integer value of value, if possible. For example int('65') would return 65.

•  0 if integer conversion is not possible.

 

float

Used to convert a value to decimal, for example converting a value held in a string to a decimal value.

 

•  Usage:

float(value)

•  Arguments:

•  value: any value. An integer, decimal, variable, constant, or string.

•  Return:

•  Decimal value of value, if possible. For example, float('2.4') would return 2.4.

•  0.0 if decimal conversion is not possible.

 

len

Used to find the length of a string.

 

•  Usage:

len(string)

•  Arguments:

•  string: a string, variable, or constant.

•  Return:

•  Length of the string if possible.

•  0 if length calculation was not possible.

 

endswith

Test what a string ends with.

 

•  Usage:

endswith(string, ending_1 [, ..., ending_n])

•  Arguments:

•  string: a string, variable or constant.

•  ending_1 through ending_n: a string, variable or constant.

•  Return:

•  True if the string ends in any of the endings specified.

•  False if the string does not end in any of the endings specified.

 

startswith

Test what a string starts with.

 

•  Usage:

startswith(string, prefix_1 [, ..., prefix_n])

•  Arguments:

•  string: a string, variable or constant.

•  prefix_1 through ending_n: a string, variable or constant.

•  Return:

•  True if the string begins with any of the prefixes specified.

•  False if the string does not begin with any of the prefixes specified.

 

lower

Convert a string to lower case.

 

•  Usage:

lower(string)

•  Arguments:

•  string: a string or variable.

•  Return:

•  string converted to lower case, or

•  The original string if an error occured. For example if you tried to call lower on a non-string type.

 

find

Return index of first occurrance of a substring

 

•  Usage:

find(string, substring [, start, stop])

•  Arguments:

•  string: a string or variable to search in.

•  substring: a string or variable to search for.

•  start: Index at which to start searching in string. (Optional. If not specified, searching will start at the beggining of string)

•  stop: Index at which to stop searching. (Optional. If not specified, searching will stop at the end of string)

•  Return:

•  The index of the first occurance of substring in string

•  -1 if substring could not be found

 

rfind

Return index of last occurrance of a substring

 

•  Usage:

find(string, substring [, start, stop])

•  Arguments:

•  string: a string or variable to search in.

•  substring: a string or variable to search for.

•  start: Index to start searching in string. (Optional. If not specified, searching will start at the beggining of string)

•  stop: Index to start searching. (Optional. If not specified, searching will stop at the end of string)

•  Return:

•  The index of the last occurance of substring in string

•  -1 if substring could not be found

 

GetFilename

For a string that contains a path, returns the filename in that string.

 

•  Usage:

GetFilename(path_string)

•  Arguments:

•  path_string: a string or variable of the path to work with.

•  Return:

•  The filename, or an empty string if there is not a file or if path_string is not a path.

•  Examples:

GetFilename("C:\Program Files\Bethesda Softworks\Oblivion\Oblivion.exe") would return  "Oblivion.exe"
GetFilename("C:\Program Files\Bethesda Softworks\Oblivion") would return an empty string

 

GetFolder

For a string that contains a path, returns the folder part of the string.

 

•  Usage:

GetFolder(path_string)

•  Arguments:

•  path_string: a string or variable of the path to work with.

•  Return:

•  The folder, or an empty string if there is not one, or if path_string is not a path.

•  Examples:

GetFolder("Data\mine.esp") would return "Data"
GetFolder("mine.esp") would return an empty string

 

Keywords

 

Keywords are special identifiers that are used for controlling the flow of your wizard, or perform special tasks. To use a keyword, place it on the beginning of a line, followed by any arguments to the keyword. As of version 292: arguments must be separated by commas.

 

SelectSubPackage

Cause the specified sub-package to be selected for installation. This is equivilant to checking the sub-package and all the esps or esms in that subpackage in the BAIN window.

 

•  Usage:

SelectSubPackage name

•  Arguments:

•  name: string or variable holding the name of the sub-package to select.

 

DeSelectSubPackage

Cause the specified sub-package to be de-selected from installation. This is equivilant to un-checking the sub-package in the BAIN window.

 

•  Usage:

DeSelectSubPackage name

•  Arguments:

•  name: string or variable holding the name of the sub-package to de-select.

 

SelectEspm

Cause the specified esp or esm to be selected for installation. This is equivilant to checking the esp or esm from the BAIN window.

 

•  Usage:

SelectEspm name

•  Arguments:

•  name: string or variable holding the name of the esp or esm to select.

 

DeSelectEspm

Cause the specified esp or esm to be deselected from installation. This is equivilant to un-checking the esp or esm from the BAIN window.

 

•  Usage:

DeSelectEspm name

•  Arguments:

•  name: string or variable holding the name of the esp or esm to de-select.

 

SelectAll

Cause all sub-packages, esps, and esms to be selected for installation. This is equivilant to first checking all sub-packages in the BAIN window, then checking all esps and esms in the BAIN window.

 

•  Usage:

SelectAll

 

DeSelectAll

Cause all sub-packages, esps, and esms to be de-selected from installation. This is equivilant to first un-checking all esps and esms in the BAIN window, then un-checking all sub-packages in the BAIN window.

 

•  Usage:

DeSelectAll

 

SelectAllEspms

Cause all esps and esms to be selected for installation. This is equivilant to checking all esps and esms in the BAIN window

 

•  Usage:

SelectAllEspms

 

DeSelectAllEspms

Cause all esps and esms to be de-selected from installation. This is equivilant to un-checking all esps and esms in the BAIN window.

 

•  Usage:

DeSelectAllEspms

 

RenameEspm

Change the installed name of an esp or esm.

 

•  Usage:

RenameEspm original_name, new_name

•  Arguments:

•  original_name: the name of the esp or esm, as it appears in the BAIN package.

•  new_name: the new name you want to have the esp or esm installed as.

 

ResetEspmName

Resets the name of an esp or esm back to its default name.

 

•  Usage:

ResetEspmName original_name

•  Arguments:

•  original_name: the name of the esp or esm, as it appears in the BAIN package.

 

ResetAllEspmNames

Resets the names of all the esps and esms back to their default names.

 

•  Usage:

ResetAllEspmNames

 

Note

Add a note to the user to be displayed at the end of the wizard, on the finish page. The '- ' will be added automatically.

 

•  Usage:

Note note

•  Arguments:

•  note: string, string variable, or expression that evalutates to a string, to be displayed on the finish page.

 

If-Elif-Else-EndIf

A basic If control block.

 

Usage:

If statement
   lines
Elif statement
   lines
Elif statement
   lines
Else
   lines
EndIf

 

If

•  A begins the control block.

•  If statement evaluates to True, then the lines following it will be run, until the next Elif, Else, or EndIf.

 

Elif

•  If statement evaluates to True, and the initial If and none of the previous Elif's were True, then the lines following this Elif will be run, until the next Elif, Else, or EndIf.

 

Else

•  If the initail If and none of the previous Elif's were True, then the lines following will be run until an EndIf is met.

 

EndIf

•  Signals the end of the If control block.

 

While-Continue-Break-EndWhile

A While loop.

 

Usage:

While statement
    lines
    Continue
    lines
    Break
    lines
EndWhile

 

While

•  Begins the while loop.

•  If statement evaluates to True, execution of the lines begins, otherwise execution skips to after the EndWhile.

 

Continue

•  Signals the while loop to begin over again at the While statement.

 

Break

•  Signals the while loop to end execution, skipping to after the EndWhile.

 

EndWhile

•  Ends the while loop. statement is re-evaluated, and if True, execution begins again at the start of the While block.

 

For-Continue-Break-EndFor

A For loop. There are three possible For loops:

•  For varname from start_value to end_value [by increment_value]

•  varname: variable that will hold values.

•  start_value: Initial value of varname

•  end_value: value of varname that will end the for loop.

•  increment_value: Optional (defaults to 1 or -1 as applicable). This the value that will be added to varname at the end of each run of the loop.

•  For varname in Subpackages

•  varname: variable that will hold the SubPackage names.

•  This loop will iterate over the names of the SubPackages in the current installer.

•  For varname in subpackage_name

•  varname: variable that will hold the file names.

•  subpackage_name: SubPackage to list the files of.

•  This loop will iterate over each of the files contained in the SubPackage subpackage_name. File names will be relative to the Data directory, before any remapping that would normally be done by BAIN.

 

•  Usage:

For arguments
    lines
    Continue
    lines
    Break
    lines
EndFor

For sub in SubPackages
    For file in sub
        lines
    EndFor
EndFor

 

For

•  Begins the for loop.

 

Continue

•  Signals the for loop to begin another iteration.

 

Break

•  Signals the for loop to end execution, skipping to after the EndFor.

 

EndFor

•  Ends the for loop.

 

SelectOne

Shows a dialog where the user can select one option from a list of options. After the user presses the "Next" button, this begins a Select control block.

 

•  Usage:

SelectOne 'description', \
        'option 1', 'description 1', 'image 1', \
        'option 2', 'description 2', 'image 2', \
        ...,  \
        'option n', 'description n', 'image n'
Case 'option 1'
    lines
    Break
Case 'option 2'
    lines
    Break
 
Case 'option n'
    lines
    Break
EndSelect

 

•  Arguments:

•  description: The text that will be displayed at the top of the dialog.

•  option n: The text of the specific option. If the text begins with a "|", this is considered the default option and will be selected by default.

•  description n: The description to display when option n is selected.

•  image n: The image to display when option n is selected. An empty string will make no image display.

 

Case

•  The lines following the Case will be run if the user selected option n on the dialog, until a Break or EndSelect is met.

•  Usage:

Case option n

 

Default

•  The lines following the Default will be run, until a Break or EndSelect, if none of the Case options have been run.

•  Usage:

Default

 

Break

•  Stops running lines in the current Case or Default block.

•  Usage:

Break

 

EndSelect

•  Signals the end of the Select control block.

•  Usage:

EndSelect

 

SelectMany

Shows a dialog where the user can select multiple options from a list. After the user presses the "Next" button, this begins a Select control block. See SelectOne for usage.

 

Return

Signals completion of the wizard. This will jump right to the finish page.

 

•  Usage:

Return

 

Cancel

Cancels the wizard, with an optional text to display in a dialog as to why the wizard was canceled.

 

•  Usage:

Cancel [text]

 

RequireVersions

Tests the users system agains version requirements you specify. If the requirements are not met, a warning dialog will be shown asking if you wish to continue anyway.

 

•  Usage:

RequireVersions oblivion_version [, obse_version, obge_version, wrye_bash_version]

•  Arguments:

•  oblivion_version: Version of Oblivion to for. See CompareObVersion for the proper format of the string.

•  obse_version: Optional. Version of OBSE to test for. See CompareOBSEVersion for the proper format of the string.

•  obge_version: Optional. Version of OBGE to test for. See CompareOBGEVersion for the proper format of the string.

•  wrye_bash_version: Optional. Version of Wrye Bash to test for. See CompareWBVersion for more info.

 

Operators

 

Assignment Operators

 

Assignment operators are how you assign values to variables. The usage can either be to assign one variable a value, or multiple variables the same value:

variable = value
variable1 = variable2 = variable3 = value

 

Assignment (=)

variable = value

 

Compound Assignment (+=, -=, etc)

There are compound assignment operators for all of the math operators. A compound assignment will first perform the math operation using the variable and the value, then assign the result to the variable.

variable += value
variable -= value
variable *= value

 

Math Operators

 

Addition (+)

Adds two values, variables, etc together

 

Subtraction (-)

Subtracts two values, variables, etc.

 

Multiplication (*)

Multiplies two values, variables, etc together.

 

Division (/)

Divides two values, variables, etc.

 

Exponentiation (^)

Raised one value to the power of another value

 

Boolean Operators

Used to test the Truth of values

 

And (&, and)

•  Usage:

left & right
left and right

•  Return:

•  True if both left and right are True.

•  False otherwise.

 

Or (|, or)

•  Usage:

left | right
left or right

•  Return:

•  True if either left or right is True.

•  False if neither left nor right is True.

 

Not (!, not)

•  Usage:

!value
not value

•  Return:

•  True if value is False.

•  False if value is True.

 

In (in)

Case Insensitive In (in:)

•  Usage:

left in right
left in: right

•  Return:

•  True if left is contained in right. For example 'hi' in 'this' would return True.

•  False otherwise.

 

Comparison Operators

Used to compare two values, variables, etc together.

 

Equal (==)

Case insensitive Equal (==:)

•  Usage:

left == right
left ==: right

•  Return:

•  True if left is equal to right.

•  False otherwise.

 

Not Equal (!=)

Case insensitive Not Equal (!=:)

•  Usage:

left != right
left !=: right

•  Return:

•  True if left does not equal right.

•  False otherwise.

 

Greater Than or Equal (>=)

Case Insensitive Greater Than or Equal (>=:)

•  Usage:

left >= right
left >=: right

•  Return:

•  True if left is greater than or equal to right.

•  False otherwise.

 

Greater Than (>)

Case Insensitive Greater Than (>:)

•  Usage:

left > right
left >: right

•  Return:

•  True if left is greater than right.

•  False otherwise.

 

Less Than or Equal (<=)

Case Insensitive Less Than or Equal (<=:)

•  Usage:

left <= right
left <=: right

•  Return:

•  True if left is less than or equal to right.

•  False otherwise.

 

Less Than (<)

Case Insensitive Less Than (<:)

•  Usage:

left < right
left <: right

•  Return:

•  True if left is less than right.

•  False otherwise

 

Case Insensitive Operators

Some of the operators have case insensitive versions, which function the same as their normal versions, but when comparing strings, case is ignored. The case insensitive versions end with a colon (:). The following have case insensitive versions:

 

==:
!=:
>=:
>:
<=:
<:
in:

 

Dot Operator

Some functions can be accesed in an easier way, using the dot operator (.) When accessed in this method, rather than specifying the first argument, the item to the left of the dot operator will be used. The following functions can be called in this way:

 

len
endswith
startswith
lower
find
rfind

 

Indexing

Indexing is used to access specific parts of a sequence like item. Currently, only strings and string variables can be indexed. If you are familiar with Python's indexing syntax, then this will be familiar to you.

 

•  Usage:

•  string[start:stop:step]

•  Arguments:

•  start: index to start at. If not specified, indexing will begin at index 0.

•  stop: index to stop at. If not specified, but the colon(:) is supplied, indexing will stop at the end of the string. Otherwise, only one character will be indexed.

•  step: how to increment when indexing. For example, a value of 2 would make the indexing return every second item. If not specified, a value of 1 will be used.

•  Negative values for start and stop will be relative to the end of the sequence. For example, -1 would mean the first character from the end of the sequence.

 

•  Examples:

"Hello"[0]   returns "H"
"Hello"[0:]  returns "Hello"
"Hello"[:]   returns "Hello"
"Hello"[0:2] returns "He"
"Hello"[-1]  returns "o"
"Hello"[1:3] returns "el"
"Hello"[-2:] returns "lo"

 

Built-in Constants

There are only a few constants that come defined in BAIN wizards.

 

True

•  Value: True (1)

 

False

•  Value: False (0)

 

Escape Sequences

Escape sequences are special sequences of character you can put in a string to get a different character out when used in the wizard

•  '\t': Insert a Tab

•  '\n': Insert a newline character.

 

Common Scripting Problems

Have a problem with your wizard script? Here are some common mistakes that cause errors or other strange behavior.

•  Make sure the Case is right. Ex1: SelectSubPackage NOT SeLEctsUBPaCkaGe Ex2: Break NOT break

•  Mismatched quotes. Ex: 'Plugin.esp" SHOULD BE 'Plugin.esp' or "Plugin.esp"

•  Might be missing a , \ at the end of the line or one \ might need removed. This usually throws an error or not all options will be displayed.

•  Extra spaces or tabs at the end of a line can cause problems with options showing up. Ex: "","",""\                  

•  Missing called Image File.

 

Examples for Beginners

 

BAIN wizard Script Highlighter for NotePad++

 

Notepad++ BAIN wizard Script Hightlighter in action

 

•  It is recommended that you install utumno's BAIN wizard Script Highlighter for Notepad plus plus if you use Notepad++ to write your install scripts.

•  It makes for spotting errors in your script a lot easier.

 

BAIN Wizard Syntax for EmEditor

•  broken85 created a similar Wizard highlighter for EmEditor. It can be found here: BAIN Wizard Syntax for EmEditor

 

Create a Package Overview Readme

•  Every Wizard should have some sort of nice little overview for the user to read before proceeding with the actual installation questions.

•  Notice the following example has no Case's(This is intended) and the Default character is before the 'Start Here_Readme'.

SelectOne "Welcome to the ExampleMod's mod Setup Wizard", \
    "|Start Here_Readme", "If this is the first time you install this mod it's recommended that you carefully read the rest of the selections readme's to have an idea of what the optional parts of this mod do.", "", \
    "ExampleMod Overview", "ExampleText bla bla bla \n\nBla Bla Bla \n\n Bla Bla\n Bla", "", \
    "Changelog", "Example Fixes Release 1.01 \nExample Full Public 1.0 Release \nExample 2nd Beta Release 0.91 \n0.9 - Example Beta Release \n0.3 - Example Alpha Release \n0.01 - Example Initial Release", "", \
    "Guidelines for a Example install", "", "", \
    "ExampleMod Screenshots", "", "Screenshots\\ExampleScreenshot.jpg", \
    "Credits\\Authors", "Wrye - For BAIN. Woooooooot! \nLojack - For the wonderful BAIN wizard installer feature. \nMetallicow - For chewing the cud.", "", \
    "Language", "Language or Nationality this BAIN wizard was written in. \n\n English (USA)", "Wizard Images\\EnglishUSA.jpg"
EndSelect

 

Yes/No Question?

•  Lets say that you want to ask the user a Yes or No question whether to install a feature of your mod.

•  SelectOne in the following example could be replaced by many other Keywords.

•  SelectSubPackage in the following example could be replaced by many other Keywords or even another Yes/No Question Block.

SelectOne "Example: Yes/No Question?", \
      "Yes", "Description", "Wizard Images\\Yes.jpg", \
      "No", "Description", "Wizard Images\\No.jpg"
    Case "Yes"
        SelectSubPackage "00 Example Subpackage" ;;;Action/No Action
        Break
    Case "No"
        ;No Plugin ;;Action/No Action
        Break
EndSelect

 

Check for a Plugin

•  Lets say that you want to check the users data folder for a specific plugin, to check if a patch (you might have created) should apply.

If DataFileExists("ExamplePlugin.esp")
    Note "ExamplePlugin Detected." ;;;Action/No Action
    SelectEspm "PatchPlugin.esp"   ;;;Action/No Action
Else ; ExamplePlugin.esp wasn't detected
    ;No Plugin                     ;;;Action/No Action
EndIf

 

Use SVN features safely

•  You're spruicing up your wizard with some fancy new features that are only availible in the SVN. How will you make sure that your wizard still works for people with the official release?

•  Enclose the 'SVN only' code in a version check.

If CompareWBVersion('292') >= 0
    ; User is running 292+
    ; Do some 292+ only stuff here, like...
    EditINI('Oblivion.ini', 'Display', 'bAllowScreenShot', 1)
Else
    ; User is running < 292, so EditINI is unavailable.
    Note "Don't forget to enable screenshots in Oblivion.ini"
EndIf

 

Mods with Wizards

•  This is a list of some mods that have wizards included with them if you would like to look at them for reference.

•  Animated Window Lighting System and Chimneys - AWLS, Bain Conversion Files, Bananasplit Better Cities, Fast and Easy Frans WIZBAIN Archive Maker -ENGLISH ONLY-, Metallicow Cursor Mod, Unique Landscapes Compilation, Weather - All Natural

 

Wizard to OBMM Script Comparison

This is a comparison of OBMM's OMOD scripting language to BAIN's Wizards.

Functionality with direct correlation to OBMM Script

OBMM

Wizards

If <function> [...]

IfNot <function> [...]

If statement
If not statement

Else

EndIf

Elif
Else
EndIf

If DialogYesNo <Message> [Title]

SelectOne message, "Yes", yes_description, yes_image, "No", no_description, no_image
Case "Yes"
statements
Break
Case "NO"
statements
Break
EndSelect

If DataFileExists <FileName>

If DataFileExists(filename)

If ScriptExtenderPresent

If CompareOBSEVersion("0.0.0.0") == 1

If ScriptExtenderNewerThan <version>

If CompareOBSEVersion(version) == 1

If GraphicsExtenderPresent

If CompareOBGEVersion("0.0.0.0") == 1

If GraphicsExtenderNewerThan

If CompareOBGEVersion(version) == 1

If OblivionNewerThan <version>

If CompareObVersion(version) == 1

If Equal <arg1> <arg2>

If GreaterThan <arg1> <arg2>

If GreaterEqual <arg1> <arg2>

If fGreaterThan <arg1> <arg2>

If fGreaterEqual <arg1> <arg2>

If statement == statement
If statement > statement
If statement >= statement
If statement > statement
If statement >= statement

Select <Title> <Option1> [Option2] [...]

SelectWithPreview <Title> <Option1> <ImagePath1> [Option2] [ImagePath2] [...]

SelectWithDescriptions <Title> <Option1> <Description1> [Option2] [Description2] [...]

SelectWithDescriptionsAndPreviews <Title> <Option1> <ImagePath1> <Description1> [Option2] [ImagePath2] [Description2] [...]

SelectOne title, option1, description1, image1, option2, description2, image2 [...]

SelectMany <Title> <Option1> [Option2] [...]

SelectManyWithPreview <Title> <Option1> <ImagePath1> [Option2] [ImagePath2] [...]

SelectManyWithDescriptions <Title> <Option1> <Description1> [Option2] [Description2] [...]

SelectManyWithDescriptionsAndPreviews <Title> <Option1> <ImagePath1> <Description1> [Option2] [ImagePath2] [Description2] [...]

SelectMany title, option1, description1, image1 [...]

Case <option>

Default

Break

EndSelect

Case option
Default
Break
EndSelect

For Count <Variable> <Start> <End> [Step]

Continue

Exit

EndFor

For variable from start to end by step
Continue
Break
EndFor

Return

Return

DontInstallPlugin <Plugin>

InstallPlugin <Plugin>

DeSelectEspm plugin
SelectEspm plugin

CopyPlugin <CopyFrom> <CopyTo>

RenameEspm original_name new_name

EditINI <section> <key> <value>

EditINI("Oblivion.ini", section, setting, value)

FatalError

Cancel [message]

SetVar <Variable> <Value>

variable = value

StringLength <Variable> <String>

variable = len(string)
variable = string.len()

iSet <Variable> <expression>

fSet <Variable> <expression>

variable = expression

ExecLines <lines>

Exec(lines)

SubString <Variable> <String> <startfrom> [length]

find(variable, string, start, stop)
variable.find(string, start, stop)

Functions in OBMM that do not have a direct equivalent, but a similar effect can be achieved in Wizards

OBMM

Wizards

Message <Message> [Title]

DisplayImage <Image File Path> [Title]

DisplayText <Text File Path> [Title]

Similar functionality can be reproduced using Note and SelectOne or SelectMany keywords.

ConflictWith <ModName> [Comment] [Level]

DependsOn <ModName> [Comment] [Level]

Similar functionality can be reproduced using If DataFileExists(modname)

DontInstallDataFile <FileName>

InstallDataFile <FileName>

DontInstallDataFolder <FolderName> [RecurseSubfolders]

InstallDataFolder <FolderName> [RecurseSubfolders]

CopyDataFile <CopyFrom> <CopyTo>

CopyDataFolder <CopyFrom> <CopyTo> [RecurseSubfolders]

Similar functionality can be obtained by packaging the mod differently, and then using SelectSubPackage and DeSelectSubPackage

For Each DataFolder <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

For Each DataFile <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

For Each PluginFolder <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

For Each Plugin <Variable> <FolderPath> [RecurseSubFolders] [SearchString]

Use:

For subpackage in SubPackages

and/or:

For file in subpackage

to iterate over files and folders in an installer. Then use:

file.lower().endswith(".esp")
GetFilename(file)
GetFolder(file)

and other string manipulation functions to test file names and folders.

 

Functions in OBMM that do not have an equivalent in Wizards

SelectVar <Variable>

SelectString <Variable>

Goto <label>

Label <label>

LoadBefore <Plugin1> <Plugin2>

LoadAfter <Plugin1> <Plugin2>

   Use BOSS in Wrye Bash instead.

UncheckESP <plugin>

SetDeactivationWarning <plugin> <warning>

ConflictsWith <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

ConflictsWithRegex <ModName> [Comment] [Level]

ConflictsWithRegex <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

DependsOn <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

DependsOnRegex <ModName> [Comment] [Level]

DependsOnRegex <ModName> <MinMajorVersion> <MinMinorVersion><MaxMajorVersion> <MaxMinorVersion> [Comment] [Level]

RegisterBSA <FileName>

UnregisterBSA <FileName>

EditShader <ShaderPackage> <ShaderName> <BinaryObjectPath>

SetGMST <file> <Editor ID> <new value>

SetGlobal <file> <Editor ID> <new value>

SetPluginByte <file> <offset> <new value>

SetPluginByte <file> <offset> <new value>

SetPluginShort <file> <offset> <new value>

SetPluginLong <file> <offset> <new value>

SetPluginFloat <file> <offset> <new value>

GetFolderName <Variable> <path>

GetFileName <Variable> <path>

GetFileNameWithoutExtension <Variable> <path>

CombinePaths <Variable> <path1> <path2>

RemoveString <Variable> <String> <startfrom> [length]

InputString <Variable> [Title] [Initial]

ReadINI <Variable> <section> <value>

ReadRenderInfo <Variable> <value>

EditXMLLine <file> <line number> <new line>

EditXMLReplace <file> <text to find> <text to replace>

 

Functions in Wizards that do not have an equivalent in OBMM

CompareWBVersion(version)
GetEspmStatus(plugin)
str(value)
int(value)
float(value)
SelectAll
DeSelectAll
SelectAllEspms
DeSelectAllEspms
While expression
Continue
Break
EndWhile

   Similar loops can be made using Label/Goto and If statements in OBMM.

RequireVersions oblivion, obse, obge, wrye_bash

 

Functions that have no meaning in Wrye Bash

If VersionGreaterThan <version>

If VersionLessThan <version>

   Use CompareWBVersion to check the Wrye Bash version.

PatchDataFile <NewFile> <FileToPatch> [Create]

PatchPlugin <NewFile> <FileToPatch> [Create]

   Unnecessary due to BAIN's conflict resolution of data files.

AllowRunOnLines

   Runon lines have always been supported in Wizards.