[RM-1] A Debug Window

Blog Info: As I’ve improved my skills as a Computer Scientist, one realm has remained elusively difficult: games. I’ve got the basics of an operational game engine, but I’m more interested in seeing how other people organize their projects. Hence, this blog will serve as a series of mini-ventures into the code of various established games, each time with a specific goal I hope to achieve.

Back-story:  I’ve used the RPG Makers since its early incarnations, always fascinated by its near-magical promise that anyone can use it to make games. (I fondly remember a birthday present my sister made for me using RPG Maker 2000, after reading only a basic skills tutorial.) I’ve always wondered how it worked under the hood, and was pleased to learn that the latest versions make nearly all the relevant internal code visible as Ruby classes. This solved my second issue with the older RPG Makers: their insistence on a GUI, even when it didn’t make sense. (People who scripted Warcraft 3 maps can probably emphasize with a purely GUI-based scripting language.) I even entertained the notion of reverse-engineering the binary code for events, thus allowing text-based editing and script injection for advanced users. Fortunately, Enterbrain beat me to it. And their most recent addition —RPG Maker VX— seemed solid enough for me to finally start experimenting with D.A.T.A. W.I.N.
Goal: Make a console-like, top-level window for debugging RPG Maker games at run-time.

In previous RPG Makers, you could just call “Show Message” if you wanted to check the value of some arbitrary datum. However, later versions represent “Show Message” as a series of Ruby code segments, rendering it useless for debugging scripts. Let’s say you want to check the value of Switch #10. You could do something like print(“Test: #{$game_switches[10]}”), which will show a pop-up. This technique has its uses; for example, you can sandwich complex scripts with various “print” commands to determine exactly when it fails.

A popup window in RPG Maker VX

A popup window in RPG Maker VX

It is less useful because it steals focus, both visually and literally. Here are two cases where I would find this annoying:

  • I’m testing a real-time battle system, and I want to see a message (“Hit!”) every time my projectile weapon connects with the enemy.
  • I’ve got a complex mini-game, and I want to track my main character’s HP in real-time while I walk through the thing. I cannot afford to “pause” the game every time his HP changes.

So, I want something like a console. Let’s start by opening the Script Editor (F11) and adding a new Script called Debug_Window. We’ll start simple:


class Debug_Window < Window_Base
  #Constructor
  def initialize()
    super(544/2, 0, 544/2, 416)
    self.z = 999
  end

  #Destructor
  def dispose
    self.contents.dispose
    super
  end

  #Call to print a line of text
  def print(text)
    self.contents.draw_text(0, 0, 544/2, 20, text)
  end
end

The code is pretty self-explanatory; check the documentation for Window_Base and Window if you’re not sure what self.contents.draw_text or super() do. The snippet self.z = 999 is used to position the window as high as possible above sprites, message boxes, and even the main menu. It should always be on top.
We can test this by creating an event and assigning it a “Script” command (on page 3) with the code:

myTest = Debug_Window.new
myTest.print("Testing~ ")

As you can see, we’ll need to make a few changes:

First attempt at a debug console

First attempt at a debug console

First, we need to avoid the need to call new each time we want some debugging text. Otherwise, we’ll get tons of overlapping windows. Let’s make a global reference. Open the Script Editor and find the script “Main”. Add the single line $Debug = Debug_Window.new before the game initializes.

Editing the game's initialization code

Editing the game's initialization code

Now, change our event code to:

$Debug.print("Testing~ ")

This code works, and is very portable, but there’s an unintended side-effect of making $Debug global, as you can see.

A side-effect of initializing $Debug in "main"

A side-effect of initializing $Debug in "main"

That’s right, you have access to your new window everywhere, even the title screen. I consider this a bonus, because it means you can add text to it at any possible moment (e.g., when teleporting between maps). But we’ve got to make this thing invisible! Looking through Window_Base, you should be able to figure this out for yourself —just set self.windowskin to nil. We should also probably extract commonly-used numbers into constants, as this improves readability. Finally, we’ll add an instance variable, @ySoFar, and a method “clear”, which are used to easily allow multiple lines of text. Here’s the final Debug_Window script.

class Debug_Window < Window_Base
  #RPG Maker window size in pixels
  MAX_WINDOW_WIDTH = 544
  MAX_WINDOW_HEIGHT = 416

  TEXT_HEIGHT = 20 #Just a guess

  def initialize()
    super(MAX_WINDOW_WIDTH/2, 0, MAX_WINDOW_WIDTH/2, MAX_WINDOW_HEIGHT)
    self.z = 999
    self.windowskin = nil  #No background or border

    @ySoFar = 0 #Start drawing lines of text at the top
  end

  def dispose
    self.contents.dispose
    super
  end

  def print(text)
    self.contents.draw_text(0, @ySoFar, MAX_WINDOW_WIDTH/2, TEXT_HEIGHT, text)
    @ySoFar += TEXT_HEIGHT  #Move an invisible “cursor”
  end

  def clear
    #To clear the console, we must first clear the cached
    # bitmap “self.contents”. Then, we reset @ySoFar
    self.contents.clear
    @ySoFar = 0
  end
end

Just to make this more interesting, let’s make that NPC says something different each time:

id = rand($data_actors.size-1)+1
act_name = $game_actors[id].name
my_str = "actor[#{id}] = "
my_str += act_name
$Debug.print(my_str)

The results are just what we wanted.

Our completed debug window

Our completed debug window

Possible Improvements: Word-wrapping and the ability to scroll a window (or automatically clear it when it gets full) might be nice, but this simple window is probably sufficient for most debugging. If you have a custom battle/menu system, then you might want to add a set of flags like so:

DEBUG_ON = true
ERRORS_ON = true
WARNINGS_ON = true
TYPE_DEBUG = 0
TYPE_ERROR = 1
TYPE_WARNING = 2

…and change print to color messages based on their TYPE. So, error messages are red, warnings are orange, and debug messages are white. The function returns if DEBUG_ON, ERRORS_ON, or WARNINGS_ON (respectively) are set to false. This allows you to leave your debug messages in the source, but disable them when you distribute your game (or if you don’t want to see them). If you’re really fancy, you can allow “clear” to work by TYPE as well. For example, you could clear only error messages and shift the remaining ones up. Experiment, and modify this code to your needs.

3 Comments

Filed under Uncategorized

3 Responses to [RM-1] A Debug Window

  1. Pingback: [RM-4] TCP Sockets in RPG Maker VX « Making Games the Hardest Way Possible

  2. Speed@

    Instead of defining variables MAX_WINDOW_WIDTH and MAX_WINDOW_HEIGHT and then using them, you could use Graphics.height and Graphics.width, that then allways returns correct screen size, even if you resize the screen, and you don’t need to manually set the numbers.

    • sorlokreaves

      > Graphics.height and Graphics.width, that
      > then allways returns correct screen size

      Great advice, thanks!

      To my readers: you can find documentation on “Graphics” in RPG Maker VX’s “help” section; it’s considered a “built-in module”, so there’s no Ruby source code for it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s