Dialogue Modding – pt 2 – Basics
✱ updated September 2025
Locating the lines
The first thing to do is to locate where in the file the lines we want to mod are located. Neither the search features in pyGFF nor the toolset work on this sort of file, so we’ll first need to convert the file to a format that can be easily searched.
For each conversation I edit, I personally like to start with a document that contains nothing but the ID and string reference for each line in that file, which I can then use as a base on which to take additional notes on the conversation’s structure and any changes I make.
If you would like to have all of this work done for you: download my “CNV Strings” from my DA2 XML Dump hosted on the Nexus, or below. These files contain the sequential line ID, string reference, and full string for each line in a conversation, for each conversation in the game (DLC included). What these don’t contain are any string references for dialogue wheel options, or any other info about conversation structure.
cnv_strings-1.zip (55 downloads )(Unfortunately the process of creating these files involved a lot of really ugly batch scripting which I am not remotely good at (my process involves a lot of banging my head against Stack Overflow until something works) so I can’t help with replicating them.)
If you need other information from the conversation in a more human-readable or easily-searchable format than the GFF, you have a few options. When you have a conversation open in pyGFF, in the Save As dialogue you have the option to convert to YAML, or you can use xoreos tools command line utilities to convert to XML.
The 2016 version of this section, for posterity…
Open the dialogue or conversation in pyGFF, Save As, and change the file type to YAML, which can be opened in any text editor. (h/t to QuenchedSteel for much appreciated assistance divining this method)
The YAML format won’t include the sequential line IDs, which doesn’t help if you need to figure out where exactly a line is in the file or determine which lines are linked in the children list, so we need to go one step further.
For each conversation I edit, I personally like to start with a document that contains nothing but the line ID and string reference for each line in that file, which I can then use as a reference to take notes and to copy and paste from the talktable. Here’s how I get that:
Open the YAML in Notepad++, ctrl+F to Find, and then search for 30201 (for DA2) or LINE_TEXT (for DAO) using Find All in Current Document. Copy and paste the search results into a new document.

