Original Source
- Original title: VXAce Hammy - FF9 Choice Window
- Original author: buddysievers
- Original date: November 5, 2025
- Source thread: https://forums.rpgmakerweb.com/threads/hammy-ff9-choice-window.180888/
- Source forum path: Game Development Engines > Ruby Game System (RGSS) Scripts > RGSS3 Scripts (RMVX Ace)
Summary
Hammy - FF9 Choice Window v1.03 Authentic Final Fantasy IX choice windows with speech bubbles, conditional choices, and unlimited options Introduction This script provides an authentic Final Fantasy IX choice window system for RPG Maker VX Ace. It displays choice windows with enhanced features including custom text display above choices, conditional choices, unlimited choice merging, and speech bubble positioning.
Archived First Post
Authentic Final Fantasy IX choice windows with speech bubbles, conditional choices, and unlimited options
Introduction
This script provides an authentic Final Fantasy IX choice window system for RPG Maker VX Ace. It displays choice windows with enhanced features including custom text display above choices, conditional choices, unlimited choice merging, and speech bubble positioning.
The system supports custom text display above choices with escape code support, conditional choice visibility based on game state, automatic merging of consecutive choice commands to bypass the 4-choice limit, speech bubble positioning above characters with arrow sprites, and custom window positioning with windowskin type override integration.
AI Disclaimer: Generative AI was used to refine the documentation and presentation of this script, as I am not a native English speaker. Additionally, AI was used for naming conventions in some places and for general beautification of the script.
Features
Core Choice Features
- Delayed choice window opening after message window closure
- Custom text display above choice commands with escape code support
- Per-line text alignment (left, center, right) with mixed format support
- Speech bubble positioning above characters with arrow sprites
- Conditional choices using switches, variables, or Ruby expressions
- Automatic merging of consecutive choice commands to bypass 4-choice limit
- Custom window positioning with optional x/y coordinate override
- Window type override support via Hammy FF9 Windowskin System integration
Customization System
- Configurable choice window display settings (line height, padding, cursor)
- Configurable compact spacing for empty text lines
- Configurable bubble positioning offsets and arrow sprites
- Support for complex conditions using game state references
Technical Features
- Automatic window centering when position not specified
- Automatic bubble positioning with boundary corrections
- Narrow window centering on bubble sprite when width < narrow_width
- Settings auto-reset after choice window closure
- Dynamic window sizing based on text content and choice commands
Screenshots
Configuration
Choice Window Display Settings
LINE_HEIGHT
Height of each text line in pixels for choice windows. Uses default font size by default, can be set to any integer value.
- Valid values: Any integer value
- Default: Font.default_size
Example
LINE_HEIGHT = 20
STANDARD_PADDING
Window padding size in pixels for choice windows. Controls the internal spacing between window borders and content.
- Valid values: Any integer value
- Default: 12
Example
STANDARD_PADDING = 12
WINDOW_MIN_WIDTH
Minimum starting width for choice calculations. Prevents window from being too narrow, set to 0 for automatic width.
- Valid values: Any integer value (0 for auto)
- Default: 0
Example
WINDOW_MIN_WIDTH = 0
CURSOR_OFFSET_X
Horizontal offset for the cursor in choice windows. Controls the spacing between window edge and choice command text.
- Valid values: Any integer value
- Default: 16
Example
CURSOR_OFFSET_X = 16
COMPACT_SPACING
Enable compact spacing for empty text lines. When true, empty text lines use reduced height for separation.
- Valid values: true or false
- Default: true
Example
COMPACT_SPACING = true
COMPACT_LINE_HEIGHT
Empty line height when compact spacing is enabled. Pixel height used for empty text lines when COMPACT_SPACING is true.
- Valid values: Any integer value
- Default: 6
Example
COMPACT_LINE_HEIGHT = 6
Predefined Condition Formulas
PREDEFINED_FORMULAS
Hash mapping symbol keys to condition strings. Usage in events: \cc[:key_name] instead of the full formula.
Examples
has_potion: "p.has_item?($data_items[1])"
early_game: "sys.playtime < 3600"
high_level: "a1.level >= 50"
rich: "p.gold >= 10000"
in_town: "map.map_id == 5"
- Default: {}
Bubble Positioning Settings
BUBBLE_POSITION
Hash containing all bubble positioning configuration.
- y_offset_below: Vertical offset for windows positioned below a target. Distance in pixels from character screen_y to window top when below.
- y_offset_above: Vertical gap for windows positioned above a target. Distance in pixels from the top of the target sprite to the bottom of the window. The sprite height is resolved dynamically.
- tag_y_offset_below: Vertical offset when arrow is below window. Distance in pixels from window bottom to arrow sprite position.
- tag_y_offset_above: Vertical offset when arrow is above window. Distance in pixels from window top to arrow sprite position.
- narrow_width: Threshold width for narrow window centering mode. Narrow windows center on arrow sprite rather than character.
- Valid values: Hash with defined symbol keys and integer values
- Default: { y_offset_below: 16, y_offset_above: 16, ... }
Example
BUBBLE_POSITION = {
y_offset_below: 16,
y_offset_above: 16,
tag_y_offset_below: -2,
tag_y_offset_above: -2,
narrow_width: 64
}
Default Bubble Arrow Sprite
BUBBLE_SPRITESHEET
Sprite filename for bubble arrow graphics.
Sprite Sheet Layout (64x64 pixels):
- (0-31, 0-31): up_left
- (32-63, 0-31): up_right
- (0-31, 32-63): down_left
- (32-63, 32-63): down_right
- Valid values: String containing filename without extension
- Default: 'BubbleTag'
Example
BUBBLE_SPRITESHEET = 'BubbleTag'
Colored Bubble Arrow Sprites
BUBBLE_ARROWS_COLORED
Hash mapping color themes to sprite filenames. Each sprite sheet uses the same 2x2 grid layout as the default.
- grey: Grey-themed arrow sprite sheet for grey windowskins.
- blue: Blue-themed arrow sprite sheet for blue windowskins.
- Valid values: Hash with Symbol keys and String values
- Default: { grey: 'BubbleTag_Grey', blue: 'BubbleTag_Blue' }
Example
BUBBLE_ARROWS_COLORED = {
grey: 'BubbleTag_Grey',
blue: 'BubbleTag_Blue'
}
Shadow Spritesheet
SHADOW_SPRITESHEET
Shadow sprite filename for bubble tag arrows. Shadow sprite sheet uses the same layout as the main bubble tag.
- Valid values: String containing filename without extension
- Default: 'BubbleTag_Shadow'
Example
SHADOW_SPRITESHEET = 'BubbleTag_Shadow'
Bubble Tag Shadow Settings
SHADOW_POSITION
Hash containing bubble tag shadow configuration.
- shadow_offset_x: Horizontal offset for shadow sprite in pixels. Positive values move shadow to the right.
- shadow_offset_y: Vertical offset for shadow sprite in pixels. Positive values move shadow downward.
- shadow_opacity: Opacity value for shadow sprite (0-255). Lower values create more transparent shadows.
- Valid values: Hash with defined symbol keys and integer values
- Default: { shadow_offset_x: 2, shadow_offset_y: 2, ... }
Example
SHADOW_POSITION = {
shadow_offset_x: 2,
shadow_offset_y: 2,
shadow_opacity: 128
}
Script Calls
Choice Window Configuration
choice_settings(text, x, y, type, bubble, timer, use_index)
Configures the choice window display settings before showing choices.
- text: Array of strings or hashes for text lines above choices. String format: 'Text content' (left-aligned by default). Hash format: {text: 'Text content', align: :center/:left/:right}. Empty strings use half-height spacing for separation.
- x: Optional horizontal position (nil for center, ignored if bubble mode)
- y: Optional vertical position (nil for center, ignored if bubble mode)
- type: Optional windowskin type (:default, :frame, :topbar, :help). Requires Hammy FF9 Windowskin System.
- bubble: Optional bubble configuration hash (default: {event_id: nil}). :event_id: Target character (0=player, positive=event, negative=follower). :position: Force vertical position (:above/:below). :direction: Force arrow direction (:left/:right).
- timer: Optional timer in frames (default: 0, 0 = disabled). When > 0, window auto-closes after specified frames. Timer starts when window is fully opened (openness == 255). Plays decision sound (Sound.play_ok) when timer expires.
- use_index: Optional boolean (default: false). When timer expires: true = use current selected index, false = use cancel case (or last choice if cancel is disabled).
- Returns: Nil
NOTE: :B input is now a navigation shortcut. Pressing :B will play the cancel sound and jump to the last visible choice in the window. This allows quick navigation to the bottom choice. Cancel case is only accessible via timer expiration when use_index=false.
Examples
# No text, centered window
choice_settings([], nil, nil)
# Single text line with icon
choice_settings(['\i[5] Choose wisely!'])
# Multiple lines with empty line separator (compact spacing)
choice_settings([
{text: '\c[14]Important Choice\c[0]', align: :center},
'', # Empty line
'What will you do?'
], 100, 200)
# With frame windowskin type (requires Hammy FF9 Windowskin System)
choice_settings(['\c[14]Special\c[0]'], nil, nil, :frame)
# Bubble above player character
choice_settings(['Choose an option'], nil, nil, nil, {event_id: 0})
# Bubble above event 5 with forced position
choice_settings([], nil, nil, nil, {event_id: 5, position: :above})
# Bubble for first follower with forced left arrow
choice_settings([], nil, nil, nil, {event_id: -1, direction: :left})
# Bubble below event 3 with right arrow
choice_settings(['Make your choice'], nil, nil, nil, {event_id: 3, position: :below, direction: :right})
# Timer with auto-select current index after 180 frames (3 seconds at 60fps)
choice_settings(['Choose quickly!'], nil, nil, nil, nil, 180, true)
# Timer with auto-cancel after 300 frames (5 seconds)
choice_settings(['Time is running out!'], nil, nil, nil, nil, 300, false)
# Note: If cancel case exists, it will execute. If cancel is disabled,
# the last choice in the list will be executed instead.
# Timer with bubble and auto-select
choice_settings(['Quick decision!'], nil, nil, nil, {event_id: 0}, 120, true)
Conditional Choices
Insert \cc[condition] in the choice text to hide choices based on game state. Conditions are evaluated as Ruby code with convenient shortcuts.
Available Shortcuts
- s[n]: Reference to Switch #n (e.g., s1, s10, s999)
- v[n]: Reference to Variable #n (e.g., v5, v100)
- a[n]: Reference to Actor #n (e.g., a1, a2)
- p: Reference to $game_party
- sys: Reference to $game_system
- map: Reference to $game_map
- gp: Reference to $game_player
Examples
# In the choice text of your event "Show Choices" command:
Go to town\cc[s3]
\cc[v10 >= 100]Buy sword
Special option\cc[s5 && v3 > 2]
Check gold\cc[p.gold >= 500]
System check\cc[sys.playtime < 3600]
Item check\cc[p.has_item?($data_items[1])]
Map check\cc[map.map_id == 5]
Player position\cc[gp.x > 10 && gp.y < 5]
Actor check\cc[a1.level >= 10]
Predefined Formulas
For complex conditions that are too long for the choice text input field or frequently reused, you can define formulas in the PREDEFINED_FORMULAS configuration hash and reference them by symbol.
Usage
\cc[:key_name] where :key_name is defined in PREDEFINED_FORMULAS
Configuration Example
# In the script's configuration section:
PREDEFINED_FORMULAS = {
has_potion: "p.has_item?($data_items[1])",
early_game: "sys.playtime < 3600",
high_level: "a[1].level >= 50",
rich: "p.gold >= 10000",
in_town: "map.map_id == 5"
}
Usage Examples
# In the choice text of your event "Show Choices" command:
Buy potion\cc[:has_potion]
\cc[:early_game]Early game bonus
High level quest\cc[:high_level]
Expensive item\cc[:rich]
Town exclusive\cc[:in_town]
Unlimited Choices
Multiple consecutive "Show Choices" commands are automatically merged into a single choice window, extending beyond the default 4-choice limit.
Merging Behavior
- Consecutive choice commands are merged automatically
- When merging, non-"Disallow" cancel settings take priority
- If multiple cancel settings exist, the last one is used
- Add a comment or other command to prevent merging with previous choices
- Window automatically resizes to show all available choices
Auto-Close Timer
The timer and use_index parameters enable automatic choice window closure after a specified duration. This is useful for time-limited decisions or creating urgency in dialogue choices.
Timer Behavior
- Timer starts when window is fully opened (openness == 255)
- When timer expires, the decision sound (Sound.play_ok) is played
- If use_index = true, the currently highlighted choice is selected
- If use_index = false, the cancel case is executed (or last choice if cancel is disabled)
:B Input Navigation
Pressing the :B (Cancel) button now acts as a navigation shortcut instead of cancelling the choice window.
Behavior
- Pressing :B plays the cancel sound and jumps to the last visible choice in the window
- This provides quick navigation to the bottom choice
- The cancel case is now only accessible via timer expiration when use_index = false
- This prevents accidental cancellation during choice selection
Bubble Positioning
The bubble parameter enables speech bubble-style choice positioning above characters. When event_id is provided, the window automatically positions itself above or below the target character with an arrow sprite pointing to them.
Event ID Values
- 0: Player character
- Positive (1,2,3...): Map event with that ID
- Negative (-1,-2,-3...): Follower (party member)
Position Options
- :above: Force window above character
- :below: Force window below character
- nil: Automatic positioning based on screen space
Direction Options
- :left: Force left-pointing arrow
- :right: Force right-pointing arrow
- nil: Automatic - uses character facing for left/right movement, window offset for up/down movement or when facing detection fails
Installation
- Copy the script to an open slot below ▼ Materials but above ▼ Main
- If using Hammy FF9 Windowskin System, place this script ABOVE the Windowskin System script
- If using Hammy Window Shadows, place this script ABOVE the Window Shadows script
- If using Hammy Window Headers, place this script ABOVE the Window Headers script
- Ensure your bubble arrow sprites are saved in Graphics/System with the names defined in the configuration section
- Recommended: Install Text Cache v1.04 by Mithran for optimal text rendering
Compatibility
This script is made strictly for RPG Maker VX Ace. It is highly unlikely that it will run with RPG Maker VX without adjusting.
License
MIT License - Free for commercial and non-commercial use.
Credits
This script includes code and concepts from:
- Jupiter Penguin's ChoiceEX script (Base merge and condition logic)
- Yami's Pop Message script (Base bubble tag logic)
Why VX Ace?
You might wonder why I'm still making scripts for VX Ace instead of MV/MZ. The answer is simple: Ruby is pure beauty, while JavaScript is a terrible language. Ruby's elegant syntax, intuitive design, and expressive power make scripting a joy. JavaScript, on the other hand, is a chaotic mess of inconsistencies and quirks that I simply despise.
I work with RPG Maker VX Ace for my own game project, and I share the scripts I create with the community. If you're still using VX Ace, you're in good company!
Download
Script: Download from GitHub
Demo: Download from GitHub
Features Mentioned
- Core Choice Features
- Delayed choice window opening after message window closure
- Custom text display above choice commands with escape code support
- Per-line text alignment (left, center, right) with mixed format support
- Speech bubble positioning above characters with arrow sprites
- Conditional choices using switches, variables, or Ruby expressions
- Automatic merging of consecutive choice commands to bypass 4-choice limit
- Custom window positioning with optional x/y coordinate override
- Window type override support via Hammy FF9 Windowskin System integration
- Customization System
- Configurable choice window display settings (line height, padding, cursor)
- Configurable compact spacing for empty text lines
- Configurable bubble positioning offsets and arrow sprites
- Support for complex conditions using game state references
- Technical Features
- Automatic window centering when position not specified
- Automatic bubble positioning with boundary corrections
- Narrow window centering on bubble sprite when width < narrow_width
Downloads / Referenced Files
Log in, then follow the RPG Maker Developers Group to see these download links.
Log in to downloadLicense / Terms Note
License MIT License - Free for commercial and non-commercial use. Credits This script includes code and concepts from:
Creator Claims / Removal
If you are the original creator and want this listing reassigned, edited, or removed, join BMMPlay and contact the moderators with proof that matches the original RPG Maker Web profile, linked GitHub, itch.io page, or another public creator identity.
Replies (0)
No replies yet.
Topic Summary
Loading summary...