Dialogue Modding – pt 1 – Orientation

updated August 2024

Modding Dialogues Without The Toolset Editor

This introductory tutorial will explain how to get started modding dialogue files that aren’t accessible in the toolset dialogue editor—specifically those from DA2 or from Origins DLC.

Which tool you will prefer to do most of your work in is up to you, but for the purposes of modding dialogue, the following tools are both required:

  • pyGFF is required to extract files from DA2’s ERFs. It’s also my personal tool of choice for editing GFF files like Dragon Age’s DLG/CNV files.
  • The Dragon Age Origins Toolset is required for a few specific edits that cannot be accomplished with pyGFF, such as deleting conditionals and editing DA2’s CL files. I recommend applying the LAA patch to DragonAgeToolset.exe to expand the amount of memory it can use.

Another general purpose tool I recommend, which is by no means required:

  • xoreos tools has a number of command line utilities that can decompose GFFs, talktables, scripts, and more into more readable and searchable formats such as XML.

Extracting the dialogues

Dialogues for each campaign are located in module resources, not in core resources. So for example, the path for Awakening dialogues is Dragon Age\addins\dao_prc_ep_1\module\data\designerdialogues.erf while the path for DA2 basegame dialogues is Dragon Age 2\modules\campaignbase\data\designerconversations.erf. Origins files end in .dlg (dialogue) while DA2 files end in .cnv (conversation). Neither of these files is encrypted, unlike most DLC files. Extract or open the file you want using your tool of choice. You kind of just have to guess which one it is, though all files follow standard naming conventions.

Without the toolset we won’t be able to recalculate animation blend trees (.dlb) so this is the only file we’ll need to edit.

A note on encrypted DLC

Modding exists within the grace of legal grey areas, and that area gets a lot greyer when DRM is brought into the mix. Bioware’s official stance on modding from 2011 indicates that DLC assets are fair game to use in mods for the series as long as the modder 1) legally owns the DLC and 2) does not create a mod which reproduces the DLC for those who don’t own it. Given that Bioware points were phased out in 2022 and since that point all DLC has been available completely free for all players who bought the game on a summer sale for $3… I mean…

Orientation to dialogue structure

This is what a file looks like in the dialogue editor. Lines always alternate between red owner/speaker/NTRY and blue player/listener/RPLY lines. The owner of this dialogue is Duncan, but other speakers can be tagged on individual lines.

Empty listener lines appear as [CONTINUE] (or [END DIALOGUE]) nodes and allow the conversation to continue uninterrupted by player input. Empty owner nodes also continue the conversation but in the toolset usually display as green [COMMENT] nodes.

In the toolset, grey linked lines show where one line is used in multiple dialogue branches. This doesn’t create a duplicate of the line, but instead allows it to be linked to from anywhere else in the conversation structure. This is as true in the exported file as it is in the Toolset. Outside of the Toolset, all child lines are “linked lines.”

Any line can have one or more children or child lines. The game selects which of these child lines should come next based on associated conditions.

condition is composed of a plot, a flag, and a boolean (true/false) value. For owner/speaker lines, the game checks the condition for the first child line against the plot flags stored in the save game. If the condition fails, then it moves down to evaluate the next, until it finds a line that is valid to play. There is usually a default line at the bottom of the list with no condition set—otherwise it’s possible to be ejected from the conversation early. For player/listener lines, the game checks the condition for every line in the list and displays the valid responses as dialogue options.

Actions, on the other hand, set or clear a specific plot flag when that line plays. This can be used to advance a particular plot quest, add or remove companion approval, move creatures and objects around in the scene, or any number of other scripted behaviors.

Note that there is also a (rarely-used) script field that can also be used to check the validity of a line or fire upon line completion.

One of the more important things to note is the ID, which is visible in the very bottom corner of the dialogue editor. This ID—the string reference—is used to locate the subtitle (in the module talktable), the voiceover audio, and the faceFX (lip sync) for each line that plays. The string reference is separate from the sequential line ID that is given to each line when a file is exported.

Understanding the basic structure of a dialogue makes it pretty easy to get at what’s going on once the conversation has been exported into GFF format.

Orientation to GFF structure

A DAO conversation will look something like this:

- 0             GFF V4.0 CONV V0.1 PC           CONV            ...             
  - 12000       CONVERSATION_STARTING_LIST      [UINT32]        (5 items)       
        0                                       UINT32          0               
        1                                       UINT32          10              
        2                                       UINT32          28              
        3                                       UINT32          64              
        4                                       UINT32          205             
  + 12002       CONVERSATION_LINE_LIST          [*]             (508 items)     
  + 12003       CONVERSATION_END                ENDA            ?, -1, 255, ?, 0
    12004       CONVERSATION_VOBANK             STRING          gxa000_anders   

