Talking 'Bout Dialogue


I can't believe it's been over a year since my last post! Time really flies, doesn't it?

Before I get into the meat of what I want to talk about in the dev log, I want to do some reflecting...


Reflections

This year marks 6 freakin' years since I first started work on Bravewater. I've grown so much from my professional software development experience in those 6 years, and that's really changed how this project has gone - both for better and worse.


The Good of Being a Full-Time Software Developer

I have a *much* better grasp on software development concepts and architecture now. When I started this project I was a week out of college and thought I knew everything about software development (LOL)

Obviously I was very wrong, which led to me starting over in 2020.

Even since my last post I've gotten even more experience with developing a large scale application, which has made me rethink even more decisions I made not long ago!

Obviously I could keep re-writing this game over and over again, but I do eventually want to ship a finished project. Thankfully I'm at a state where most of the core mechanics are working well and I feel comfortable with them, so I think this will be it for re-writes.


The Bad of Being a Full-Time Software Developer

Developing a game while working full time is really, REALLY difficult. I do professional work for 8+ hours a day, and to be honest, it's been impossible to find the motivation and brain power to do it even more after work. Combine that with the everyday responsibilities of life and the hot mess that things have been in the world for the past two years, and Bravewater has unfortunately taken a backseat in my life.

That's not to say I don't want to make it happen. I think about this game almost every week. It's been a dream since I was a teenager to make a game, and I refuse to give up on that dream.


The Plan For This Full-Time Software Developer

I plan to dedicate at least one day a week to spend at least an hour on continuing work on Bravewater. That might not sound like much, but it's much more than I've been spending on it in the past year. I'm hoping this will let me push through and FINALLY get a playable demo out within a year. We'll see how that goes. 

Again, I really want this to happen. Especially if it means I can get to a point where this becomes my full time job. That would be incredible!


Enough Reflecting, Get on With it!

I've spent the last few months working on the dialogue system again. As I got to a point where I wanted to start building out the tutorial level, I realized my dialogue system that I bragged about being so great in the last blog post...wasn't actually that great.

I really loved the transition I made to JSON. It made making dialogue scripts a piece of cake. But I realized I made it way more cumbersome than it should have been.

Previously an interaction had "PreActions", "Lines", and "PostActions". "PreActions" were things that happened before "Lines" were displayed, then "PostActions" were things that happened after all the "Lines" were read.

So if I went to talk to a character, the PreActions would be to pop up the dialogue box, set the character's name and image, etc.

The lines would be reading off whatever the character had to say

The PostActions would be either switching to another character or hiding the dialogue box and doing some cleanup.

This sounds great, but I had a huge realization as I sat down to write some dialogue...

Why does this need to be in these 3 sections? All of these are just actions; reading the lines is just a more complicated action. There's no need to split them up like this!

Then came a second realization - with the old system I had to constantly define what character was talking. Shouldn't the character name / image be implied based on who is talking rather than having to tell the system that over and over again?

So I sat down and re-wrote a huge chunk of the system. As I started writing it, I realized that I could write it in a way that mimics screenplays. The file itself is an act, and in an act you have characters and scenes. When a character speaks in a scene, that's dialogue.

Holy crap, it makes so much sense!

So let's take a look at a chunk of an example dialogue "act" file with the new system:

{
    "friendlyName": "Tutorial Level Dialogue",
    "characters": [
        {
            "name": "player",
            "friendlyName": "Player",
            "displayedName": "{PLAYER}",
            "image": "player_"
        },
        {
            "name": "subconscious",
            "friendlyName": "Player's Subconscious",
            "displayedName": "{PLAYER}'s Subconscious",
            "image": "subc_"
        }
    ],
    "scenes": [
      {
        "name": "tutorial_intro",
        "friendlyName": "Intro - Starting",
        "dialogue": [
          {
            "character": "player",
            "actions": [
              {
                "type": "ShowDialogue"
              },
              {
                "type": "SetNPCNameText"
              },
              {
                "type": "SetNPCImageIdentifier"
              },
              {
                "type": "ShowNPCName"
              },
              {
                "type": "ShowNPCImage"
              },
              {
                "type": "ReadLines",
                "parameters": [
                  "{*happy*}Where am I? \n \n(Tap this box to advance/speed up dialogue)",
                  "{*happy*}Is this a dream?",
                  "{*happy*}Am I dead?"
                ]
              }
            ]
          },
          {
            "character": "subconscious",
            "actions": [
              {
                "type": "SetNPCNameText",
                "parameters": [
                  "???"
                ]
              },
              {
                "type": "SetNPCImageIdentifier",
                "parameters": [
                  "unknown"
                ]
              },
              {
                "type": "ReadLines",
                "parameters": [
                  "{*happy*}Hello there, {PLAYER}."
                ]
              }
            ]
          },
          {
            "character": "player",
            "actions": [
              {
                "type": "SetNPCNameText"
              },
              {
                "type": "SetNPCImageIdentifier"
              },
              {
                "type": "ReadLines",
                "parameters": [
                  "{*happy*}Who are you?!"
                ]
              },
              {
                "type": "HideDialogue"
              },
              {
                "type": "HideNPCName"
              },
              {
                "type": "HideNPCImage"
              }
            ]
          }
        ]
      }
    ]
}