Now switch over to Replace, switch the search mode to Regular expression, and tick on “. matches newline.”
Find what: ,.+?\[
Replace with: \r\n

This will strip out everything but the string references and a little bit at the start and end of the document can be manually deleted. Then hit ctrl+A, tab, and alt+C and insert numbers counting from 0.

If you don’t know how to search the talktable, refer to the previous part of this tutorial. If you know exactly what line of dialogue you’re looking for, you can search for it in the talktable to get the string reference, then search for the string reference in this text file to get the line ID. If you need to search for anything other than the string reference – say you’re looking for all lines with specific plot flags – you can instead do this search in the YAML, scroll up to get the string reference, and repeat.
However you decide to keep track of the lines you need and the changes you’ve made to them – and I absolutely recommend you keep track of both – you will probably want to note down at the very least the line ID, the string reference and string, the children list, and any conditions.
Changing the conversation by editing conditions
Conditions are very, very powerful, and very easy to locate and change.
As a refresher: a condition consists of a plot (identified by GUID), a flag, and a boolean (true/false). The game checks to see if the condition matches the data in the save game, and if it does, the line will play. If not, it continues to check the next child line in the sequence. A line without a condition will always play (or always be a selectable PC response).
There must always be at least one line in every child list that has no condition or else if, for whatever reason, none of the conditions on any of the child lines are met, the conversation will end abruptly (and might softlock progression on the current quest!). If it’s an owner/speaker line (as opposed to a selectable player response), then this condition-less line must be the last line in the list, or else it will prevent any lines below it from playing.
If you want a line to play under different circumstances
You can replace the plot GUID and flag to swap the plot flag out entirely for a new one.
If you want a line to always play
You can remove the condition entirely and it will override any lines lower than it on the list. You must use the toolset to delete conditions. pyGFF won’t convert the empty string to a null string and the line won’t play as intended. Delete the CONVERSATION_PLOT_GUID (in pyGFF this null string displays as a question mark) and change the plot flag to -1.
If you want a line to never play
Do not delete the line from the file. Every line in a dialogue or conversation is automatically sequentially numbered, starting from 0 (zero-indexed) and these line IDs are used in every child line link. If you delete one of these lines it will re-index every line below it, without updating any of the existing child links, profoundly breaking the conversation.
One option to prevent lines from playing is to alter the condition to never return a positive. If modding DAO files, one quick way to do this is to use a debug script that is included in the toolset for this purpose: add zz_return_false to the CONVERSATION_SCRIPT field.

This condition script field no longer exists in DA2, but there does exist a generic GEN_RETURN_FALSE flag: gen00pt_combos (GUID A14C2B2F7402454AAE0468A6472FA5DE) flag 282.
Try not to make assumptions about what other plot flags may return always false. To give an example several modders, included myself, found out the hard way: in Dragon Age: Inquisition, the plot GUID 00000000-0000-0000-0000-000000000000 flag 0 may return true.
Changing the conversation by altering child line links
You can have a much finer degree of control over the conversation by altering the child line list. Every single line in the conversation must be linked from one or more other lines (or the starting list) or else it will never play.
From my experience modding DA2, the enforced alternating speaker->listener structure of the conversation in the toolset editor can be freely disregarded when manually editing a GFF. So you can, for example, link multiple speaker lines directly to each other in sequence without any empty listener “continue” nodes between them, and everything will work as normal. I don’t have enough experience with DAO to state whether or not this is also the case.
If you’re going to be doing much re-pathing I recommend starting from the earliest relevant line and manually following the linked lines through the conversation to make sure the relevant parts of the branch are fully accounted for, rather than starting at the bottom and trying to guesswork your way back up to the start of the branch. If you have exported your converation in a searchable format such as YAML or XML, you can search for the IDs of the lines you’re working with to make sure you’ve accounted for all possible child lists that link to them. It’s very easy to miss one or several.
You can freely add or delete links (again don’t ever delete lines ever). You can also rearrange them to alter the priority with which they play.
To delete links, just hit the delete key. To add a link go ahead and copy and paste one line on the list and then change the value to match the new line you want to link to. The only time finding and copying an existing link to that line from elsewhere in the conversation would be faster is if you’re making changes to the DA2 dialogue wheel. You must use pyGFF to rearrange links. Just select the child list and use the doohickey to shuffle them around to your heart’s content. You can also add or remove links down here if you want.

Be careful when adding new linked lines that you only add lines from that section of the conversation. Once you’ve linked to a different branch, you’re stuck on that branch unless you have plans to route your way back.
Adding new player responses
Cloning and adding new lines does not normally fall under basic editing – it is covered in more depth in a later section. Actually adding edited vo into a conversation and making sure the facefx and animations play correctly can be a complicated process even with the toolset. Without the toolset it’s a far more complex endeavor. Sometimes very complex indeed.
The simple exception to this complicated problem is adding an unvoiced player response in DAO. It’s… well, it’s pretty easy. Just duplicate one of the player *RPLY lines in the list you want to add to (preferably one that already links to the response you want to follow it) and make sure it ends up all the way down at the bottom. Very last line in the file. Very important. As with deleting lines, you don’t want to do anything that will alter the sequential IDs of lines in the conversation.
As with removing conditions, keep in mind that if the new line you are adding will not have a condition attached, then you will either need to 1) use the toolset when you add this new line or 2) open the file in the toolset afterward to fix the null string in the line’s condition field. Otherwise the fancy new line you’ve added simply won’t play.
Now you can add or change the condition if you want, and then add a local string.
Local strings
You’ll be familiar with local strings if you’ve ever opened a .dlg (or a .uti or etc.) after exporting them from the toolset, as the toolset… for some reason… exports local strings which will override the string reference. Which is why dialogue and item mods show up in english in non-english localized games even if the text hasn’t been altered. Which sucks! But it’s useful here.
Here’s what that new line ends up looking like:


You can see pyGFF has separate fields for the string reference (don’t bother altering that) and string, while in the toolset you have to manually add a colon after the string reference and type the new string into the same field.
New line edited to satisfaction, go back up to that original child list and add in the link.
(I haven’t touched much on actions at all although you can see in pyGFF there’s one present in the copied/altered line – almost definitely an approval gain. If you want to alter actions I’m going to assume you’re already familiar with the concept, but you edit them the same way you would conditions.)
Moving forward
If you can find your way around the dialogue you can do quite an impressive amount with simply rerouting lines and altering conditions and actions. It’s a full account of every technique I’d used in a published mod at the initial time of writing.
While these first two basic tutorials have been equally applicable to modding both DAO or DA2, further parts of the tutorial, which delve into more complicated subjects, will be more oriented toward modding DA2 and detailing its specific file structure. The reason for this is that familiarity with the toolset dialogue editor should make the structure of DAO dialogue files pretty clear, and the ability to use the developer-provided tools to natively create and export things like cutscenes, stages, or even new soundbanks and facefx, should get you a long way.