One of my main goals when starting this project was to use it as a learning opportunity (and it got me a job, so hey, I guess it worked)! To that end, I was going to avoid using plugins or pre-made things wherever possible. But as I got in to it, I identified a few things that would be too much of a pain to do 100% from scratch: Saving, Enemy Pathfinding and a Dialogue system. Let's talk about the dialogue system!
The most important feature of the dialogue for this game was arbitrary branching paths. The player should be able to answer questions with a few options, and talking to one NPC shouldn't always give the same responses. I did code something that did that from scratch but... coming up with a convenient way of actually authoring the dialogue itself was a bit too time-consuming, so I ended up adapting YarnSpinner: https://yarnspinner.dev/
YarnSpinner provides an easy to read scripting language and code to parse that and hook the results in to Unity components that let me actually display it all line by line!
They already had a really great Unity package I could import, but I would soon find that (like everything else in The Lost pages), the randomness of it all made things a bit trickier.
The main issue was that YarnSpinner assumed I could just set up everything beforehand in the scene. In reality, the scene view and inspectors are kind of useless in my project, everything is randomly generated, so scenes are largely empty! In my case, where nothing can be assumed ahead of time, I need to add the yarn script for each NPC/sign/whatever on the fly when the user interacts with them, then make sure to run the right dialogue node.
The first part (adding the script) was easy enough, just needed to add a way to check if it was already added... running the first node however, was the first place I ended up introducing some serious jank. Have a look at my script to find that first node:
Of course, with this method, I needed unique names for the first nodes of each script. I (kind of) enforced this with a custom inspector that expects the start node to share the name of the parent object (So NPC Bob's dialogue will have a start node "Bob"). Let me know if you want to hear more about custom inspectors/Unity editor scripting! I actually spent way too much time on this project making custom inspectors so it'd be convenient and foolproof to work on this project.. as thought I wasn't just doing it all myself LOL
After all that was sorted out, I just needed to add some extra features like adjustable text speed, pausing player/NPC movement during dialogue, and some custom commands to do stuff like open up a shop.
Although I think a new dialogue feature may be coming soonish: Animal Crossing style noises for character speech! I know it's not necessary, but I really love when games have that sooo I might just have to 😉