Dragon Quest Battle System — Part II

Silvio Carréra
6 min readAug 31, 2020

So, in the last post, we built the basic structure and flow of Dragon Quest’s Battle system. On this post, we’ll work on getting the visuals closer to the real one, adjusting the windows, and finalize the bottom log window.

Adjusting the Design

First, I’ll extract the window from the screenshot I had. With that, I can create the border and make the image I needed.

Unity already knows how to slice the image for you all you have to do is to set where you want it to.

Next, I had used a screenshot from the game to position the windows in the same spot. Note is that on the left and top window the titles have a black background that covers the white window border. To make it look like that I added a black background to each of my text fields.

Bottom Screen Smooth Text Display and Scroll Up

The bottom screen serves as a log of events to what’s happening in the battle. In the last post, I cleared the text and added a new one. In the original Dragon Quest the text is shown by bits and the window scrolls up when it’s full.

The basic workflow of the log window is:

  1. Receive text to be displayed and store it
  2. Every X seconds display a new letter on the screen
  3. If the window is full scroll up
  4. If there’s still text to display, go to Step 2
  5. No more text to display, wait

Let’s look at some code now, shall we?

This is the main section of our WindowBattleLog class. The textField is the variable that holds the text displayed on screen. The textToAdd handles the text that is queued up to be shown next. This way I can “push” a lot of text in and the window will handle its display.

The textSpeed handles how fast the letters will show one after the other. The scrollSpeed is a delay before I scroll the text up. More on that later on.

The TOTAL_LINES and CHARS_PER_LINE tell me how many lines I want the window to have and the number of chars a line can have at most.

The AddText function is the entry point. That’s what I call everytime an action happens and I want to display it. It adds the new text to a variable. I also added a handy breakline option since DQ used quite a bit.

After that I do an invoke to the function that will consume the text and show it by bits on the display. Note that I check if the invoke is already running at the beginning. If I’m adding more text but the invoke is already consuming something, then there’s no need for me to start it since it will loop by itself.

The add to display consumes the first char of the textToAdd string and adds it to the text field. If the length of the textToAdd is one then I added the last letter so I can clear the variable. If not then we advance the textToAdd one index.

What we are doing is, say we did and AddText(“Command?”). The firs time, the AddToDisplay will consume the first letter “C” and show it on the screen. Then the variable will change from “Command?” to “ommand?” so on the next loop well consume the “o”. This way we always consume the first letter not matter the size of the textToAdd.

Note that before doing the invoke again I check if the window is full. Let’s take a look at that function.

The window will be full when I have more lines than the TOTAL_LINES amount. To count how many lines I have right now I loop through each char and check if it’s a “\n” (breakline) character. If it, is then we increase the line amount.

Now, there is another case where “\n” won’t show up. Since unity will truncate the textField as the content is added we won’t get a new “\n” there. So if we add a very long text at once it will automatically breakline but a “\n” won’t be found.

So, the way I solved that is since I know the number of chars a line has I just count them. If it reaches the quota them I can consider that a new line.

If the window is full then we will scroll the text up. A quick hack I’m doing here is erasing the first line then moving the rest of the text to its position. Since it all happens fast you get the impression the text moved up when it didn’t actually.

We find the index of the next line by checking for a “\n”. As I mentioned before there might be lines without a “\n” between them. We can find those lines by checkign secondLine is bigger than CHARS_PER_LINE.

With that done we get the substring starting from the second line index we found until the end string. Meaning the length minus the second line index value.

Next we set the text displayed as the substring.

Now let’s take a look at how the calls to the WindowBattleLog are:

It’s looking ok, right? But a bit messy. Before moving ahead to other things let’s organize this a bit. Let’s create another class to help us out.

Vocab is a static class to hold some data for us. In this case, it relates to the text we’ll be displaying. This is another nice hack you can use to organize data. This is easy to use and maintain but definitely not the right approach for a larger-scale project. Then again, we need to use the right solutions and this one fits with our problem.

With the class set up let’s use it now:

With the Vocab class, we create a clear division between logic and data.

Here’s the final result:

That’s it for part II! Please feel free to look through the code and question it. If you missed the first part you can find it here.

In part III we’ll be going through the player window and command window. We’ll be able to choose the command and the target.

Originally published at https://www.tumblr.com on November 25, 2016.

--

--