WeiDU Documentation

Westley Weimer
weimer@cs.berkeley.edu




Table of Contents
1 About WeiDU

The main home page for WeiDU is: http://weidu.org/. I encourage you to download the latest version.

WeiDU is designed to make it easier to write and distribute modifications to Infinity Engine games. It can load and modify Infinity Engine resources according to instructions you provide. WeiDU is ideal for packaging modifications that include dialogue or that want to be compatible with other modifications.

I'll be honest with you up front: WeiDU is initially harder to use than some of its alternatives. However, most users report that (1) the alternatives are insufficient because they lack features that only WeiDU provides and (2) WeiDU grows on you over time.

You are welcome to use these utilities to make and distribute your own Infinity Engine mods. This utility is covered by the GNU General Public License, but you are also allowed to distribute an unmodified binary copy of WeiDU.EXE (without the source code) with your mod if you like.

I decided to write my own Infinity Engine DLG and TLK utilities because I was unable to get the TeamBG DLG Editor and Mass Converter to work properly. Either they wouldn't parse the strings or they would mangle the text or they would randomly crash ... it was bad all around. Also, they were all GUIs. As a unix weenie I'm in love with command line utilities and as a PL doctoral student I love making little languages and compilers. WeiDU was originally a family of small programs with unimaginative names like DC, DD and TP. The more appealing term ``WeiDU'' (which rhymes with ``IDU'', Eye-Dee-You) was coined by Jason Compton and Ghreyfain, noted BGII mod authors.

2 Don't Panic!

Step-By-Step Beginner's Guide to WeiDU:
  1. Don't Panic. Many of you are children of the GUI era. But programs that run from the command line can be your friend, and in the long run are often much faster and, yes, easier to use.

  2. The Best Way To Learn How To Write Code In WeiDU's D Format Is To Read Code Written In WeiDU's D Format. Start by decompiling existing in-game DLGs that you understand and read through them. Compare how they appear in WeiDU to how they appear in other BG2 editing tools you may be more comfortable with, such as Near Infinity or Infinity Explorer.

  3. The Best Way To Learn How To Write Code In WeiDU's D Format Is To Read Code Written In WeiDU's D Format, Part 2. A growing number of BG2 add-on packs are being created using WeiDU. A list is available at http://www.pocketplane.net/modlist/. These can help you understand how WeiDU's advanced features, such as dialogue appending, script and 2DA patching, and item/spell/creature patching work in a ``real-world'' setting. Make it a point to download some of them and understand HOW they work.

  4. Take a look at some of the examples in this document. There is a lovely WeiDU tutorial (written by Japheth) available at http://forums.pocketplane.net/index.php?topic=55.0. If you are feeling overwhelmed, start there first. It also covers installation. Ghreyfain also has a ``how to create an NPC with WeiDU'' tutorial at http://forums.pocketplane.net/index.php?topic=52.0.

  5. There is a WeiDU discussion board at http://forums.pocketplane.net/index.php?board=50.0. The discussion board is the best place to have your WeiDU (and mod-making) questions answered.

  6. Finally, if you are using a Mac and you want to play around with WeiDU, check out http://weidu.org/Mac.html for more information on obtaining a copy of WeiDU that works under OS X.
3 D and DLG File Concepts

This section is a gentle introduction to how Infinity Engine DLG files are structured. First, let's use WeiDU to create SCSARLES.D and take a look at the dialogue of Sir Sarles.

You may install WeiDU.exe anywhere on your system. However, I recommend that you put it in your Baldur's Gate 2 installation directory. However, WeiDU will use the Windows Registry to attempt to locate your BG2 game files.

To run the effect described, open up a DOS prompt window and change directories to get to your BGII directory. Then just type in the text in red at the DOS Prompt.

C:\Program Files\Black Isle\BGII - SoA\> weidu SCSARLES.DLG


This will create a text file called SCSARLES.D in the current directory. Open it up with Notepad or Microsoft Word or something. It's just a text file that describes the game dialogue.

It will look something like:
// creator  : c:\bgate\weidu\weidu.exe 
// argument : SCSARLES.DLG
// game     : C:\Program Files\Black Isle\BGII - SoA
// source   : C:\Program Files\Black Isle\BGII - SoA\data\Dialog.bif
// dialog   : C:\Program Files\Black Isle\BGII - SoA\DIALOG.TLK
// dialogF  : (none)

BEGIN ~SCSARLES~

IF ~NumTimesTalkedTo(0)~ THEN BEGIN 0 // from:
  SAY #28655 /* ~Who is it? Might I ask why you have disturbed my
    meditations? My creative muse must be gently awakened, and your
    stomping about is simply not conducive to this.~ [SARLES02] */
  IF ~~ THEN REPLY #28656 /* ~My apologies. I will leave you to your
    thinking.~ */ GOTO 1
  IF ~~ THEN REPLY #28657 /* ~I apologize, but I have come to request your
    talent on a commissioned artwork.~ */ 
      DO ~SetGlobal("TalkedToSarles","GLOBAL",1)~ GOTO 2
END

