This is an add-on for the default message systems, or for those custom message systems that are compliant. It permits the game developer to present an image behind the default message window, and even allow for the image to display cel animation properties.
Essentially, one can present characters that appear to be talking.
Script
Instructions/Configuration
Code:
#==============================================================================
# ** Animated Message Profiles
#------------------------------------------------------------------------------
# by DerVVulfman
# Version 1.0
# 06-08-2025 (MM/DD/YYYY)
# RGSS / RPGMaker XP
#==============================================================================
#
# > INSTRUCTION / CONFIGURATION PAGE <
#
#==============================================================================
#
# INTRODUCTION:
# =============
#
# This is an add-on for the default message systems, or for those custom mes-
# sage systems that are compliant. It permits the game developer to present
# an image behind the default message window, and even allow for the image to
# display cel animation properties.
#
# Essentially, one can present characters that appear to be talking.
#
#
#------------------------------------------------------------------------------
#
# INSTALLATION:
# =============
#
# At bare minimum, place both the Instruction / Configuration and the Engine
# scripts below Scene_Debug and above Main.
#
# sage systems that are compliant. It permites the game developer to present
# The configuration page defines the actual profiles that are displayed, the
# location where they are shown, and if they are indeed animated.
#
#
#------------------------------------------------------------------------------
#
# CONFIGURATION SETTINGS:
# =======================
#
# There is only one thing you can do within the configuration section at the
# bottom of this page. And that is to create profiles that appear behind the
# message window, whether they are animated or not.
#
# Profiles are defined within a hash array. Each of these profiles are iden-
# tified by a key, a string value that can be easily referenced. And each of
# these profiles points to an array indicating where the profiles are placed,
# the speed in which the profiles circulate between animated frames, and the
# list of one (or more) profile animation frames.
#
# Syntax: DATA[key] = [ xpos, ypos, speed, repeat img, img, img... img ]
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# * key: A string (in quotes) that separates it from other profiles.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# * xpos: X-Position or Coordinates where the sprite(s) will draw.
# * ypos: Y-Position or Coordinates where the sprite(s) will draw.
# * speed: (in frames per second) The number of frames between each image.
# * repeat: (a true/false value) Indicating if multiple images repeat
# * img: An image file (or set of file) in the Graphics\Pictures folder.
#
# You can show one single image behind the message box with the following
# example:
# DATA["LunarSmile"] = [50,120,4,true'actor1']
# -- or --
# DATA["LunarSmile"] = [50,120,4,true'actor1']
#
# Or, you can render a profile that draws three images in the pictures folder
# in rapid succession like so:
#
# DATA["ZeldaIsLaughing"] = [50,120,4, true 'actor1','actor1a','actor1b']
# -- if the animation continues until closed --
# DATA["ZeldaIsLaughing"] = [50,120,4, false 'actor1','actor1a','actor1b']
# -- if the animation ends after all three images have been shown --
#
#
#------------------------------------------------------------------------------
#
# MESSAGE WINDOW COMMANDS:
# ========================
#
# DISPLAYING THE PROFILE:
#
# You may display a profile by using the Message Code: \AB[key].
#
# While the key must have quotes when defined in the module, the message
# code's key value does not use quotes.
#
# EX: \ab[ZeldaIsLaughing]That is so funny!!!
#
# The above example would display an animated profile with the defined
# profile name of 'ZeldaIsLaughing' with text following immediately.
#
# Alternately, you may use a script call prior to the display of the
# message with the 'set_profile' command like so:
# @>Script: set_profile("ZeldaIsLaughing")
# @>Text: That is so funny!!!!"
#
# - - - - -
#
# HOLDING A PROFILE PRESENT
#
# Normally, the image vanishes when you close a window. However, there may be
# instances where a character is delivering multiple message windows of text
# and you want the image to remain for the very next message.
#
# For this, you need to apply the 'hold_profile' script call on the message
# the contains the current profile. This is to prevent it from erasing the
# profile before the message ends. This may appear like so:
#
# @>Script: set_profile("ZeldaIsLaughing")
# @>Script: hold_profile
# @>Text: That is so funny!!!!"
# @>Text: I am just laughing uncontrollably!!!!"
#
# This example would use the same profile image for both messages. However,
# the below exaple would have its third message window without the profile.
#
# @>Script: set_profile("ZeldaIsLaughing")
# @>Script: hold_profile
# @>Text: That is so funny!!!!"
# @>Text: I am just laughing uncontrollably!!!!"
# @>Text: Okay, I'm done now."
#
# To continue with the image remaining in place, you must use the hold_profile
# command before each message that you want to PREVENT the profile's erasure.
#
# - - - - -
#
# SWAPPING A PROFILE PRESENT
#
# For use in tandem with the above 'hold_profile' call, this is a special
# command that lets you switch from one profile set to another without the
# profile sprite erasing. Unlike the hold_profile call, the 'swap_profile'
# is run right before the new message is shown, and used in tandem with the
# application of a new profile like so:
#
# @>Script: set_profile("ZeldaIsLaughing")
# @>Script: hold_profile
# @>Text: That is so funny!!!!"
# @>Script: swap_profile
# @>Text: \AB[ZeldaCry]Waaahhh!"
#
# This would provide a more seamless change in character behavior between
# messages without the character needing to vanish and be redrawn.
#
#
#------------------------------------------------------------------------------
#
# PAPERDOLL/BITMAP COMPATABILITY:
# ===============================
#
# paper doll (noun)
# 1. A paper or cardboard representation of a person usually in two dimen-
# sions for children to play with.
# 2. Figures cut out of paper or thin card, with separate clothes, also made
# of paper, that are usually held onto the dolls by paper folding tabs.
#
# Sometimes called a Visual Equipment script, a paperdoll system is one that
# can change a character's appearance based on the gear attached.
#
# While Animated Message Profiles does not have a built-in paperdoll system,
# it contains an area where changes to a profile's appearance may be made. It
# is within the Window_Message class, and is a specifically defined method to
# grant a would-be scripter access to the bitmaps to adjust.
#
# In short, I made a method a scripter can mess with. ^_^
#
# Line # 315: update_profile_reader
#
#
#------------------------------------------------------------------------------
#
# NOTES ON THE EXAMPLE CONFIG:
# ============================
#
# The two profiles are using images found in the 'Graphics\Profiles' folder.
# And in that folder, there are only two files, "Ikuno1.png" & "Ikuno2.png".
#
# You use multiple image files to creat an animation, and at least one file
# to create a portrait if static and not animated.
#
# The first profile is that of "Ikuno". The profile will appear at coordi-
# nates 80,140 which would line up nice with the default message window if
# it is at the bottom of the screen. The speed is set to 4, which means the
# individual cels change after 4 frames (in framerate). It is set to false,
# this indicates it will only cycle through all the animation cels once. And
# it only has two images: "Ikuno1.png" and "Ikuno2.png". This means that it
# only plays the two images in sequence once... and stops.
#
# The second profile is that of "Ikuno2". The profile will appear at coordi-
# nates 80,140 the same as the first. The speed is set to 0, however, this
# is an illegal value as the animation speed rate cannot go below '1'. The
# repeat value is set to 'true' so it will play every animation frame in its
# set over and over aggain. And it lists "Ikuno1", "Ikuno2" and "Ikuno1".
#
# The third profile is that of "Ikuno3". And this one is merely a static,
# one frame/image profile. Ergo, it will not appear animated.
#
# - - - - -
#
# Example I used with the three profile settings:
#
#
# @>Script: hold_profile
# @>Text: \AB[Ikuno]What? Yeah, my mouth isn't moving.
# @>Script: swap_profile
# @>Text: \AB[Ikuno2]Yap Yap Yap!
# @>Text: Peekaboo... you don't see me
# @>Script: set_profile("Ikuno3")
# @>Text: Now you do.
#
#
#------------------------------------------------------------------------------
#
# COMPATABILITY:
# ==============
#
# Designed for message systems compliant with RPGMaker XP's default system.
# All default scripts aliased.
#
#
#==============================================================================
#
# TERMS AND CONDITIONS:
# =====================
#
# Free to use, even in commercial projects. However, I will need some form
# of due credit.
#
#
#==============================================================================
module Profiles
# --------------------------------------------------------------------------
DATA = {} # Do Not Touch
# --------------------------------------------------------------------------
˂#==============================================================================
# ** Animated Message Profiles
#------------------------------------------------------------------------------
# by DerVVulfman
# Version 1.0
# 06-08-2025 (MM/DD/YYYY)
# RGSS / RPGMaker XP
#==============================================================================
#
# > MAIN SYSTEM PAGE <
#
#==============================================================================
#==============================================================================
# ** RPG::Cache
#------------------------------------------------------------------------------
# The module that loads each of RPGXP's graphic formats, creates a Bitmap
# object, and retains it.
#==============================================================================
module RPG::Cache
#------------------------------------------------------------------------
# * Profile image
# filename : filename of the cached bitmap
#------------------------------------------------------------------------
def self.profiles(filename)
begin
self.load_bitmap("Graphics/Profiles/", filename)
rescue
self.load_bitmap("Graphics/Profiles/", "")
end
end
end
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
# This class handles data surrounding the system. Backround music, etc.
# is managed here as well. Refer to "$game_system" for the instance of
# this class.
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :profile_name # Name of profile image data
attr_accessor :profile_hold # Profile do not erase flag
attr_accessor :profile_swap
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias msg_profiles_game_system_initialize initialize
#==============================================================================
# ** Window_Message
#------------------------------------------------------------------------------
# This message window is used to display text.
#==============================================================================
class Window_Message < Window_Selectable
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias msg_profiles_windows_initialize initialize
alias msg_profiles_windows_dispose dispose
alias msg_profiles_windows_terminate_message terminate_message
alias msg_profiles_windows_refresh refresh
alias msg_profiles_windows_update update
#--------------------------------------------------------------------------
# * Original methods Aliased
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
#
msg_profiles_windows_initialize # Run the original method
initialize_message_profile # Create profile data
#
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
def dispose
#
@profile.dispose # Dispose of profile sprite
msg_profiles_windows_dispose # Run the original method
#
end
#--------------------------------------------------------------------------
# * Terminate Message
#--------------------------------------------------------------------------
def terminate_message
#
msg_profiles_windows_terminate_message # Run the original method
terminate_message_profile # Terminate profiledata
#
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
#
refresh_message_profile # Perform profile refresh
msg_profiles_windows_refresh # Run the original method
#
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
#
update_message_profile if @contents_showing # Perform update if showing
msg_profiles_windows_update # Run the original method
#
end
#--------------------------------------------------------------------------
# * New Content
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# * Object Initialization : Creation of clear profile data variables
#--------------------------------------------------------------------------
def initialize_message_profile
#
@profile = Sprite.new # Create the profile sprite
@profile.z = self.z - 1 # Set it behind the message
@msgprofile = [] # Create empty filename array
@msgwait_count = 0 # Reset the wait count
@profilerepeat = true # Reset repeat function
#
end
#--------------------------------------------------------------------------
# * Terminate Message : Resetting of profile
#--------------------------------------------------------------------------
def terminate_message_profile
#
terminate_message_profile_erase # Clear profile image
$game_system.profile_hold = false # Clear profile hold flag
#
end
#--------------------------------------------------------------------------
# * Terminate Message : Erasing of profile image and data
#--------------------------------------------------------------------------
def terminate_message_profile_erase
#
return if $game_system.profile_hold # Clear profile hold
return if @profile.nil? # Exit if no profile sprite
@profile.visible = false # Make profile sprite hidden
unless @profile.bitmap.nil? # Only if there is a bitmap
@profile.bitmap.dispose # ..dispose of the bitmap
end
@profile.bitmap = nil # Nil out the profile bitmap
@msgprofile = [] # Clear the filename array
$game_system.profile_name = nil # Erase the profile name
@profilerepeat = true
#
end
#--------------------------------------------------------------------------
# * Refresh : Acquiring and setting profile data name and updating message
#--------------------------------------------------------------------------
def refresh_message_profile
#
return if $game_temp.message_text.nil? # Exit if there's no message
text = $game_temp.message_text # Get the message text
text.gsub!(/\\[Aa][Bb]\[(.*?)\]/) do # Substitute the \ab code
$game_system.profile_name = $1 # ..and set the profile name
""
end
$game_temp.message_text = text # Replace the message text
#
end
#--------------------------------------------------------------------------
# * Frame Update: Profile display and animation
#--------------------------------------------------------------------------
def update_message_profile
#
unless $game_system.profile_swap # Unless swapping profiles
return if @profilerepeat == false # Exit method on no repeat
end
#
if @msgwait_count > 0 # If a wait count exists
@msgwait_count -= 1 # ..reduce the wait count
return # ..and exit the method
end
#
update_profile_generator # Run the profile generator
#
return if @bitmap.nil? # Exit if not valid bitmap
return if @profile.bitmap.nil? # Exit if no profile bitmap
return if @pattern.nil? # Exit if no defined pattern
return if @sprite_numbers.nil? # Exit if no sprite number set
return if @msgprofile.nil? # Exit if no configed profile
#
@pattern = (@pattern + 1) % @sprite_numbers # Set animation pattern
if @pattern == (@sprite_numbers-1) # If at end of loop
@profilerepeat = @msg_repeat # .. determine if repeating
end
#
sx = @pattern * @cw # Define which image to use
src_rect = Rect.new(sx, 0, @cw, @ch) # Acquire the sprite image
@profile.bitmap.clear # Clear the sprite bitmap
@profile.bitmap.blt(0, 0, @bitmap, src_rect) # Apply the new bitmap
@msgwait_count = @msg_count # Reset the wait count
@profile.visible = true # Show the provile sprite
#
end
#--------------------------------------------------------------------------
# * Update: Generate the Profile Animation Strip
#--------------------------------------------------------------------------
def update_profile_generator
#
return if $game_system.profile_name.nil? # Exit if no profile name
return if $game_system.profile_name == "" # Exit if profile name empty
name = $game_system.profile_name # Get the profile name
#
return unless update_profile_empty? # Exit if exist or is to swap
return if Profiles::DATA.nil? # Exit if no configured data
return unless Profiles::DATA.has_key?(name) # Exit if no profile configed
#
if $game_system.profile_swap == true # If profiles are swapped
@profilerepeat = true # Ensure repeat at restart
end
#
unless $game_system.profile_swap == true # If profiles are not swapped
@profile = Sprite.new # ..make a new profile sprite
end
#
@msgprofile = Profiles::DATA[name] # Acquire configured profile
@profile.z = self.z - 1 # Set profile behind message
@profile.x = @msgprofile[0] # Set x-coordinate of profile
@profile.y = @msgprofile[1] # Set y-coordinate of profile
@msg_count = @msgprofile[2] # Set Message wait count
@msg_repeat = @msgprofile[3] # Set Message repeat flag
files = @msgprofile[4] # Set first file in list
@msg_count = 1 if @msg_count < 1 # Set wait count minimum
@pattern = 0 # Reset profile pattern
#
@sprite_numbers = @msgprofile.size-4 # Get size of configed profile
bitmap = RPG::Cache.profiles(files) # Set first bitmap
@cw = bitmap.width # Get profile strip width
@ch = bitmap.height # Get character height
width = @cw * @sprite_numbers # Get single-image width
@bitmap = Bitmap.new(width, @ch) # Create simgle-image bitmap
#
for i in 0...@sprite_numbers # Cycle through sprites
src = update_profile_reader(@msgprofile,i) # Acquire individual sprite
src_rect = Rect.new(0, 0, @cw, @ch) # Acquire sprite rectangle
@bitmap.blt(@cw*i, 0, src, src_rect) # Blit sprite
end
#
@profile.bitmap = Bitmap.new(@cw, @ch) # Create clean profile bitmap
@profile.visible = true # Make visible
$game_system.profile_swap = false # And clear swap flag
#
end
#--------------------------------------------------------------------------
# * Update: Testing if there is no image, or if image is to be replaced.
#--------------------------------------------------------------------------
def update_profile_empty?
#
if $game_system.profile_swap == true # If swapping profiles set
return true # ..Exit method true
end
if @profile.bitmap.nil? # If there is no bitmap
return true # ..Exit method true
end
return false # Exit method false
#
end
#--------------------------------------------------------------------------
# * Update: Acquire each Profile from the Animation Strip
# name : used to identify the profile for possible editing
# index : index within the animation strip
#--------------------------------------------------------------------------
def update_profile_reader(name, index)
#
# Acquire the cached bitmap
src_bitmap = RPG::Cache.profiles(@msgprofile[index+4])
# Possible edits to the bitmap may go here... before the returned bitmap
return src_bitmap
#
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Set Message Profile outside of Show Text box
# key : key as defined in the Profiles Module
#--------------------------------------------------------------------------
def set_profile(key=nil)
#
if key.nil? # If no valid key supplied
$game_system.profile_name = nil # ..set erased profile name
return # ..and exit method.
end
unless Profiles::DATA.has_key?(key) # If no valid profile given
$game_system.profile_name = nil # ..set erased profile name
return # ..and exit method.
end
$game_system.profile_name = key # Set the profile name
#
end
#--------------------------------------------------------------------------
# * Set image hold/freeze to use in next message
#--------------------------------------------------------------------------
def hold_profile
#
$game_system.profile_hold = true # Set the profile hold flag
#
end
#--------------------------------------------------------------------------
# * Set sprite frozent to allow profile image and animation swapping
#--------------------------------------------------------------------------
def swap_profile
#
$game_system.profile_swap = true # Set the profile swap flag
#
end
end
Instructions
Within the main header page / configuration page
Compatibility
Designed to work with the default message system, but should be compliant with most that are structurally similar.
Terms and Conditions
Free to use, even in commercial projects. However, I will need some form of due credit.