Dialogue Editor - Branching dialogue writing tool in Godot

Hi yall! I would like to show a project of mine i’ve been working on and off for a little over three years now. Not a game, but a game making tool. I present to you - Dialogue Editor, a tool for writing branching dialogues! (I did not care to come up with a quippy name, sorry. Maybe if i ever open it to the public i’ll rebrand). Made in Godot, to be used with Godot (initially).

Part 1. Research

I love bioware rpgs. I love dialogue options. I want to make games that are filled to the brim with player expression and reactivity. I need a tool that facilitates that.

Now, dialogue in games is well-troden territory, so firstly i explored existing offerings. Those included Twine, Ink, Yarn Spinner, Ren’Py, Articy (used in Disco Elysium), Chat Mapper, Dialogic by Emilio Coppola Narrat by Liana Pigeot, Dialogue Designer by radmatt, RPG Maker, SRPG Studio, Dragon Age Origins Toolkit, Divinity Original Sin 2 Toolkit, and various Unity and Unreal plugins.

My requirements were:

  1. Works with Godot.
  2. Graph-based. The two major paradigms i saw were 1) graphs with interconnected nodes of text and 2) linear text with jump-to bookmarks. Both have their strengths and weaknesses, but i figured graph-based suited my purposes better.
  3. Flexible. I would like to be able to use it for all sorts of games with all sorts of UIs, dynamic characters, and what not.
  4. Pleasant to use.

Nothing i found fit all of those, i had to make a tool that fit my hand myself after all. The edior i liked most was the one Obsidian made for themselves, shown off in a briliant GDC talk by Carrie Patel and David Szymczyk. The Divinity one was a close second, if only because they are quite similar. And so, armed with a youtube video as reference, i set out.

As a side note, it is worth saying that dialogue trees, which all these tools essentially boil down to, are not the only possible way to do non-linear narrative. I highly recommend Emily Short’s excellent blog in general, and specifically her posts about quality-based story structures and storylets. As well as a Valve GDC talk about their contextual dialogue system in left 4 dead, which is essentially a storylet system too.

Part 2. Showcase

And three odd years later here’s what i have on my hands.

demonstration

Explanation of the different node types if you're interested

The three bread and butter nodes are:

  1. Hear Node - the regular text node. Be it anything an npc says, narration, or the full version of a dialogue option your character says out loud, like in mass effect or later dragon ages or fallout 4 or witcher or cyberpunk or greedfall you get the idea.
  2. Say Node - dialogue options presented to the player as a list
  3. See Node - cutscene direction nodes, their text is hidden in the final gameplay. Borrowed that one from a Baldur’s Gate 3 cinematics GDC talk by Jason Latino

Additionally two special nodes are:

  1. Root Node - dialogue starting point. I’ve seen some people also use an Dialogue End node, but it is imo redundant.
  2. Reference Node - a “link” to a different node, which allows loops, merging of branches, etc. It can either reference a node itself, or it’s children (borrowed that functionality from the Divinity Toolkit)

The playback order is the same as in the Obsidian editor, you can watch the linked gdc talk for the explainer.

A loose pile of features:

  • Auto-placement of nodes. No constant re-arranging of nodes, no manual connecting of one node to another.
  • Keyboard navigation. you can see the mouse cursor in that gif, it aint moving much. i don’t have hotkeys for everything yet, but just being able to move around with the arrows / zoom to a particular node / enter and exit text editing is sooo good.
  • Undo/redo system. That one is so vital oh my god.
  • Search nodes by text.
  • Folding/unfolding of branches.
  • Simultaneous editing of multiple dialogues in different tabs.
  • Condition and action system. Dialogues can share flags, set them, check for them, as well as execute scripts.
  • Actors and node tags are also shared between dialogues. You can select which actors are present in the current dialogue.
  • Separation of editing-time and play-time data. this allows doing things like generic dialogues between Character A and Character B, with actual identities of A and B provided at runtime by game logic.
  • Settings! Customizable color-coding, node spacing, optional auto-saving

I tried to make it flexible enough to allow all sorts of in-game presentations. As an exersice i’ve re-created the Disco Elysium column diaogue. Fun fact, while doing this i had the game opened for reference and wanted to see how they handled a particular edge case. Turns out, they didn’t! It was bugged.

disco

Disco Elysium bug

disco bug

Part 3. Regrets

The biggest mistake of this project by far was envisioning it as a Godot extension. When i first discovered Godot and made it my engine of choice i was dazzled by the idea of godot editor running on godot itself, and how you can use godot to make plugins for godot. And also how godot is an all in one solution, you can edit levels AND write code in one program! So wouldn’t it be cool to write dialogue in that same program! It was a fundamental design decision i made at the very start and it has done nothing but bite me in the ass ever since.

Here’s how it shook up. The pros:

  1. I can use godot’s file explorer to create and edit resource files. which means i don’t need to implement my own dialog windows for settings and some supporting file creation. saved myself like two days of work!
  2. I don’t need to fuck with file formats, saving and loading, i can just use godot’s resources
  3. I don’t need to have multiple programs opened, everything lives inside of godot. Minimalistic!