This differs slightly from the DA2 version, which will look something like this:

                                                             
- 0             GFF V4.0 CONV 3.0 PC            CONV            ...             
    30000                                       UINT8           255             
  - 30001       CONVERSATION_STARTING_LIST      [LINK]          (4 items)
      + 0                                       LINK            0, ...          
      + 1                                       LINK            4, ...          
      + 2                                       LINK            99, ...         
      + 3                                       LINK            102, ...        
  + 30002       CONVERSATION_LINE_LIST          [*]             (211 items)
  + 30003       CONVERSATION_END                PLOT            ?, -1, 255
    30004                                       FLOAT32         -1.0            
    30005                                       FLOAT32         -1.0            

Files from DAO are generally easier to read at first than those from DA2 because there’s more readable text, but the idea is basically the same (and I have labeled certain DA2 fields in the examples here). You can see both files have a starting list, indicating which lines of dialogue mark the beginning of separate branches of the conversation tree.

Expanding the line list to view the contents of a line of dialogue reveals where the real differences lie. A line in DAO will look something like this:

 
- 12                                                       NTRY                  
    12100          CONVERSATION_STAGE_NAME                 STRING      2p_200_bronze_r
    12104          CONVERSATION_STAGE_AT_CURRENT_LOCATION  UINT8       255       
    12201          CONVERSATION_LINE_TEXT                  TLKSTRING   428168    
    12202          CONVERSATION_LINE_SPEAKER               STRING      OWNER     
    12203          CONVERSATION_LINE_LISTENER              STRING      PLAYER    
    12204          CONVERSATION_LINE_GAME_LANGUAGE         INT32       0         
    12205          CONVERSATION_LINE_ICON                  INT32       0         
    12206          CONVERSATION_LINE_VISIBILITY            INT32       0         
    12207          CONVERSATION_LINE_AMBIENT               UINT8       0         
  + 12208          CONVERSATION_LINE_COND                  PLOT     
  + 12209          CONVERSATION_LINE_ACTION                PLOT                  
    12211          CONVERSATION_LINE_CUTSCENE              CUT                   
    12213          CONVERSATION_LINE_ANIMATION             UINT32      4294967295
    12214          CONVERSATION_LINE_SKIP                  UINT8       0         
    12215          CONVERSATION_LINE_FASTPATH              UINT8       0         
    12216          CONVERSATION_LINE_NOVOINGAME            UINT8       0         
    12217          CONVERSATION_LINE_REVERT_ANIM           UINT8       0         
    12218          CONVERSATION_LINE_SLIDE_SHOW_TEXTURE    STRING                
  - 12400          CONVERSATION_LINE_CHILDREN_LIST         [UINT32]    (3 items)  
        0                                                  UINT32      243
        1                                                  UINT32      245
        2                                                  UINT32      247
    12500          CONVERSATION_LINE_ACTIVE                [IMAP]      (2 items) 

The file structure for DA2 is very different. Two lines will look more like this:

- 5                                                        LINE                  
    30200                                                  UINT16      10
    30201          CONVERSATION_LINE_TEXT                  TLKSTRING   6071418
  + 30202          CONVERSATION_LINE_COND                  PLOT
  + 30203          CONVERSATION_LINE_ACTION                PLOT
  - 30204          CONVERSATION_LINE_CHILDREN_LIST         [LINK]      (2 items)
      - 0                                                  LINK                  
            30100                                          UINT16      6
            30101  CONVERSATION_WHEEL_PARAPHRASE           TLKSTRING   4294967295
            30301  CONVERSATION_WHEEL_CATEGORY             UINT8       255
            30300  CONVERSATION_WHEEL_ICON                 UINT8       255
            30303  CONVERSATION_WHEEL_FOLLOWER             UINT32      4294967295
      - 1                                                  LINK                  
            30100                                          UINT16      61
            30101                                          TLKSTRING   4294967295
            30301                                          UINT8       255       
            30300                                          UINT8       255       
            30303                                          UINT32      4294967295
- 6                                                        LINE                  
    30200                                                  UINT16      257       
    30201                                                  TLKSTRING   6071479   
  + 30202                                                  PLOT                  
  + 30203                                                  PLOT                  
  + 30204                                                  [LINK]      (1 item)  

As you can see, each line in a DAO dialogue file contains a large number of fields not present in DA2 conversation files. Some of these fields concern animations/cinematics, which in DA2 have been moved to external .cl files. Others are options which in DA2 have been converted to a single bitwise flag. (Both of these concepts are explored in further depth in later parts of the tutorial series). A few fields I’m pretty sure are only used in the Toolset but never in game.

On the other hand, DA2 child lines have several more fields than DAO, to accommodate the dialogue wheel (which also has its own dedicated writeup in this tutorial series).

