Variable & Switch Debug HUD
Version: 1.0
Author: modern algebra
Date: April 15, 2010
Version History
- <Version 1.0> 04.15.2010 - Original Release
Description
This script is an extra feature that only works in Test Play. Basically, whenever a switch, self switch, or variable are modified, this script will display the modification just made and the result in the bottom left corner of the screen. This is useful for debugging complicated event systems as it allows you to track what is happening to the variable, switch, or self-switch every time you modify them.
Features
- Easy way to track variables, switches, and self-switches when debugging event systems or cut scenes
- Only operates when in Test Play
- Can be toggled on and off at any time with a button
- Can exclude certain variables, switches, or self-switches from showing up on the HUD if they update so frequently it is annoying
ScreenshotsObviously, this is a gibberish event and you wouldn't have this many on screen at once, but it shows a little of how it works
Instructions
It's pretty much plug & play, but please read the header of the script if you wish to configure some aspects of it.
Script
#==============================================================================
# Variable & Switch Debug HUD
# Version: 1.0
# Author: modern algebra (rmrk.net)
# Date: April 15, 2010
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
#
# This script is an extra feature that only works in Test Play. Basically,
# whenever a switch, self switch, or variable are modified, this script will
# display the modification just made and the result in the bottom left corner
# of the screen. This is useful for debugging complicated event systems as it
# allows you to track what is happening every frame.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Instructions:
#
# Place this script above Main and below Materials in the Script Editor (F11)
#
# It will work simply by plugging it in, and you can toggle it on and off
# at any time simply by pressing F8 (or whatever you replace it with below).
# Note: This will operate only when test playing! So don't worry. You can
# also toggle it on and off through a call script command:
# $game_system.vsd_switch = true/false
# where true turns the HUD on and false turns it off.
#
# You can also configure lots of stuf with this script: see line 31
#==============================================================================
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# VSD_SHOW_FRAMES - This is how many frames each modification shows up for.
VSD_SHOW_FRAMES = 180
# VSD_EXCLUDED_SCENES - If you want to exclude any scenes from showing this for
# whatever reason, just put the name of the scene in the array, without quotes
VSD_EXCLUDED_SCENES = []
# VSD_EXCLUDED_VARIABLES - if this array contains any variable ID, then any
# modifications of that variable will not be shown. This is useful if you have
# variables that are updated frequently.
VSD_EXCLUDED_VARIABLES = []
# VSD_EXCLUDED_SWITCHES - if this array contains any switch ID, then any
# modifications of that switch will not be shown. This is useful if you have
# switches that are updated frequently.
VSD_EXCLUDED_SWITCHES = []
# VSD_EXCLUDED_SELFSWITCHES - if this array contains any self switch key, then
# any modifications of that switch will not be shown. A self-switch key is:
# [map_id, event_id, label] (label is "A", "B", "C", "D")
VSD_EXCLUDED_SELFSWITCHES = []
# VSD_TOGGLE_BUTTON - this is the button you press to turn the HUD on or off
VSD_TOGGLE_BUTTON = Input::F8
# VSD_DEFAULT_ON - this is whether the HUD is on by default or off
VSD_DEFAULT_ON = true
# VSD_SWITCH_COLOR - this is the color of the text showing switches. It can be
# either an integer, referring to the colours of the windowskin palette, or
# it can be an RGBA array [red, green, blue, alpha]
VSD_SWITCH_COLOR = 23
# VSD_VARIABLE_COLOR - this is the color of the text showing variables. It can
# be either an integer, referring to the colours of the windowskin palette, or
# it can be an RGBA array [red, green, blue, alpha]
VSD_VARIABLE_COLOR = 6
# VSD_SELFSWITCH_COLOR - this is the color of the text showing selfswitches. It
# can be either an integer, referring to the colours of the windowskin
# palette, or it can be an RGBA array [red, green, blue, alpha]
VSD_SELFSWITCH_COLOR = 31
# VSD_BACKCOLOR - this is the color of the background to all the texts. It can
# be either an integer, referring to the colours of the windowskin palette, or
# it can be an RGBA array [red, green, blue, alpha]
VSD_BACKCOLOR = [0, 0, 0, 60]
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# END EDITABLE REGION
#//////////////////////////////////////////////////////////////////////////////
#==============================================================================
# ** Game_System
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new instance variable - vsd_switch
#==============================================================================
class Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :vsd_switch
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modrna_vsdtoggle_init_8cs3 initialize
def initialize (*args)
@vsd_switch = VSD_DEFAULT_ON
modrna_vsdtoggle_init_8cs3 (*args) # Run Original Method
end
end
#==============================================================================
# ** Game_Switches
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - []=
#==============================================================================
class Game_Switches
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set Switch
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modbr_vsd_setswitch_4tc2 []=
def []= (switch_id, *args)
prev_value = self[switch_id]
modbr_vsd_setswitch_4tc2 (switch_id, *args)
if !VSD_EXCLUDED_SWITCHES.include? (switch_id) && $scene.is_a? (Scene_Base)
$scene.vsd_show_operation (true, switch_id, prev_value)
end
end
end
#==============================================================================
# ** Game_SelfSwitches
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - []=
#==============================================================================
class Game_SelfSwitches
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set Switch
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias mrnal_vsd_stslfswt_6uj2 []=
def []= (key, *args)
prev_value = self[key]
mrnal_vsd_stslfswt_6uj2 (key, *args)
if !VSD_EXCLUDED_SELFSWITCHES.include? (key) && $scene.is_a? (Scene_Base)
$scene.vsd_show_operation (true, key, prev_value)
end
end
end
#==============================================================================
# ** Game_Event
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new method - vsd_event_name
#==============================================================================
class Game_Event
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Event Name
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def vsd_event_name
return @event ? @event.name : ""
end
end
#==============================================================================
# ** Game Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - command_122 (Variable)
#==============================================================================
class Game_Interpreter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Control Variable
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modalg_vds_cntrlvar_7uj4 command_122
def command_122 (*args)
prev_values = {}
for id in @params[0]..@params[1]
prev_values[id] = $game_variables[id]
end
val = modalg_vds_cntrlvar_7uj4 (*args)
if $scene.is_a? (Scene_Base)
for id in @params[0]..@params[1]
$scene.vsd_show_operation (false, id, prev_values[id], @event_id, @params[2, @params.size - 2]) if !VSD_EXCLUDED_VARIABLES.include? (id)
end
end
return val
end
end
#==============================================================================
# ** Sprite_ShowOperations
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This sprite shows the variable & switch operations onscreen during play test
#==============================================================================
class Sprite_ShowOperation < Sprite_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize(viewport, operation, *args)
super (viewport)
self.bitmap = Bitmap.new (Graphics.width, 24)
if operation
if args[0].is_a? (Integer)
draw_switch_operation (*args)
else
draw_selfswitch_operation (*args)
end
else
draw_variable_operation (*args)
end
@frame_count = VSD_SHOW_FRAMES
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Dispose
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def dispose (*args)
super (*args)
self.bitmap.dispose
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update
@frame_count -= 1
return if self.disposed?
if @frame_count == 0
self.dispose
elsif @frame_count < 25
self.opacity -= 10
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Text Color
# n : Text color number (0-31) or RGBA array
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def text_color(n)
if n.is_a? (Integer)
x = 64 + (n % 8) * 8
y = 96 + (n / 8) * 8
return Cache.system ("Window").get_pixel(x, y)
else
return Color.new (*n)
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Switch Operation
# switch_id : ID of switch operated on
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_switch_operation (switch_id, prev_value)
return if switch_id > $data_system.switches.size
prev_value_s = prev_value ? "ON" : "OFF"
label = sprintf ("S%04d: #{$data_system.switches[switch_id]} (#{prev_value_s})", switch_id)
value = $game_switches[switch_id] ? "ON" : "OFF"
text = "#{label} = #{value}"
tw = self.bitmap.text_size (text).width + 8
self.bitmap.fill_rect (Graphics.width - tw, 0, tw, 24, text_color (VSD_BACKCOLOR))
self.bitmap.font.color = text_color (VSD_SWITCH_COLOR)
self.bitmap.draw_text (0, 0, self.bitmap.width, 24, text, 2)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw SelfSwitch Operation
# switch_id : ID of switch operated on
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_selfswitch_operation (key, prev_value)
prev_value_s = prev_value ? "ON" : "OFF"
event = $game_map.events ? $game_map.events[key[1]] : nil
return if event == nil
label = sprintf ("SS:#{key[2]} of EV%03d: #{event.vsd_event_name} (#{prev_value_s})", key[1])
value = $game_self_switches[key] ? "ON" : "OFF"
text = "#{label} = #{value}"
tw = self.bitmap.text_size (text).width + 8
self.bitmap.fill_rect (Graphics.width - tw, 0, tw, 24, text_color (VSD_BACKCOLOR))
self.bitmap.font.color = text_color (VSD_SELFSWITCH_COLOR)
self.bitmap.draw_text (0, 0, self.bitmap.width, 24, text, 2)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Variable Operation
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_variable_operation (var_id, prev_value, event_id = 0, params = [])
return if var_id > $data_system.variables.size
label = sprintf ("V%04d: #{$data_system.variables[var_id]} (#{prev_value})", var_id)
result = $game_variables[var_id].to_s
# Determine operation string
op_s = case params[0]
when 0 then " = "
when 1 then " + "
when 2 then " - "
when 3 then " * "
when 4 then " / "
when 5 then " % "
end
value_s = "0"
# Determine operand
case params[1]
when 0 # Constant
if params[0] == 0
op_s = ""
value_s = ""
else
value_s = "#{params[2]}"
end
when 1 # Variable
value_s = sprintf ("V%04d: #{$data_system.variables[params[2]]} (#{$game_variables[params[2]]})", params[2])
when 2 # Random
value_s = "Random No. #{params[2]} - #{params[3]}"
when 3 # Items Held
value_s = "Amount of #{$data_items[params[2]].name}(s) held (#{$game_party.item_number($data_items[params[2]])})"
when 4 # Actor
actor = $game_actors[params[2]]
if actor != nil
value_s = "#{actor.name}'"
value_s += "s" unless actor.name[-1, 1] == "s"
stat_s = case params[3]
when 0 then "Level (#{actor.level})"
when 1 then "EXP (#{actor.exp})"
when 2 then "HP (#{actor.hp})"
when 3 then "MP (#{actor.mp})"
when 4 then "Max HP (#{actor.maxhp})"
when 5 then "Max MP (#{actor.maxmp})"
when 6 then "Attack (#{actor.atk})"
when 7 then "Defence (#{actor.def})"
when 8 then "Spirit (#{actor.spi})"
when 9 then "Agility (#{actor.agi})"
end
value_s += " #{stat_s}"
end
when 5 # Enemy
enemy = $game_troop.members[params[2]]
if enemy != nil
value_s = "#{enemy.name}'"
value_s += "s" unless enemy.name[-1, 1] == "s"
stat_s = case params[3]
when 0 then "HP (#{enemy.hp})"
when 1 then "MP (#{enemy.mp})"
when 2 then "Max HP (#{enemy.maxhp})"
when 3 then "Max MP (#{enemy.maxmp})"
when 4 then "Attack (#{enemy.atk})"
when 5 then "Defence (#{enemy.def})"
when 6 then "Spirit (#{enemy.spi})"
when 7 then "Agility (#{enemy.agi})"
end
value_s += " #{stat_s}"
end
when 6 # Character
case params[2]
when -1
character = $game_player # Player
value_s = "Player's"
when 0
character = $game_map.events ? $game_map.events[event_id] : nil
else
character = $game_map.events ? $game_map.events[params[2]] : nil
end
if character != nil
if value_s != "Player's"
value_s = "#{character.vsd_event_name}'"
value_s += "s" unless character.vsd_event_name[-1, 1] == "s"
end
stat_s = case params[3]
when 0 then "X Coordinate (#{character.x})"
when 1 then "Y Coordinate (#{character.y})"
when 2 then "Direction (#{character.direction})"
when 3 then "Screen X (#{character.screen_x})"
when 4 then "Screen Y (#{character.screen_y})"
end
value_s += " #{stat_s}"
end
when 7 # Other
value_s = case params[2]
when 0 then "Map ID (#{$game_map.map_id})"
when 1 then "Party Size (#{$game_party.members.size})"
when 2 then "Party's Gold (#{$game_party.gold})"
when 3 then "Steps Taken (#{$game_party.steps})"
when 4 then "Play Time (#{Graphics.frame_count / Graphics.frame_rate})"
when 5 then "Timer (#{$game_system.timer / Graphics.frame_rate})"
when 6 then "Save Count (#{$game_system.save_count})"
end
end
text = "#{label}#{op_s}#{value_s} = #{result}"
tw = self.bitmap.text_size (text).width + 8
self.bitmap.fill_rect (Graphics.width - tw, 0, tw, 24, text_color (VSD_BACKCOLOR))
self.bitmap.font.color = text_color (VSD_VARIABLE_COLOR)
self.bitmap.draw_text (0, 0, self.bitmap.width, 24, text, 2)
end
end
#==============================================================================
# ** Scene_Base
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - start, initialize, update
# new method - vsd_show_operation
#==============================================================================
class Scene_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Start Processing
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias malg_vsd_strt_6yh1 start
def start (*args)
@vsd_shown_operations = []
@vsd_viewport = Viewport.new (0, 0, Graphics.width, Graphics.height)
@vsd_viewport.z = 1000
@vsd_viewport.oy = 128 if self.is_a? (Scene_Battle)
@vsd_scroll = 0
malg_vsd_strt_6yh1 (*args) # Run Original Method
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Terminate
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias ma_vsd_trmnt_8ik1 terminate
def terminate (*args)
@vsd_shown_operations.each { |sprite| sprite.dispose unless sprite.disposed? }
@vsd_shown_operations.clear
ma_vsd_trmnt_8ik1 (*args) # Run Original Method
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modrn_vswtchd_updte_5th3 update
def update (*args)
if $TEST
if Input.trigger? (VSD_TOGGLE_BUTTON) # Toggle feature
$game_system.vsd_switch = !$game_system.vsd_switch
if !$game_vsd_switch
@vsd_shown_operations.each { |sprite| sprite.dispose }
@vsd_shown_operations.clear
end
end
delete_array = []
for i in 0...@vsd_shown_operations.size
@vsd_shown_operations[i].update
delete_array.push (i) if @vsd_shown_operations[i].disposed?
end
delete_array.reverse.each { |i| @vsd_shown_operations.delete_at (i) }
# Move viewport if showing message
if self.is_a? (Scene_Map)
@vsd_viewport.oy = $game_message.visible && $game_message.position == 2 ? 128 : 0
end
if @vsd_scroll > 0
@vsd_scroll -= 3
@vsd_shown_operations.each { |sprite| sprite.y -= 3 }
end
end
modrn_vswtchd_updte_5th3 (*args) # Run Original Method
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Show Operation
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def vsd_show_operation (*args)
return if !$TEST || !$game_system.vsd_switch || VSD_EXCLUDED_SCENES.include? (self.class)
sprite = Sprite_ShowOperation.new (@vsd_viewport, *args)
sprite.y = @vsd_shown_operations.empty? ? Graphics.height : @vsd_shown_operations[0].y + 24
@vsd_scroll += 24
@vsd_shown_operations.unshift (sprite)
end
end
Credit
Thanks
- anonymous requestor whose name is forgotten
Support
Please post in this topic at RMRK.net for support. Please do not PM me.
Known Compatibility Issues
I am currently unaware of scripts that this is incompatible with.
Author's Notes
This script was kind of inspired by a request I saw ages ago, but I don't remember where or who made it and I think he/she only wanted to show a couple specified variables all the time. Anyway, it inspired me to write this which I think is a nice idea for when making/debugging event systems that have complicated variable and switch interactions.
Mr_Wiggles has also
converted this script to RMXP