WeiDU DocumentationValerio Bigiani, AKA The Bigg |
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.
Step-By-Step Beginner’s Guide to WeiDU:
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 EXITReplies 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.1This 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 labelDuring 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.
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 [ IF_FILE_EXISTS ] filename state list END | This tells WeiDU to place the given states at the end of the already-existing dialogue filename.DLG. If there is IF_FILE_EXISTS and the file doesn’t exists, this action is skipped. |
| or | APPEND_EARLY [ IF_FILE_EXISTS ] 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 ] [ IF_FILE_EXISTS ] 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. If the entryFilename file is missing and there is IF_FILE_EXISTS, the whole CHAIN is not compiled. |
| 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 and the INTERJECT_COPY_TRANS tutorial 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). See the INTERJECT_COPY_TRANS2 tutorial. |
| or | INTERJECT_COPY_TRANS3 entryFilename entryLabel globalVariable chainText list | This works just like INTERJECT_COPY_TRANS, except that all states in chainText get a link in the entry state, rather than only the first one. Expecting documentation. |
| or | INTERJECT_COPY_TRANS4 entryFilename entryLabel globalVariable chainText list | This is either INTERJECT_COPY_TRANS3 with INTERJECT_COPY_TRANS2-style action handling, or INTERJECT_COPY_TRANS2 with the extended INTERJECT_COPY_TRANS3 state creation rules, depending at how you look at it. |
| 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 actions in all 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_TRANS_ACTION filename BEGIN stateNumber list END BEGIN transNumber list END oldText newText | This instructs WeiDU to replace all instances of oldText in newText to all of the actions in all 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. |
| or | REPLACE_TRANS_TRIGGER filename BEGIN stateNumber list END BEGIN transNumber list END oldText newText | This instructs WeiDU to replace all instances of oldText in newText to all of the triggers in 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. |
| or | ALTER_TRANS filename BEGIN stateNumber list END BEGIN transNumber list END BEGIN changeWhat changeInto list END | Fine altering of a single transition. See the ALTER_TRANS tutorial. |
| 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 | R_A_T_P_R filenameRegexp oldText newText [ moreFilenameRegexps ] | Just like REPLACE_ACTION_TEXT_PROCESS, but the filenames are regexps. The .DLG is implied. Do not use this. R_A_T_P_R is shortand for REPLACE_ACTION_TEXT_PROCESS_REGEXP (to avoid undue scrollbars in the readme on a 1024x768 monitor). |
| 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 [ IF_FILE_EXISTS ] filename stateLabel | The dialogue continues at the state with label stateLabel in the file filename.DLG. The whole transition is not compiled if there’s IF_FILE_EXISTS and the file filename doesn’t exist. |
| 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 | [ == [ IF_FILE_EXISTS ] 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. If the IF_FILE_EXISTS part is present, these lines are not compiled at all if the current file is not missing. |
| or followed by | BRANCH transTriggerString BEGIN [ == [ IF_FILE_EXISTS ] fileName [ IF transTriggerString THEN ] sayText = sayText ... ] END | As above, except that the first transTriggerString is appended to all existing dialogue units. |
| 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". |
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.
Note: since it may not be obvious, if an option accepts ’X’ and says to be cumulative, if you want to apply it multiple times you have to use the following hideousness:
weidu --string 1 --string 2 --string 3
This does not apply to *-rest commands like --biff-get-rest and --force-install-rest.
Moreover, *-rest commands must be the last, EG
weidu --biff-get-rest sw1h01.itm --out foo
will try to extract sw1h01.itm, --out and foo from the biffs; you have to express the above as
weidu --out foo --biff-get-rest sw1h01.itm
*-list commands work like the -rest variants, except that they stop parsing for the current switch once they find an option starting with ’-’. Basically, this works like you’d expect:
weidu --biff-get-list sw1h01.itm --out foo
| 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 BG1 or BG2 or PST or IWD or IWD1 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. |
| --languagem X | Sets the TP2 Language to the one passed here. Has no effect if the value is bigger than the language count (I.E. you’ll get asked for the language, unless you gave --uninstall, --reinstall or --force-uninstall). |
| --force-install X | installs component number X, skips the others (cumulative). |
| --force-uninstall X | uninstalls component number X, skips the others (cumulative). If there is no --force-install, you don’t get asked for the language. |
| --force-install-rest X Y... | installs component number X Y..., skips the others (cumulative). |
| --force-uninstall-rest X Y... | uninstalls component number X Y..., skips the others (cumulative). |
| --force-install-list X Y... | installs component number X Y..., skips the others (cumulative). |
| --force-uninstall-list X Y... | uninstalls component number X Y..., skips the others (cumulative). |
| --skip-at-view | AT_* VIEW this actions (and the extra chromosome versions like NOTEPAD this ) aren’t processed, while still processing batch files and similia. |
| --ask-every | Behave as if ASK_EVERY_COMPONENT were present for all TP2 components. |
| --continue | Continue TP2 processing despite TP2 Action errors. |
| --args X | X will be stored in the tp2 variable %argv[n]%, where
n is 0 for the first argument, 1 for the second, etc. If the installation is non-interactive, said variables will be loaded from the last interactive session. |
| --args-rest X Y... | X Y Z will be stored in the tp2 variables %argv[n]%,
where n is 0 for the first argument, 1 for the second, etc.If the installation is non-interactive, said variables will be loaded from the last interactive session. |
| --args-list X Y... | X Y Z will be stored in the tp2 variables %argv[n]%,
where n is 0 for the first argument, 1 for the second, etc.If the installation is non-interactive, said variables will be loaded from the last interactive session. |
| --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. |
| --clear-memory | calls CLEAR_MEMORY after every TP2 action. |
| 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. |
| --traify-old-tra X | Assumes file X to contain strings already in .tra format. Use this over --traify# for merging new strings in an already traified D or TP2 or BAF file. |
| --untraify-d X | convert .D file X to use hardcoded strings... |
| --untraify-tra X | ...from TRA file X. Please note that the outcoming file
could not work properly (if baf code embedded in a d file contains @ references, or if a string contains
the~ character). |
| --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-get-list X Y ... | Every argument given on the command line after --biff-get-rest is treated as if it were preceeded by --biff-get, with the -list exception. 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. If not specified, it is assumed as 62169 (that is, the number of strings in unmodded SoA). |
| --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).
C:\Program Files\Black Isle\BGII - SoA\> weidu bodhi.dlg
[C:\Program Files\Black Isle\BGII - SoA\chitin.key] 182 BIFFs, 41793 resources [C:\Program Files\Black Isle\BGII - SoA\DIALOG.TLK] 84458 string entries [C:\Program Files\Black Isle\BGII - SoA\data\Dialog.bif] 2729 file entries [BODHI.DLG] loaded [.\BODHI.D] created from [BODHI.DLG]
This loads BODHI.DLG from the standard search path (i.e., the current directory, your override directory, then the game BIFFs) and creates BODHI.D from it.
C:\Program Files\Black Isle\BGII - SoA\> weidu bodhi.dlg --trans
... [.\BODHI.TRA] created as translation file [.\BODHI.D] created from [BODHI.DLG]
This creates BODHI.D as above and also the translation file BODHI.TRA (listing all of the strings in BODHI.D in an easy-to-traslate or spell-check format). BODHI.D will be created with special references to those strings.
This is particularly useful if you are converting existing modifications you may have created with another tool, such as IDU, into WeiDU format. It allows you to both create the WeiDU D code and the translation-friendly string labels at the same time.
C:\Program Files\Black Isle\BGII - SoA\> weidu --nofrom bodhi.dlg --out foozle.d --text
... [.\foozle.d] created from [BODHI.DLG]
This creates foozle.d (instead of BODHI.D) and does not put any "// from:" comments in foozle.d. It will include states with SAYs of the form
SAY ~Hello~ /* #1 */instead of
SAY #1 /* ~Hello~ */
C:\Program Files\Black Isle\BGII - SoA\> weidu bodhi.dlg jaheira.dlg --out test
... [test\JAHEIRA.D] created from [JAHEIRA.DLG] [test\BODHI.D] created from [BODHI.DLG]
This loads BODHI.DLG and JAHEIRA.DLG and creates BODHI.D and JAHEIRA.D. The optional --out test argument instructs WeiDU to put the resulting D files in the test directory.
C:\Program Files\Black Isle\BGII - SoA\> weidu bodhi.d
... [bodhi.d] parsed [BODHI.DLG] saved 135 states, 259 trans, 16 strig, 66 ttrig, 54 actions
This loads and parses bodhi.d and then executed all instructions in it. This bodhi.d file just defines BODHI.DLG, which is created. If bodhi.d contains strings that do not occur in DIALOG.TLK, BODHI.DLG will be created with invalid string references.
C:\Program Files\Black Isle\BGII - SoA\> weidu bodhi.d --tlkout new-DIALOG.TLK
... [bodhi.d] parsed [BODHI.DLG] saved 135 states, 259 trans, 16 strig, 66 ttrig, 54 actions [new-DIALOG.TLK] created, 84459 string entries
This loads and parses bodhi.d and then executed all instructions in it. This bodhi.d file just defines BODHI.DLG, which is created. If there are any new strings a new version of DIALOG.TLK is written to new-DIALOG.TLK.
C:\Program Files\Black Isle\BGII - SoA\> weidu ppworker.d bodhi.d --out test
... [bodhi.d] parsed [ppworker.d] parsed [BODHI.DLG] saved 135 states, 259 trans, 16 strig, 66 ttrig, 54 actions [PPWORKER.DLG] saved 33 states, 81 trans, 4 strig, 12 ttrig, 10 actions
This creates test/BODHI.DLG and test/PPWORKER.DLG based on the instructions in bodhi.d and ppworker.d. If these D files include new text, use --tlkout to make a new DIALOG.TLK.
C:\Program Files\Black Isle\BGII - SoA\> weidu examples/sola/solae1.d
OR
C:\Program Files\Black Isle\BGII - SoA\> weidu examples\sola\solae1.d
... [examples/sola/solae1.d] parsed [SOLA.DLG] loaded [SOLA.DLG] saved 336 states, 401 trans, 64 strig, 18 ttrig, 125 actions [SOLAE1.DLG] saved 36 states, 49 trans, 1 strig, 11 ttrig, 1 actions [SOLAE2.DLG] saved 3 states, 3 trans, 0 strig, 0 ttrig, 0 actions [SOLAE3.DLG] saved 2 states, 2 trans, 0 strig, 0 ttrig, 0 actions [SOLAE4.DLG] saved 3 states, 3 trans, 1 strig, 0 ttrig, 0 actions [SOLAE5.DLG] saved 2 states, 2 trans, 0 strig, 0 ttrig, 0 actions [SOLAE6.DLG] saved 4 states, 5 trans, 0 strig, 2 ttrig, 0 actions
It just so happens that solae1.d APPENDs text to SOLA.DLG and creates SOLAE1.DLG, SOLAE1.DLG, SOLAE3.DLG, ..., SOLAE6.DLG. You could have put them all in the override directory with --out override. You may use the forward slash (/) or the backslash (\) for directories. Use --tlkout to make a new DIALOG.TLK if these contain new text.
C:\Program Files\Black Isle\BGII - SoA\> weidu examples/sola/solafoe.d --transin examples/sola/solafoe.tra
OR
C:\Program Files\Black Isle\BGII - SoA\> weidu examples/sola/solafoe.d examples/sola/solafoe.tra
... [examples/sola/solafoe.tra] parsed (15 translation strings) [examples/sola/solafoe.d] parsed [SOLA.DLG] loaded [SOLA.DLG] saved 336 states, 401 trans, 65 strig, 18 ttrig, 124 actions [SOLAFOE.DLG] saved 11 states, 14 trans, 1 strig, 2 ttrig, 1 actions
It happens that solafoe.d uses 15 strings from a translation file, APPENDs to SOLA.DLG and creates SOLAFOE.DLG. You may use --transin to specify a translation file or (if it ends in TRA) just throw it on the command line. If you include multiple TRA files, the last one to define a particular string index wins for that string. They need not all cover the same set. Use --tlkout if there is new text involved.
C:\Program Files\Black Isle\BGII - SoA\> weidu --string 123 --strfind understudy --strfind acid.*rows
...
[C:\Program Files\Black Isle\BGII - SoA\chitin.key] 182 BIFFs, 41793 resources
[C:\Program Files\Black Isle\BGII - SoA\DIALOG.TLK] 84458 string entries
String #123 is ~Haer' Dalis, all of you, stop them!~
String #6763 is ~Acid Arrows~
String #11662 is ~Biff The Understudy~
...
This displays string #123 and all strings that contain the string "understudy" and all strings that match the regular expression (regexp) "acid.*rows". Note that case does not matter.
C:\Program Files\Black Isle\BGII - SoA\> weidu --strapp ANewString --tlkout happy.tlk
[C:\Program Files\Black Isle\BGII - SoA\DIALOG.TLK] 84458 string entries [.\happy.tlk] created, 84459 string entries
Not much to say here. String reference #84459 in happy.tlk is now “ANewString”.
C:\Program Files\Black Isle\BGII - SoA\> weidu --biff data/dialog.bif
...
[data\Dialog.bif] contains ABELA.DLG at index 0
[data\Dialog.bif] contains ACHEN.DLG at index 1
...
This shows all of the resources (e.g., ACHEN.DLG is a resource) that are contained in data/Dialog.bif.
C:\Program Files\Black Isle\BGII - SoA\> weidu --biff-get dragred.cre
[C:\Program Files\Black Isle\BGII - SoA\chitin.key] 182 BIFFs, 41793 resources [C:\Program Files\Black Isle\BGII - SoA\DIALOG.TLK] 84458 string entries [C:\Program Files\Black Isle\BGII - SoA\data\Creature.bif] 3194 file entries [.\dragred.cre] 1776 bytes, created from [C:\Program Files\Black Isle\BGII - SoA\data\Creature.bif]
This grabs Firkraag’s dragon-form CRE creature file from the game BIFFs and saves it in the current directory.
C:\Program Files\Black Isle\BGII - SoA\> weidu --biff-get sper.*itm
[.\chitin.key] loaded, 590551 bytes [.\chitin.key] 182 BIFFs, 41793 resources [.\DIALOG.TLK] loaded, 10154904 bytes [.\DIALOG.TLK] 77666 string entries [.\data\Items.bif] loaded, 659688 bytes [.\data\Items.bif] 1990 file entries [.\SPER01.ITM] 266 bytes, created from [.\data\Items.bif] [.\SPER02.ITM] 314 bytes, created from [.\data\Items.bif] [.\SPER03.ITM] 362 bytes, created from [.\data\Items.bif] [.\SPER04.ITM] 322 bytes, created from [.\data\Items.bif] [.\SPER05.ITM] 266 bytes, created from [.\data\Items.bif] [.\SPER06.ITM] 266 bytes, created from [.\data\Items.bif] [.\SPER07.ITM] 554 bytes, created from [.\data\Items.bif] [.\SPER08.ITM] 314 bytes, created from [.\data\Items.bif] [.\SPER09.ITM] 314 bytes, created from [.\data\Items.bif] [.\SPER10.ITM] 362 bytes, created from [.\data\Items.bif] [.\data\25Items.bif] loaded, 222370 bytes [.\data\25Items.bif] 479 file entries [.\SPER11.ITM] 314 bytes, created from [.\data\25Items.bif] [.\SPER12.ITM] 1610 bytes, created from [.\data\25Items.bif] [.\SPERMEL.ITM] 890 bytes, created from [.\data\25Items.bif]
This one assumes that the game is in the current directory and asks for every spear item in the game. Note that --biff-get uses regular expressions (regexp), not DOS-style wildcards. Note also that --biff-get does not look in the override directory. Finally, if you are using a Mac (or otherwise running unix) you’ll want to put the regular expression in double quotes, like so: C:\Program Files\Black Isle\BGII - SoA\> weidu --biff-get "sper.*itm"
C:\Program Files\Black Isle\BGII - SoA\> weidu --biff-type CRE --biff-str SPWI911
...
LICH01.CRE in [data\Creature.bif] matches
HLKANG.CRE in [data\Creature.bif] matches
...
This finds all CRE files that contain the string "SPWI911", which is equivalent to finding all enemy mages that know the spell Meteor Swarm (which has resource name "SPWI911"). You could also try something like:
C:\Program Files\Black Isle\BGII - SoA\> weidu --biff-type BCS --biff-str Terminsel
...
AR0300.BCS in [data\Scripts.bif] matches
AR0308.BCS in [data\Scripts.bif] matches
JAHEIRA.BCS in [data\Scripts.bif] matches
...
to find all of the game scripts that include a variable that includes the substring "Terminsel". As you would expect, Jaheira shows up. Note that these searches are moderately time-consuming (e.g., searching all scripts takes about 20 seconds).
C:\Program Files\Black Isle\BGII - SoA\> weidu --tlkcmp-from DIALOG.TLK --tlkcmp-to dialog-asc.tlk
...
[DIALOG.TLK] loaded, 8692747 bytes
[DIALOG.TLK] 74107 string entries
[dialog-asc.tlk] loaded, 10211578 bytes
[dialog-asc.tlk] 82805 string entries
WARNING: DIALOG.TLK has 74107 entries, dialog-asc.tlk has 82805 entries
STRING_SET 70866 ~Babau~ []
STRING_SET 70867 ~Babau~ []
This compares all strings in common between two DIALOG.TLK files and generates a list of STRING_SET TP2 entries to convert the TLK file named in --tlkcomp-from into the TLK file named in --tlkcomp-to. In this case, WeiDU indicates there are two differences in the strings shared between a standard ToB TLK file and an Ascension Classic TLK file: strings 70866 and 70867 were changed to "Babau". Also note that the Ascension Classic TLK file has more entries (82805 compared to 74107).
If you have made a large number of manual changes to a TLK file (such as grammar/spelling corrections, or other dialogue tweaks), this is a handy way to generate install-ready scripting to apply those changes to an end user’s version of BG2.
Note that the use of --out will be helpful for a long list.
C:\Program Files\Black Isle\BGII - SoA\> weidu --tlkcmp-from DIALOG.TLK --tlkcmp-to dialog-asc.tlk --out mylist.txt
This will make a new file mylist.txt file that contains the STRING_SET parts of the output, which can then be put into a TP2 file.
C:\Program Files\Black Isle\BGII - SoA\> weidu --automate MyMod/SomeFolder --append MyMod.tp2
WeiDU’s --automate feature can save you oodles of time, so you probably will want to learn how to use it. It’s rather simple when you get the hang of it (but everything is right?).
Suppose you have just created some items, some spells and some creatures and some areas for you mod and you want to distribute them to others using WeiDU. You could manually write out string patching code by hand for each resource. Or you can get WeiDU to do it automatically.
WeiDU will scan every item, spell and creature inside the given folder (in this example, the folder is MyMod/SomeFolder) and emit TP2 commands to COPY those resources from that folder into the override folder. In addition, each resource’s current strings (like item descriptions and monster names) will be loaded from your TLK file and used to patch that resource as it is copied.
For example, the output of --automate on a folder that contains a potion of extra healing looks like this:
COPY ~MyMod/SomeFolder/potn52.itm~ ~override/potn52.itm~
SAY NAME ~Potion~
SAY NAME2 ~Potion of Extra Healing~
SAY UNIDENTIFIED_DESC ~Potions are typically found in ceramic, crystal, glass,
or metal flasks or vials. Flasks or other containers generally contain
enough fluid to provide one person with one complete dose to achieve the
effects of the potion.~
SAY DESC ~When wholly consumed, this potion restores 27 hit points to the
person. The effect is instantaneous and the potion is destroyed in the
process.~
SAY 0xde ~Gulp!~ [GULP]
And there you have it, apparently there is a substitute for hard work.
Some translators who are using WeiDU to translate non-WeiDU mods find it handy to be able to convert between TLK and TRA files.
First, let’s create a TRA file:
C:\Program Files\Black Isle\BGII - SoA\> weidu --traify-tlk --min 2000 --max 2002
...
@2000 = ~Indeed! It's been quite tasty so far. Listen, we're not here to
devour everything. In fact, we'd like to help a little girl named
Jaella.~
@2001 = ~No, we haven't. We will devour you if you don't tell us what we
need to know.~
@2002 = ~Let us stop this charade. I'm only here to ask you a few
questions.~
...
You may also extract only those strings matching a regexp:
C:\Program Files\Black Isle\BGII - SoA\> weidu --traify-tlk --strfind lawyer
...
@36568 = ~Honor-bound and honor-branded, then, is it? Very well, lawyer,
you have set me free and for that I thank you.~
...
Finally, you may redirect the output to a file using --out and read from a different TLK file by adding it on the command line.
Once you have a TRA file with a few entries you can create a TLK file from it:
C:\Program Files\Black Isle\BGII - SoA\> weidu --make-tlk my.tra --tlkout new.tlk
[c:\src\weidu\weidu.exe] WeiDU version 109 [C:\Program Files\Black Isle\BGII - SoA/chitin.key] 182 BIFFs, 41793 resources [C:\Program Files\Black Isle\BGII - SoA/dialog.tlk] 82405 string entries [my.tra] parsed [my.tra] has 100 translation strings New TLK will have 200 entries [new.tlk] created, 200 string entries
String @1 in your TRA file will become string reference #1 in the TLK file. If your TRA file has “holes” the new TLK file will have blank entries. You may specify --make-tlk multiple times: the last TRA file to define a translation string determine that string reference.
This tutorial was thoughtfully provided by Japheth.
Using --make-biff is dead easy. Here’s a quick and dirty example:
Assuming WeiDU is in your BGII directory, grab a bunch of files from your override folder and stick them into a folder inside your BGII directory. We’ll call the folder mybiff for this example.
Once the files are inside the folder, this is all you would have to do to make WeiDU create a biff of the files:
C:\Program Files\Black Isle\BGII - SoA\> weidu --make-biff mybiff
[c:\src\weidu\weidu.exe] WeiDU version 122
[./chitin.key] 182 BIFFs, 41793 resources
[./dialog.tlk] 82479 string entries
[data\mybiff.bif] will contain 20 resources totalling 211096 bytes
[data\mybiff.bif] incorporating [mybiff/udsola02.cre]
...
[data\mybiff.bif] incorporating [mybiff/sola10.cre]
KEY saved (183 biffs, 41813 resources)
WeiDU will add the files into the BIFF mybiff.bif and stick that file in your data directory. It will also update the CHITIN.KEY.
Before using this feature, make sure you backup your CHITIN.KEY.
You can use --remove-biff to remove a BIFF file from CHITIN.KEY and destructively replace it with a new, smaller CHITIN.KEY. Before using this feature, make sure you backup your CHITIN.KEY. Do not use this feature.
C:\Program Files\Black Isle\BGII - SoA\> weidu --make-biff mybiff data\25ArMisc.bif
[c:\src\weidu\weidu.exe] WeiDU version 157 [./chitin.key] 182 BIFFs, 41793 resources [./dialog.tlk] 83772 string entries Removing references to 16 resources in [data\25ArMisc.bif] KEY saved (181 biffs, 41777 resources)
Note that the specified BIFF is not deleted from your computer’s file system, it is merely removed from CHITIN.KEY. When specifying the BIFF case does not matter but the folder separator, usually “\” or “:”, does. Use --list-biffs to get the official list of possible BIFFs to remove. Do not use this feature.
C:\Program Files\Black Isle\BGII - SoA\> weidu --nocom --text --transitive banomen.dlg
The --transitive flag tells WeiDU to follow EXTERN references when emitting D files. So the resulting BANOMEN.D file has lines like this:
IF WEIGHT #31 ~InParty("Edwin")
See("Edwin")
Gender("Edwin",FEMALE)
!StateCheck("Edwin",STATE_SLEEPING)
Global("BAnomen1","LOCALS",0)~ THEN BEGIN 10
SAY ~Hey, Edwina! I shall be your champion at the next tournament that
we come to if only you give me a piece of your robe, uh, that is, dress
to adorn my shield.~ [ANOMEN49]
IF ~~ THEN DO ~SetGlobal("BAnomen1","LOCALS",1)~ EXTERN ~BEDWIN~ 104
END
IF ~~ THEN BEGIN BEDWIN 104
SAY ~(My condition draws fools like flies to honey). Silence, you idiot!
You've a death wish that is larger than your swollen head.~ [EDWINW39]
IF ~~ THEN GOTO 11
END
IF ~~ THEN BEGIN 11
SAY ~Fair Edwina, I am truly bereft by your non-acceptance. It is tragic
when a knight has no fair maiden to moon over. Heh he he...~
IF ~~ THEN EXIT
END
Note that both lines from both Edwin and Anomen are presented. The resulting “D” file is not valid in that it cannot be fed back to WeiDU directly, but it should make it easier for you to read all of the jokes offline.
Note that WeiDU may well go into an infinite loop when you use --transitive. Sorry about that.
This section includes tutorials on specific parts of WeiDU. Many of them were contributed by users like you.
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