IF ~~ THEN BEGIN 1 // from: 0.0
  SAY #28661 /* ~Then I shall forget you were ever here. Actually, it is an
    astoundingly easy thing to do.~ */
  IF ~~ THEN DO ~SetNumTimesTalkedTo(0)~ EXIT
END
Dialogues in Infinity Engine games behave like finite state machines. If you aren't familiar with the concept of a finite state machine, see http://whatis.techtarget.com/definition/0,,sid9_gci213052,00.html or http://www.c3.lanl.gov/mega-math/workbk/machine/mabkgd.html. Each block of the form:
  IF ~Initial Condition~ THEN BEGIN state1
    SAY ~Something~
    IF ~Reply Condition~ THEN REPLY ~Reply Text~ GOTO state2
  END
represents a state (more details below). When the player starts a conversation with an NPC, the game engine scans through all of the states in that NPC's DLG file in a special WEIGHTed order and picks the one with a non-empty and true "Initial Condition". If no state has a non-empty and true "Initial Condition" then you get that ``Bob - has nothing to say to you.'' message. Don't worry about the weighting process for now.

The speaker (in this case, Sir Sarles) then says whatever appears after SAY. The REPLY lines represent responses the PC can say back. If the "Reply Condition" is true, the player is given the option of saying the "Reply Text" and moving to another state in the dialogue (where Sarles will probably say something else).

Remember: SAY is for what the NPC says, REPLY is for what the player says back. If you think carefully, you'll notice that all dialogue in Infinity Engine games is structed in this manner.

Conditions use the same syntax as triggers do in Infinity Engine BCS scripting. You will need to learn Infinity Engine scripting before too long. Strings are delineated by tildes or %% or "" (your choice, but WeiDU uses the tilde by default). After SAY or REPLY or JOURNAL you may give two Strings instead of one. The first is used with DIALOG.TLK, the second is used with DIALOGF.TLK (foreign language version for when the main character is female). If you do not give two Strings, the one String you gave is used for both.