For basic edits, everything we really want is present in both: the tlk string reference, the condition, and the list of child lines.

Lines of dialogue export reasonably in order. One thing to note while unraveling the structure of the specific conversation you’re working with is that in DA2, speaker and player lines export alternating in sequence, while Origins exports all speaker lines first (NTRY) followed by all player lines second (RPLY).

Finally, let’s take a look at the structure of conditions and actions, starting with DAO:

- 12208         CONVERSATION_LINE_COND              PLOT
    12300       CONVERSATION_PLOT_GUID              STRING      6526F8E770484223A6FD7B72C1DE70C8
    12301       CONVERSATION_PLOT_FLAG              INT32       1   
    12302       CONVERSATION_PLOT_TEST              UINT8       255 
    12303       CONVERSATION_SCRIPT                 STRING      ?   
    12304       CONVERSATION_SCRIPT_PARAMETER       INT32       0   
- 12209         CONVERSATION_LINE_ACTION            PLOT
    12300       CONVERSATION_PLOT_GUID              STRING      ?   
    12301       CONVERSATION_PLOT_FLAG              INT32       -1  
    12302       CONVERSATION_PLOT_TEST              UINT8       255 
    12303       CONVERSATION_SCRIPT                 STRING      ?   
    12304       CONVERSATION_SCRIPT_PARAMETER       INT32       0   

And in DA2:

- 30202         CONVERSATION_LINE_COND              PLOT
    30400       CONVERSATION_PLOT_GUID              STRING      6F4E853DF7EE4DE3841C31928BF663C3
    30401       CONVERSATION_PLOT_FLAG              INT32       8   
    30402       CONVERSATION_PLOT_TEST              UINT8       255 
- 30203         CONVERSATION_LINE_ACTION            PLOT
    30400                                           STRING      ?   
    30401                                           INT32       -1  
    30402                                           UINT8       255 

You’ll note the script field in DAO files is not present in DA2, but everything else is the same. There’s a plot GUID, a plot flag, and the plot test, which will be either 255 (true) or 0 (false).

Identifying plot flags

For the most part, you’ll be able to guess plot flags from context, but if you’re concerned with specific flags available in the DAO base game, you can find the flags and GUID in the toolset.

toolset: plot editor

If you want to confirm a plot flag in DAO DLC you can find the same information in the .plo file.

Unfortunately the file structure of DA2 plot flags is very different, and none of it in human-readable format. Determining what plot flags you may need is a feat that requires a post all to itself (upcoming in a future update…).

Accessing the talktable

Of course all of this is pointless if we can’t see what each individual line is. That’s where the tlk string reference comes into play. Each string reference corresponds with an entry in the talktable.

Again, conversation data is located in module resources, not core resources. So the English language Awakening talktable, for example, is in Dragon Age\addins\dao_prc_ep_1\module\data\talktables\dao_prc_ep_1_en-us.tlk and the DA2 talktable is in Dragon Age 2\modules\campaign_base\data\talktables\campaign_base_en-us.tlk. You can open talktables in the toolset or pyGFF if you reeeeeally want to but, uh, I don’t recommend it.

For an option that works for both DAO and DA2 talktables, use tlk2xml in xoreos tools to convert the talktable to XML format.

For a different command line option for DA2 talktables, download DA2 Tlk Converter (GitHub). To convert the talktable to plaintext format, copy the talktable into the same folder as the program. Copy the following into an empty text file and save it with the .bat extension in the same location, then double click the batch file to run the script.

for %%a in (*.tlk) do da2tlkconv.exe -d -i %%a %%a.txt

For a solution for DAO talktables which does not require the use of the command line, download DAOTlkEdit (ModDB mirror). When you open the talktable, sort by StrRef (string reference). In the bottom right corner is a field where you can search for strings or string references.

String references export to the talktable somewhat in order, as they are generated the first time that line is saved in the toolset. If you search for a string reference and it can’t be found, that means it’s an empty string and that line functions as a [CONTINUE].

Finally! If you don’t want to mess with any of that, you can download my DA2 TLK Dump below or from my Dialogue Mini Mods on the Nexus. I’ve formatted these files to suit my preferences when searching them.

da2_tlk_dump.7z (197 downloads )

Visualizing conversations from DA2

While you cannot open DLC dialogues or DA2 conversations in the toolset’s native conversation editor, some noble soul on the now-deleted Bioware forums did create a conversation viewer (archive.org mirror) for DA2, and archive.org managed to snag most of it. This can be a helpful way to get an idea of the flow of a conversation before diving into the muddled mess that is GFF for yourself. Please read the installation instructions carefully. I barely remember how I got the SQL database working myself so I’m not going to help anyone troubleshooting. I’ve mirrored missing content here:

da2_content.zip (393 downloads )