You'll see that characters are defined up at the top of the file. This lets me re-use character definitions over and over throughout the scenes and dialogue. No more defining parameters of who is talking every time!

Below that are the scenes. Each scene has a name to identify it, which is how we call it from the game. By the way, you'll see "friendlyName" throughout, and this is for the dialogue editor that I'll get into in a bit.

Each scene is a list of dialogue, which is made up of a character that is speaking and the actions that happen while it's that character's turn to speak. 

You'll see that we start out by showing the dialogue box, setting up the image and name text to show, showing those, then reading off the dialogue lines. The dialogue lines are prefixed with an emotion, such as {*happy*}, to modify the character image to reflect the emotion of the line being read.

When all the actions are completed, we move on to the next dialogue in the list. When all the dialogue has been executed, the scene ends. 

Typically the last actions in the last scene will be to hide the dialogue box/name/image, but it could be *anything*. That's the beauty of this system. It can be made to do as little or as lot as I want.

Here's the end result.

This system is fantastic. I am so happy with how it works. It lets me very easily create dialogue scenes without writing any C# code.

Now, that said, it's still JSON. I know how to write JSON, but if I collaborate with anyone non-technical, this is going to look like greek to them. Not to mention that even for me, JSON is still cumbersome to write.

That's where the editor comes in!


The Editor

I still find it hilarious that I have to write code that helps me write code. Software development is weird.

This actually isn't my first editor. It's my third time writing one. The first two worked with XML dialogue files, and the very first one was windows only, which was hard to deal with when your laptop is a Mac. 

The second editor required a back-end to convert the JSON I wrote in the front-end to XML, and also to access the file system. Why? I didn't know better!

These are the first two editors from a blog post I made in 2018. Oh how far I've come...

So just like with Bravewater itself, I started over.

Again.

And funny enough, as I write this blog post I realize that my new editor almost looks identical in layout and general design to the last one, despite not seeing this picture since 2018. That was totally unintentional. I guess my brain has a very specific design in mind!


It's as easy as 1a, 1b, 2, 3!

With this tool I'm able to make a scene into something that can play out in my game in a matter of minutes. Best of all, it's cross platform and requires no backend! I wrote the editor in Angular and bundled it into an Electron app so it can run just like a "real" application on both Mac and PC. Modern web APIs let me work with the filesystem without any backend, and being that dialogue is JSON, I don't have to do any conversion since JSON is primarily a web thing. 

It's good stuff. I don't want to spend too much time talking about it because it's just a tool, but I love how it turned out.

Plus look at it! It's pretty!


What Else Did You Work on?

I actually built out a battle system. I have a blog post drafted up on that, but I'll come back to that when the RPG side of the game gets fully worked out. It was probably a mistake to spend time on that rather than finishing up the RPG aspect of things, but that's what my brain wanted me to work on at the time!


So...What Now?

Here's a rough list of everything that needs to be done.

  1. A quest system needs to be built out to guide the player in doing whatever they are tasked to do (and rewarding them when a quest is completed)
  2. A basic item system needs to be built out so the character can get items and have the game do logic based on if they have specific items or not.
  3. Once quests and items are done, the tutorial level can be built out.
  4. Once the tutorial level is finished, the first chapter of the story can start being worked on. That's going to involve building out a shopkeeper and fleshing out the item system a bit more.
  5. Once the story is at the point that a battle begins, the battle system will need some polishing up.
  6. Once the battle system is all good and set up to transition to/from the RPG, it'll be time to polish things up! Art, music, UI design, and controller support are going to be major hurdles at this point, and frankly it's what scares me the most.

Obviously there's no way a full game is going to come out of this any time soon, but I want to have something that's polished enough to send it out to the world and let people finally experience a small part of my dream. Assuming I make it to that point, I'll start a kickstarter and see what happens. If things go well, Bravewater might just be a real game...

Regardless of what happens, it all happens one step at a time. I can put the dialogue chapter behind me and move on to quests now.

Let's do it.

- J

Leave a comment

Log in with itch.io to leave a comment.