You may also use raw numbers prefaced with a number sign (like #1234) to specify a strref inside DIALOG.TLK directly. This is useful when modifying existing dialogues (say, the Fate Spirit in ToB) so that you if a foreign user installs your dialogue they will retain all of the foreign versions of the strings you didn't change or add. Normally the string reference numbers are put right after the SAY keyword and the string text is put in comments. The --text command-line option causes string text to be emitted with the string number in comments.

You may also indicate that a sound file (WAV/WAVC) should be associated with a given String by including its up-to-8-letter resource name in [brackets] after the string, as in:
  SAY ~Hello~ [HELLO]
Comments are C/C++ style: everything from // to the end of the line is a comment, as is /* everything in these star-slash things */. Comments are ignored by WeiDU. They are there for your benefit. Example:
  SAY ~Hello~ [HELLO]   // this is a comment        ... way out to here!
  IF /* this is also a comment */ ~~ THEN EXIT
Replies can also contain actions (using the DO keyword) which behave just like Infinity Engine BCS script actions. They can also add Journal entries, end the dialogue or transfer to another speaker.

Examples:
  IF ~~ THEN BEGIN 2 // from: 0.1
This line marks the beginning of state 2 in a dialogue. The comment tells you that it can be reached by the first reply transition from state 0.
  IF ~~ THEN REPLY ~My apologies. I will leave you to your thinking.~ // #28656 
      GOTO 1
This REPLY can always be chosen and involves the spoken text "My apologies...". That text is string reference number 28656. If the PC chooses that reply, it transitions to state 1.

Finally, a transition may also take the form:
  COPY_TRANS filename label
During processing, COPY_TRANS will be replaced by all of the transitions from state "label" of file "filename". The copying takes place before all other D actions.

4 D Dialogue File Format

The D file format is a way of describing Infinity Engine dialogues and modifications to Infinity Engine Dialogues in a portable, easy-to-understand format. It supports foreign language translations and allows you to describe extensions to existing game dialogues without forcing you to describe their content. This allows you to write mods that work with mods written by others.

The D file format is presented here in an extended context-free grammar notation. If you are unfamiliar with CFGs, take a look http://www.wikipedia.com/wiki/Context-free_grammar, http://cs.wpi.edu/~kal/PLT/PLT2.1.2.html or http://www.cs.rochester.edu/users/faculty/nelson/courses/csc_173/grammars/cfg.html. You don't really need to understand a CFG formally, though.

To get a real idea of how they work, use WeiDU to create JAHEIRA.D for yourself and look at it in a text editor. You can also browse the examples and test directories that come with WeiDU.

All of the syntax keywords are given in a UPPERCASE COURIER. All other keywords are symbolic. Notes:
D File   A D file is a text file that contains a number of D Actions. D Files tell WeiDU how to create and modify Infinity Engine DLG files.
is D Action list A D File is a list of D Actions. Typically the first and only one is BEGIN, which defines the content of a new dialogue. Other D Actions can be used to modify existing dialogues.
 
D Action   A D Action tells WeiDU how to create or modify Infinity Engine DLG files.
is BEGIN filename [ nonPausing ] state list BEGIN tells WeiDU that you are creating a new DLG file from scratch. Any existing DLG file with the same name will be overwriten. The new DLG file contains exactly the states in the list. If you set nonPausing to a non-zero integer, the game will not ``stop time'' while the conversation takes place. By default time stops during conversations.
or APPEND filename state list END This tells WeiDU to place the given states at the end of the already-existing dialogue filename.DLG.
or APPEND_EARLY filename state list END Works like APPEND, but the states are added early on in the compilation timeline (just after BEGIN is processed). Thus they can be the targets for INTERJECT_COPY_TRANS and friends.
or CHAIN [ IF [ WEIGHT #weight ] stateTriggerString THEN ] entryFilename entryLabel chainText list chainEpilogue This instructs WeiDU to make a long conversation in which the PC can say nothing. This is useful when you want the NPCs to talk among themselves for a long time. It and its friends, INTERJECT and INTERJECT_COPY_TRANS can incredible time-savers when you're writing non-trivial dialogue. See the examples for ideas. CHAIN will only append to existing dialogues. You cannot use CHAIN to create a new DLG.
or INTERJECT entryFilename entryLabel globalVariable chainText list chainEpilogue Behaves like CHAIN except that all of the chainText is additionally guarded by the transition predicate Global("globalVariable","GLOBAL",0) and accompanied by the action SetGlobal("globalVariable","GLOBAL",1). If you pick globalVariable to be unique, this will ensure that the chainText is only ever seen once per game. This is useful for making interjections.
or INTERJECT_COPY_TRANS entryFilename entryLabel globalVariable chainText list This behaves just like INTERJECT except that the exitFilename and exitLabel are not present. Instead, whenever the dialogue would pass out of the chainText it follows a copy of the transitions that were at the state with stateLabel originally. This is convenient for making quick interjections from NPCs that do not actually change the true flow of the conversation. See the transition COPY_TRANS for more information about this idea.
or INTERJECT_COPY_TRANS2 entryFilename entryLabel globalVariable chainText list This works just like INTERJECT_COPY_TRANS, except that any actions taken in the transitions of the state specified by entryFilename and entryLabel are preserved and kept with the speaker associated with entryFilename (rather than being mistakenly performed by your new speaker). We are expecting more documentation on this feature in the future.
or EXTEND_TOP filename stateLabel list [ #positionNumber ] transition list END This instructs WeiDU to add the transitions in list to the top of the transition list for the specified states in filename.DLG (which must already exist).
If a positionNumber is given, WeiDU to insert the transitions just between already-existing transitions #positionNumber and #positionNumber+1 in the given states for the given file. The first transition is number 1.
or EXTEND_BOTTOM filename stateNumber list [ #positionNumber ] transition list END Behaves just like EXTEND_TOP but adds the transitions to the bottom of the list instead.
or ADD_STATE_TRIGGER filename stateNumber stateTriggerString [ stateNumber list ] This instructs WeiDU to add the stateTriggerString to all of the states with the given stateNumbers in the file filename.DLG (which must already exist). This is handy for adding extra conditions to an existing dialogue state.
or ADD_TRANS_TRIGGER filename stateNumber transTriggerString [ moreStateNumbers list ] [ DO transNumber list ] This instructs WeiDU to add the transTriggerString to all of the transitions in all of the states with the given stateNumbers in the file filename.DLG (which must already exist). This is often used in conjunction with EXTEND_BOTTOM to make a new branch in an existing state. Use ADD_TRANS_TRIGGER to add the negation of some predicate to all of the existing transitions, then use EXTEND_BOTTOM to add a transition with that predicate to that state. If a list of transNumbers is specified, only those transitions will have transTriggerString added to them. If such a list is not specified, every transition in every specified state will be modified. Note that the ``first'' transition is number 0.
or ADD_TRANS_ACTION filename BEGIN stateNumber list END BEGIN transNumber list END transActionString This instructs WeiDU to add the transActionString to all of the transitions in all of the states specified by the stateNumber list and the transNumber list. You may use state labels in the stateNumber list. If the transNumber list is empty, the text added to all transitions on all listed states. Note that the BEGIN and END keywords must be present, even if you specify an empty list of transNumbers. The ``first'' transition is number 0. Any out-of-bounds transNumbers are silently ignored. The transActionString is prepended to any existing action text on a per-transition, per-state basis.
or REPLACE filename state list END This instructs WeiDU to load filename.DLG and replace some of its states with the new ones described in the state list. All of the states should have numeric stateLabels (e.g., "5" or "67"). A new state with label X will replace the old state number X.
or SET_WEIGHT filename stateLabel #stateWeight This instructcs WeiDU to destructively change the WEIGHT of the given state in filename.DLG (which must exist). This should only be used to patch or workaround existing dialogues. Never use SET_WEIGHT if you can help it.
or REPLACE_SAY filename stateLabel sayString This instructs WeiDU to destructively change the sayString of the given state in filename.DLG (which must exist). This should only be used to patch or workaround existing dialogues. Never use REPLACE_SAY if you can help it.
or REPLACE_STATE_TRIGGER filename stateNumber stateTriggerString [ stateNumber list ] This instructs WeiDU to destructively set the stateTriggerString of all of the states with the given stateNumbers in the file filename.DLG (which must already exist). It should be used with caution.
or REPLACE_TRIGGER_TEXT filename oldText newText This instructs WeiDU to destructively replace every occurrence of oldText (which may be a regexp) in the stateTriggerStrings and transTriggerStrings of filename.DLG (which must exist). This should only be used to patch or workaround existing dialogues. Never use this if you can help it.
or REPLACE_TRIGGER_TEXT_REGEXP filenameRegexp oldText newText Just like REPLACE_TRIGGER_TEXT but the filename is a regexp. The .DLG is implied. Do not use this.
or REPLACE_ACTION_TEXT filename oldText newText [ moreFilenames ] This instructs WeiDU to destructively replace every occurrence of oldText (which may be a regexp) in the stateActionStrings of filename.DLG (which must exist). This should only be used to patch or workaround existing dialogues. Never use this if you can help it.
or REPLACE_ACTION_TEXT_REGEXP filenameRegexp oldText newText [ moreFilenameRegexps ] Just like REPLACE_ACTION_TEXT but the filenames are regexps. The .DLG is implied, do not include it in your regexps. Do not use this.
or REPLACE_ACTION_TEXT_PROCESS filename oldText newText [ moreFilenames ] This instructs WeiDU to destruveily replace every occurrence of oldText (which may be a regexp) in the stateActionStrings of filename.DLG (which must exist) with newText. However, newText is first compiled as a BAF action list. In particular, this means that replacing with commands like:
  ~DisplayString(Myself,@123)~
  
... will do what you expect. This should only be used to patch or workaround existing dialogues. Never use this if you can help it.
or REPLACE_ACTION_TEXT_PROCESS_REGEXP filenameRegexp oldText newText [ moreFilenameRegexps ] Just like REPLACE_ACTION_TEXT_PROCESS, but the filenames are regexps. The .DLG is implied. Do not use this.
 
chainEpilogue   Determines where the dialogue should flow at the end of the CHAIN.
is END filename stateNumber Transfer to the given state in the given dialogue file.
or EXTERN filename stateNumber Transfer to the given state in the given dialogue file.
or COPY_TRANS filename stateNumber At the end of the CHAIN text, copy all transitions from the given state in the given file. This is useful for interjections (see INTERJECT).
or EXIT At the end of the CHAIN text, exit the dialogue.
or END transition list Execute the given transitions after the final state in the CHAIN.
 
state   In Infinity Engine games, this is the fundamental unit of dialogue.
is IF [ WEIGHT #weightNumber ] stateTriggerString [ THEN ] [ BEGIN ] stateLabel SAY sayText [ = sayText ... ] transition list END When you start conversing with a creature that uses a DLG file, the Infinity Engine searches through all of the states in that file in order of increasing WEIGHT and selects the first one it finds for which the stateTriggerString is both true and not empty. The creature then says all of the associated sayText. Finally, the transitions are evaluted in bottom-up (i.e., reverse) order. If a transition is found with a transTriggerString that evaluates to True and no replyText, that transition is immediately executed. Otherwise, all of the transitions are presented as options to the PC.

If a stateLabel is an integer it is called a stateNumber. All of the states in the DLG files that come with the original game use stateNumbers. Only D files use symbolic strings for stateLabels.

Including more than one bit of sayText here is often called Multisay.

Finally, once you are familiar with the syntax you may omit the THEN and BEGIN keywords if you like.
or APPENDI filename state list END This is legacy syntax that behaves just like the D Action APPEND but is considered a state. Avoid it.
or CHAIN2 entryFilename entryLabel chain2Text list exitFilename exitLabel This is legacy syntax that behaves somewhat like the D Action CHAIN but is considered a state. In addition, chain2Text is slightly different from chainText. Avoid this construction.
 
sayText   sayText and replyText are displayed to the user as part of a dialogue.
is text sayText and replyText are both text.
 
transition   Transitions determine how dialogue flows from one state to another.
is IF transTriggerString [ THEN ] transFeature list transNext If the transTriggerString evaluates to true or is empty, this transition is viable. If it contains no replyText within its transFeature list, it is immediately taken. Otherwise, the replyText is presented as an option to the user. If the transition is taken, any actions in the transFeature list are performed and the dialogue flows to the point indicated by the transNext. transitions are evaluated in "reverse order". That is, the "bottom" or "last" response for a state is checked first. If its transTriggerString evaluates to true and it has no REPLY text, that transition is immediately taken. See SAREV25A state 1 for an example of a state with all kinds of transitions.
or + [ transTriggerString ] + replyText transFeature list transNext This abbreviated syntax for transitions that would contain REPLY (which is by far the most common case) allows you to save yourself some time and typing. It behaves like the full form above.
or COPY_TRANS filename stateLabel This instructs WeiDU to copy all of the transitions from the state with the given stateLabel in filename.DLG. This copying takes place before all other D Actions. For example, this is a valid transition list:
IF ~Before()~ THEN GOTO my_state
COPY_TRANS PLAYER1 33
IF ~After()~ THEN EXTERN SOLA 55
 
transFeature   These are features or actions associated with taking a transition.
is REPLY replyText If this transition is taken, the PC says the replyText.
or DO stateActionString If this transition is taken, the stateActionString is executed.
or JOURNAL text If this transition is taken, the text is added to the PC's journal.
or SOLVED_JOURNAL text If this transition is taken, the text is added to the ``solved'' section of the PC's journal.
or UNSOLVED_JOURNAL text If this transition is taken, the text is added to the ``unsolved'' section of the PC's journal.
or FLAGS integer This allows you to set the features associated with a transition directly using the binary format of DLG files. Do not use this!
 
transNext   This determines where dialogue flows after a transition has been taken.
is GOTO stateLabel The dialogue continues at the state with label stateLabel in the same DLG file as the current state.
or EXTERN filename stateLabel The dialogue continues at the state with label stateLabel in the file filename.DLG.
or EXIT The conversation ends.
or + stateLabel This is a synonym for GOTO.
 
chainText   This is a rapid shorthand for chaining together many little bits of dialogue when the PC is not saying anything.
is [ IF transTriggerString THEN ] sayText = sayText ...  
followed by [ == fileName [ IF transTriggerString THEN ] sayText = sayText ... ] The == (that's two consecutive equal signs) marks the beginning of a new speaker (indicated by fileName). If the transTriggerString is true or if it is not present, this new speaker says all of its sayText in order.
 
text   This represents strings that are shown to the player, rather than strings that the game uses internally for predicates and actions.
is String [ [WAVEFILE] ] The given string is used for both male and female players. The optional [WAVEFILE] is the associated sound.
or String [ [WAVEFILE] ] String [ [WAVEFILE] ] The first string and sound file are used if the PC is male, the second string and sound file are used if the PC is female. This is useful mainly for international versions of Infinity Engine games.
or #integer The string with reference number #integer from DIALOG.TLK should be used unchanged.
or @integer The last definition of the translation string @integer given in any TRA file should be used.
or !integer text Forced String Reference. As with text in general, but rather than being assigned a new, previously-unused DIALOG.TLK string entry (or merging with an existing one that has the same text), this text is written over DIALOG.TLK string entry #integer. Do not use this feature.
 
String   This is how you tell WeiDU what text you want shown to the player. For international mods or international translations, you may use any encoding you like (that is, you are not restricted to 7-bit characters or Latin-1 or anything like that).
is "abcdef" A string can be any sequence of characters not including a " that is enclosed in ""s.
or ~abcdef~ A string can be any sequence of characters not including a ~ that is enclosed in ~~s.
or %abcdef% A string can be any sequence of characters not including a % that is enclosed in %%s. This is handy for Big5 translations, since " and ~ can be part of Big5-encoded characters.
or ~~~~~abcdef~~~~~ That's five consequtive tildes on each side. A string can be any sequence of characters not including ~~~~~ that is enclosed in ~~~~~s. For example, string #8750 is ~!@#$\%^&*()_+-=[]{}\|;:'",<.>/? and can be given to WeiDU as ~~~~~~!@#$\%^&*()_+-=[]{}\|;:'",<.>/?~~~~~ (the content of the string is shown in red for clarity).
or String ^ String String literal concatenation. The second string is appended to the first string. No whitespace is added. Thus "hello" ^ "World" is the same as "helloWorld".

5 Command Line Options

WeiDU is a command-line utility. GUIs are available, but this document only describes command-line invocation. Use the DOS Shell ("command" or "cmd") to run WeiDU. You control its behavior by passing arguments to it on the command line.

You invoke WeiDU by typing WeiDU and then any number of options and files, as described below.


Compiling And Decompiling
FILE.D Compile FILE to a DLG (dialogue file).
FILE.DLG Decompile FILE to a D (dialogue text file).
number When decompiling a DLG file to a D file, emit only state number. You may specify this multiple times and only the states you specify will be emitted.
numberA-numberB When decompiling a DLG file to a D file, emit only states between numberA and numberB (inclusive). You may specify this multiple times and only the states you specify will be emitted.
FILE.BAF Compile FILE to a BCS (script file).
FILE.BCS Decompile FILE to a BAF (script text file).
--script-style X Use the given BAF/BCS scripting style. X must be BG or BG2 or PST or IWD or IWD2.
--transin X Use FILE as a source of translation strings when processing D and BAF files.
FILE.TRA Equivalent to --transin FILE.TRA.
 
Module Packaging Input And Control
FILE.TP or FILE.TP2 Read FILE and ask the user whether to install, reinstall or uninstall its TP2 Components.
--yes Answer all TP2 questions with 'Yes' and do not prompt for a key to be pressed at the end of TP2 processing.
--uninstall Answer all TP2 questions with 'Uninstall' and do not prompt for a key to be pressed at the end of TP2 processing.
--reinstall Re-install all TP2 components that are already installed and do not promtp for a key to be pressed at the end of TP2 processing.
--ask-every Behave as if ASK_EVERY_COMPONENT were present for all TP2 components.
--continue Continue TP2 processing despite TP2 Action errors.
--debug-assign Print out all values assigned to TP2 variables (even implicit ones created by WeiDU).
--debug-value Print out all values encountered in TP2 processing and the results they evaluate to. Among other things, this is useful for catching parenthesis errors in your values.
 
Automatic Updating Options
--update-all Auto-update all WeiDU setup files (e.g., Setup-MyMod.exe) in the current directory.
--noautoupdate If you are running WeiDU as Setup-MyMod.exe, do not attempt to update yourself or any other mod.
--noselfupdatemsg If you are running WeiDU as Setup-MyMod.exe and it automatically updates itself, do not display a message or ask the user to press return.
 
Infinity Engine Game Location Options
--game X Set main game directory to X. WeiDU looks for CHITIN.KEY and DIALOG.TLK and the override directory in the main game directory (but see --tlkin and --search). WeiDU will look in the current directory and use the registry to find your game. If this fails, you will need to run WeiDU using the --game switch to define the full path to the BG2 directory. WeiDU will also search for BG1, IWD and PST.
--nogame Do not load any default game files. Unless you also specified --tlkin, no DIALOG.TLK will be loaded. Unless you also specified --search, no override directory will be used.
--search X Look in X for input files (cumulative). X is treated as an override directory and is given priority over the default override directory.
 
Game Text (TLK) File Input
--tlkin X Use X as DIALOG.TLK (instead of looking for DIALOG.TLK in the game directory).
--ftlkin X Use X as DIALOGF.TLK (instead of looking for DIALOGF.TLK in the game directory).
FILE.TLK Equivalent to --tlkin X.
--tlkmerge X Merge strings from X over the strings from any other loaded DIALOG.TLK.
 
General Output Options
--out X Emit most output files generated by command-line options (e.g., D, DLG, kits, --biff-get, BAF, BCS, --automate, --traify-tlk, --extract-kits, --list-biff, --cmp-from, --dcmp-from, etc.) to file X. If X is a directory, certain commands (e.g., D, DLG, --biff-get, etc.) will place their output there. Does not affect TP2 processing.
--append X Like --out, but if X is an existing file then the result will be appended to it instead of overwriting it.
--backup X Backup files to directory X before overwriting. Does not affect TP2 processing.
--tlkout X If any strings were added to or changed in the loaded DIALOG.TLK, emit X as an updated version that reflects those changes. Many operations (e.g., compiling D files, --tlkmerge, STRING_SET) can add to or modify DIALOG.TLK.
--ftlkout X If any strings were added to or changed in the loaded DIALOGF.TLK, emit X as an updated version that reflects those changes.
 
Dialogue Text File (D) Options
--noheader Do not emit D header comments.
--nofrom Do not emit D // from: comments.
--full-from Generate complete // from: comments with a slower two-pass process.
--nocom Do not emit ANY D or BAF comments.
--text Emit string text with string references in comments.
--transitive Follow EXTERN links when making D files. See the tutorial on --transitive.
--toplevel Emit only top-level dialogue states -- that is, states with non-empty triggers.
 
Translation Options
--traify X Convert X (which should be a D or TP2 or BAF) so that it uses translation references instead of literal strings. Use --out Y to specify a name for the transformed version of X and its new TRA file.
--traify# X Use with --traify and --traify-tlk. Start the newly-created TRA file at translation string @X instead of @0.
--trans Emit coupled D and TRA files when decompiling a DLG.
--transref Emit string reference numbers in TRA files when using --trans.
--traify-tlk Emit a TRA file for the loaded TLK file (see --tlkin, --out, --min and --traify#).
--make-tlk X Create a TLK file from TRA file X (cumulative, see --tlkout).
--testtrans Test all specified TRA translation files to see if any of them use text that is already in the loaded DIALOG.TLK. If they do you can save translation effort by using string references instead.
--forceify X Convert the given D file to use forced strrefs (see --out, SAY, Forced String Reference).
 
Game Text Repository (TLK) Options
--string X Display string reference #X (cumulative). If you also specify --min or --max, all string references between --min (or 0) and --max (or infinity) will be displayed.
--strfind X Display strings that contain X (cumulative, regexp allowed).
--strapp X Append string X to DIALOG.TLK (cumulative).
 
Game Archive (BIFF) Options
--list-biffs Enumerate all BIFF files in CHITIN.KEY.
--list-files Enumerate all resource files in CHITIN.KEY
--biff X Enumerate contents of BIFF file X (cumulative).
--biff-get X Extract resource X from game BIFFs (cumulative, regexp allowed).
--biff-get-rest X Y ... Every argument given on the command line after --biff-get-rest is treated as if it were preceeded by --biff-get. Use this command to extract multiple different files (or regexps) at once.
--biff-str X Search all game BIFFs for files containing X (regexp allowed).
--biff-value X Search all game BIFFs for files containing value X at offset ADDR. Must be used with --biff-value-at.
--biff-value-at ADDR Gives the offset address for a --biff-value search.
--biff-type X Limit --biff-str or --biff-value searches to resources of type X (cumulative).
--biff-name X When a --biff-str or --biff-value search finds a matching file, assume it has a strref name at offset X and print that name out as well.
--make-biff X Create data/X.bif from all files in folder X and destructively update CHITIN.KEY. Do not use this feature. Do not even think of using this feature without backing up CHITIN.KEY.
--remove-biff X Remove references to BIFF X and all of its resources from CHITIN.KEY. Do not use this feature.
 
Comparison Options (see --out)
--cmp-from X Emit WRITE_BYTEs to turn this file ...
--cmp-to X ... into this one.
--dcmp-fromX Emit REPLACEs to turn this DLG file ...
--dcmp-to X ... into this one.
--tcmp-fromX Compare this TRA file (or directory of TRA files)...
--tcmp-to X ... with this one (or this directory).
--tlkcmp-fromX Emit STRING_SETs to convert this TLK file ...
--tlkcmp-toX ... into this one.
--tlkcmp-use-strings When using --tlkcmp-from, emit commands of the form STRING_SET "Hello" @1 instead of STRING_SET #1 @1.
--bcmp-from X Emit APPLY_BCS_PATCH to turn this BCS file ...
--bcmp-to X ... into this one.
--bcmp-orig X Original file X to apply ...
--bcmp-patch X ... this patch to.
 
Range Options
--min X Lower range for some commands. See --traify-tlk, --tlkcmp-from and --string.
--max X Upper range for some commands.
 
Automatic Module Packaging Options
--automate X Automatically create a TP2 file for resources in folder X. See --out.
--automate-min X Only --automate string references above X.
--extract-kits X Extract all kits starting with kit #X and create TP2 actions to install those kits as part of a module.
 
Resouce Exploration Options
--list-eff X List effects in resource X. See --out.
F.ITM or F.EFF or F.SPL Equivalent to --list-eff F.EXT.
 
Logging Options
--log X Log output and details to X.
--autolog Log output and details to WSETUP.DEBUG.
--logapp Append to log file instead of overwriting it.

Finally, note that WeiDU will not add duplicate strings to DIALOG.TLK. If you instruct WeiDU to make use of the string ``Imoen'' (via SAY or --strapp or whatever) it will re-use any existing definition of ``Imoen'' instead. Two strings are equivalent in this sense only if they have the same text and the same associated sounds (normally strings have no associated sounds).

6 Example Uses
7 WeiDU Tutorials

This section includes tutorials on specific parts of WeiDU. Many of them were contributed by users like you.

7.1 Multisay
This tutorial was thoughtfully provided by Jason Compton.

Although a single SAY line can be of any length, for style purposes (particularly in BG2) it is considered good form to break up very large lines into smaller chunks.

One can easily create a series of simple SAY blocks, one doing GOTO to the next, but if there are no special conditions being checked or actions being taken, you can very easily string several lines together.

Let's say you have a scenery NPC teaching a lesson about the Bill of Rights to the US Constitution.
BEGIN TEACHER

IF ~NumTimesTalkedTo(0)~ THEN BEGIN constitution_1
  SAY ~On September 25, 1789, the First Congress of the United States
    therefore proposed to the state legislatures 12 amendments to the
    Constitution that met arguments most frequently advanced against it. The
    first two proposed amendments, which concerned the number of constituents
    for each Representative and the compensation of Congressmen, were not
    ratified. Articles 3 to 12, however, ratified by three- fourths of the
    state legislatures, constitute the first 10 amendments of the
    Constitution, known as the Bill of Rights.~
  IF ~~ THEN EXIT
END 
This is a perfectly valid block of dialogue, but it is extremely long, and would likely scroll out of the text window for players with lower resolution.

Rather than break each sentence up into a new explicit state, we can use Multisay and save a lot of typing. Multisay is invoked with the = (equals) sign, which tells WeiDU that, "the current speaker should say another line here."

Here's how that D state would look with Multisay:
IF ~NumTimesTalkedTo(0)~ THEN BEGIN constitution_1
  SAY ~On September 25, 1789, the First Congress of the United States
  therefore proposed to the state legislatures 12 amendments to the
  Constitution that met arguments most frequently advanced against it.~
      =
  ~The first two proposed amendments, which concerned the number of
  constituents for each Representative and the compensation of Congressmen,
  were not ratified.~
      =
  ~Articles 3 to 12, however, ratified by three-fourths of the state
  legislatures, constitute the first 10 amendments of the Constitution,
  known as the Bill of Rights.~
  IF ~~ THEN EXIT
END
This will create three dialogue states, separated by simple "click to continue" transitions.

And that's Multisay in a nutshell. Note that (as always with WeiDU) the line break and spacing before and after the = are totally optional, and used here only for illustration.
SAY ~One~ = ~Two~ = ~Three~ 
is perfectly valid as well.

You may Multisay inside almsot any state, so you may use it within an APPEND D Action. This is valid:
APPEND J#KLSYJ
  IF ~~ THEN BEGIN Renal1_1
    SAY ~All right, CHARNAME. I can accept that... you are right, there
    are bigger issues to consider.~ 
      = 
    ~But I hope you do understand why I said something, why it would be
    upsetting to have someone so close to me, in a role like that.~
    IF ~~ THEN EXIT
  END                            // end of state Renal1_1
END                             // end of APPEND J#KLSYJ
However, you cannot use Multisay inside REPLACE, because the nature of REPLACE is to change (that is, replace) a single state, while Multisay's nature is to create multiple states.

7.2 CHAIN
This tutorial was thoughtfully provided by Jason Compton.

CHAIN is an extension of the Multisay concept, simply with multiple participants. If you have two NPCs bantering back and forth for a prolonged period of time, and you do not need to do any special condition checks or actions as they babble, it can get very tedious to set up a separate IF/THEN/BEGIN/SAY block for each line.

Imagine a conversation like this: If you wanted to add this witty little banter to your game, you could do it with 11 APPEND blocks for each line, or save a little time doubling up the back-to-back Imoen and Kelsey lines with Multisay inside their APPENDs, so you'd only need 9. In fact, you could get away with 2 APPEND blocks (remember that the states don't have to appear in the order they are spoken, so you could mention all of Kelsey's lines first and then all of Immy's as long as the labels thread up the conversation correctly), one with 5 state declarations and one 4. But there's an even better way, and that's to use CHAIN. It works very much like Multisay. You use = to indicate that the current speaker should speak again, and == (that's two consecutive equal signs) to indicate that a new speaker should take over.

Note that as of WeiDU 82, CHAIN can now define state triggers, perform DO actions, and end with an EXIT or COPY_TRANS. This means that for most simple NPC/NPC banters, where the PC does not have an opportunity to speak, you no longer need to use anything else.

Watch and see how this dialogue works using a CHAIN.
CHAIN
  IF ~Global("KelseyImoenPizza","LOCALS",0)
      InParty("Imoen2")
      See("Imoen2")
      !StateCheck("Imoen2",STATE_SLEEPING)~ THEN BJKLSY pizzachain
  ~Imoen, what do you like on your pizza?~
DO ~SetGlobal("KelseyImoenPizza","LOCALS",1)~
  == IMOEN2J
  ~Oregano.~
  =
  ~Oh, and maybe with a little basil mixed in.~
  == BJKLSY
  ~Well, yeah, but anything else?~
  == IMOEN2J
  ~Sauce is good.~
  == BJKLSY
  ~(laughs) You're not being very helpful, Imoen.~
  == IMOEN2J
  ~Crust. I like crust on my pizza. Cooked crust is better.~
  == BJKLSY
  ~Do you want me to make you this pizza or not?~
  =
  ~It WAS your idea.~
  == IMOEN2J
  ~I can't decide. Never mind, I'm just gonna have yogurt.~
  == BJKLSY
  ~(sigh)~
EXIT 
Note how this dialogue works.

We use the CHAIN statement to define the state trigger (the starting conditions that must be true) and assign it to BJKLSY.DLG. The "pizzachain" label is mostly just for internal reference. Kelsey delivers the first line, then we use == IMOEN2J to allow her to answer, "Oregano." Then, we can use the single = to indicate that the current speaker (Imoen) has two consecutive lines.

Then it's Kelsey's turn to speak, so we use == BJKLSY to tell WeiDU to tell WeiDU to switch to the other speaker (which is Kelsey, since we specified BJKLSY. They banter back and forth for a while, and then when it is Kelsey's turn to have back-to-back lines Do you want me to make you this pizza or not? and It WAS your idea., we separate with a single = to indicate that the current speaker (Kelsey) has two consecutive lines.

After Kelsey's final, exasperated sigh, we use the EXIT command to terminate the CHAIN, and exit the dialogue.

And that's all you need to know to use CHAIN. It saves a tremendous amount of time over setting up individual APPEND blocks, even Multisay blocks, for each NPC.

Advanced CHAINing:

You may include DO actions and conditionals inside chainText, as in:
CHAIN
  IF ~Global("KelseyImoenPizza","LOCALS",0)
      InParty("Imoen2")
      See("Imoen2")
      !StateCheck("Imoen2",STATE_SLEEPING)~ THEN BJKLSY pizzachain
  ~Imoen, what do you like on your pizza?~
DO ~SetGlobal("KelseyImoenPizza","LOCALS",1)~
  == IMOEN2J
    ~Oregano.~
    =
    ~Oh, and maybe with a little basil mixed in.~

  == BJKLSY
    ~Well, yeah, but anything else?~

  == IMOEN2J
    ~Sauce is good.~

    == BJKLSY   IF ~PartyHasItem("pepperoni")~ THEN
      ~Look, we HAVE pepperoni. Why don't I just use that? I'll eat it,
      anyway. If you don't like it, have yogurt instead.~

    == IMOEN2J  IF ~!PartyHasItem("pepperoni")~ THEN
      ~Crust. I like crust on my pizza. Cooked crust is better.~
    == BJKLSY IF ~!PartyHasItem("pepperoni")~ THEN
      ~Do you want me to make you this pizza or not?~
      =
      ~It WAS your idea.~

    == IMOEN2J  IF ~!PartyHasItem("pepperoni")~ THEN
      ~I can't decide. Never mind, I'm just gonna have yogurt.~
    == BJKLSY IF ~!PartyHasItem("pepperoni")~ THEN
      ~(sigh)~
EXIT
In this case, the dialogue changes if the party has the pepperoni item. If it does, Kelsey says the we HAVE pepperoni and then (sigh) and then the dialogue ends. If not, the dialogue works as before. The chainText lines with IFs in them are only spoken if their conditionals are true.

7.3 COPY_TRANS

This tutorial was thoughtfully provided by Jason Compton.

There are