The cons:

  1. Biggest one by far: sometimes code works differently when you run it as an executable vs a plugin. you can debug an executable. you can not debug a plugin. so if something works in debug but then doesn’t work when used as an actual plugin, you’re fucked! the most common case was me forgetting the ‘tool’ keyword at the top of the script, but it was also the most trivial to catch and fix. but some of those were real mind fuckers. Files didn’t save, files got corrupted, files didn’t load properly, plugin code didn’t get loaded properly, it’s a horror show in there
  2. Some godot hotkeys could not be disabled or overriden (at least i couldn’t figure out how). So you would accidentally add new nodes to the opened scene even though you were in the dialogue editor tab, not the scene editor tab.
  3. Having the editor be embedded into the engine means i’m tied to that version of the engine. When i started this project, the latest version of Godot was 3.4. Currently the latest version of Godot is 4.3. I intend to use this tool for at least the rest of my life. So if i want to use some cool new engine feature for the actual game that i’m supposedly making with the tool, i need to port the editor to the newer version of godot. Just porting from 3.4 to 3.5 broke some things. I can’t even begin to imagine how many things will break if i port to godot 4.
  4. I’m not even using godot to make a game right now!!! I’m making a game for the playdate, rolling my custom engine in freaking lua!!! all this Native Godot Integration is completely irrelevant!!!
  5. Oh and because i’m using a completely different engine, turns out, i DO need to fuck with file formats, saving and loading! Strike that pro #2 frome the record! Also, godot’s resource files SUCK. Incremental counter ids are totally unusable with version control. So many a corrupted dialogue file. Had to write my own unique id generator.
  6. And to open the dialogue editor, i now need to keep the entire godot open, even though i don’t use any of it for development. instead of having less programs opened, i now have extraneous programs opened! Not minimalistic at all! Strike that pro #3 from the record as well.

So yeah, after three years of banging my head against a wall for what amounted to no reason at all, i have finally decided to abandon my aspirations of making it a godot plugin, and now the editor will (at some point) become a standalone program.

Part 4. Future

At this point i’ve largely moved on from working on the editor to working on an actual game using it. There is still plenty of work to be done, like moving away from the plugin paradigm, polishing out the jank, stomping out minor bugs. It is roughly feature-complete, the big remaining one is localization tables. Another cool feature i want is nested dialogues: having nodes that contain full sub-dialogues inside of them. This one is not essential and requires a lot of ui work, so it’s kept on ice for now.

I’m not sure if i want to make the editor available to the public. Doing so would require writing documentation, lots of polishing, timely bug fixing, etc. And i want to spend my limited time on making games, not maintaining tools for making games. Additionaly, i’m not sure anyone would even want to use it. It is not nearly plug-and-play enough for people who don’t want to futz with code. And people who do would probably find it too opinionated (three years later some of those opinions even i don’t agree with!) and would rather make something from scratch themselves.

So for now it will remain used by just me and a couple friends. It can be available upon request, but keep in mind its semi-finished state. Maybe in a couple more years.

Part 5. Lessons Learned

  1. Copying (or more specifically re-creating) other people’s work is great! Looking at other people’s work under a microscope, figuring out how to make it yourself, improving things you didn’t like about the reference along the way. It will absolutely make you a better craftsperson.
  2. Having tools be separate specialized programs is good actually. It takes a little bit more upfront work, but results in less dependency, less maintenance, and more flexibility. You can have yourself a separate level editor, a separate dialogue editor, a separate database editor, a separate code editor, and be better off for it.
  3. Tale as old as time, i got stuck in the tool making stage, instead of the tool using stage. The editor was already usable like two years ago. But also it is now just so much more pleasant to use. Idk. I’ll report to you on this in like two to three years when i finish a game with it and tell you if it was worth it.

And this concludes my show-and-tell, thanks for reading!

Could not fit all the links in one post, so here’s the addendum:

  1. Dialogic by Emilio Coppola
  2. Narrat by Liana Pigeot
  3. Dialogue Designer by radmatt
  4. Emily Short’s excellent blog

YO! thanks for this writeup. Super well done, it’s hard to even come up with questions for this. I feel a kind of connection to this thread because one of my latest claims-to-fame is also a graph-based dialogue editor I wrote for the folks at LimboLane’s upcoming release. This was mostly UI work though; I didn’t handle the runtime interpreter for it, just editing and specifying the file format.

I think the case you make about the internal Godot plugin is pretty interesting. I did run into some of the in-godot plugins myself and thought that process sounded pretty convenient, so this is really good critical observation on why that may not actually be ideal. I wonder how many of those same dev problems persist after the 4.0 gap though. Really the big deal about that to me would be that it hooks itself better into Godot’s internal file server stuff - Most engines struggle with editing certain files while the engine editor itself is live, so I assume their own plugin API helps keep that in check. Regardless it sounds like you’d be working with making it an external tool though, for the sake of broader engine support.

I definitely wouldn’t sweat something like a public release for this. I think when you show off custom tools publicly it can create a pretty big amount of false interest, namely folks who like the idea of trying something new but don’t actually have any reason to commit to a change. There’s no real reason to say “no” to when you ask publicly about releasing this kind of thing, but it doesn’t necessarily mean all those yesses are speaking from use-case scenarios. You’ll probably get a ton of mileage out of just trying things out for yourself over the next however-many-months, and maybe that would give enough insight into what you’d want to change before going public.

Thank you!! I would love to see some screenshots of the tool you made, if you’re allowed to share that. I am always super interested in how other people tackled these same problems and what clever bits i can bring over.

I wonder how many of those same dev problems persist after the 4.0 gap though

When moving from 3.4 to 3.5 some signals changed their parameters in a ui element or two which broke things. So even jumps between minor version can introduce new unexpected hurdles. Ten years from now they might do a Godot 5 for all i know and god knows i don’t want to still be fixing these problems ten years from now askjdgg. Even if still using this tool in 10 years might be wishfull thinking, i am allowed to dream!

Most engines struggle with editing certain files while the engine editor itself is live, so I assume their own plugin API helps keep that in check

You’re right, there were (and still are) some conflicts when using a file simultaneously in Godot and in the external editor. But since i’m currently not using Godot for the game i’m making, i’m not affected by those yet. And to be honest there were similar problems even when using the editor as an extension, but those were more likely my error.