Overview
Lich includes a built-in GTK3-based graphical interface for launching and managing game connections. The GUI provides an intuitive way to:
Select characters from saved accounts
Manage multiple game accounts
Configure connection settings
Launch scripts automatically
Manage passwords with encryption
Enabling the GUI
The GUI is enabled by default when GTK3 is available:
# GUI enabled (default)
lich --gui
lich
# Disable GUI (headless mode)
lich --no-gui
The GUI requires GTK3 to be installed. If GTK3 is not available, Lich automatically falls back to command-line mode.
Installation Requirements
Linux
sudo apt-get install ruby-gtk3
sudo dnf install rubygem-gtk3
macOS
brew install gtk+3
gem install gtk3
Windows
GTK3 Ruby bindings should be included with the Lich installer.
GUI Features
Account Management
The GUI allows you to save and manage multiple game accounts:
Add Account
Click “Add Account” and enter:
Account name
Password (encrypted storage)
Default front-end (Wizard, StormFront, etc.)
Default game (GemStone IV, DragonRealms, etc.)
Select Character
Characters from saved accounts appear in the dropdown
Launch
Click “Launch” to connect with the selected character
Password Encryption
The GUI supports three encryption modes:
Plaintext
Standard
Enhanced
Security Level: None ⚠️Passwords stored in plain text. Not recommended. encryption : plaintext
account : MyAccount
password : MyPassword123
Security Level: Medium 🔒Passwords encrypted with machine-specific key. encryption : standard
account : MyAccount
password : <encrypted_data>
Security Level: High 🔐Passwords encrypted with user-provided master password. encryption : enhanced
account : MyAccount
password : <encrypted_data>
master_password_required : true
Password encryption modes can be configured from the GUI account management interface or via command-line options (see Configuration ).
Game Selection
The GUI provides a dropdown for selecting your target game:
lib/common/gui/game_selection.rb
GAME_MAPPING = {
'GS3' => 'GemStone IV' ,
'GSX' => 'GemStone IV Platinum' ,
'GST' => 'GemStone IV Prime Test' ,
'GSF' => 'GemStone IV Shattered' ,
'DR' => 'DragonRealms' ,
'DRX' => 'DragonRealms Platinum' ,
'DRT' => 'DragonRealms Prime Test' ,
'DRF' => 'DragonRealms Fallen'
}
Front-end Selection
Choose which front-end client to use:
Wizard - Legacy GSL-based client
StormFront - XML-based Windows client
Avalon - Alternative GSL client
Genie - DragonRealms XML client
Frostbite - Modern XML client
Auto-start Scripts
Configure scripts to launch automatically on login:
auto_start_scripts :
- repository
- go2
- lnet
- infomon
Dark Mode
Lich supports GTK’s dark theme:
# Enable dark mode
lich --dark-mode=true
lich --dark-mode=on
# Disable dark mode
lich --dark-mode=false
lich --dark-mode=off
Dark mode is applied via GTK settings:
if defined? ( Gtk )
@theme_state = Lich . track_dark_mode = true
Gtk :: Settings . default . gtk_application_prefer_dark_theme = true
end
Window Management
Window Persistence
The GUI remembers window size and position between sessions:
lib/common/gui/window_settings.rb
# Settings saved to: data/login_gui_settings.yml
settings = {
width: 800 ,
height: 600 ,
position: [ 100 , 100 ]
}
Multi-Monitor Support
Window positions are constrained to visible monitors:
lib/common/gui/window_settings.rb
# Ensures window appears on screen
def constrain_to_monitor ( position , width , height )
# Validates position is within monitor bounds
end
On macOS, the GUI accounts for the menu bar:
lib/common/gui/window_settings.rb
DARWIN_SPACER = 28 # pixels
# Apply offset on macOS
spacer = darwin? ? DARWIN_SPACER : 0
window. move (x, y + spacer)
Accessibility Features
The GUI implements accessibility support:
lib/common/gui/accessibility.rb
# Make combo box accessible to screen readers
Accessibility . make_combo_accessible (
combo,
"Game Selection" ,
"Select the game for this character"
)
This provides:
Screen reader labels
Keyboard navigation
Focus management
ARIA attributes
GTK Queue for Thread Safety
GTK operations must run on the main thread:
if defined? ( Gtk )
def Gtk.queue ( & block )
GLib :: Timeout . add ( 1 ) {
begin
block. call
rescue StandardError => e
Lich . log "error in Gtk.queue: #{ e } "
end
false # don't repeat timeout
}
end
end
Usage in Scripts
# Safe GTK operations from any thread
Gtk . queue {
window = Gtk :: Window . new ( :toplevel )
window. title = "My Script Window"
window. show_all
}
Calling GTK methods directly from non-main threads will cause segmentation faults. Always use Gtk.queue when updating the GUI from scripts.
Custom GUI Windows
Scripts can create custom GTK windows:
Gtk . queue {
window = Gtk :: Window . new ( :toplevel )
window. title = "Script Config"
window. set_default_size ( 400 , 300 )
# Create vertical box layout
vbox = Gtk :: Box . new ( :vertical , 5 )
window. add (vbox)
# Add label
label = Gtk :: Label . new ( "Configuration Options" )
vbox. pack_start (label, expand: false , fill: false , padding: 5 )
# Add button
button = Gtk :: Button . new ( label: "Save" )
button. signal_connect ( 'clicked' ) {
echo "Button clicked!"
}
vbox. pack_start (button, expand: false , fill: false , padding: 5 )
window. show_all
}
Logo and Branding
Lich includes an embedded logo:
Gtk . queue {
@default_icon = GdkPixbuf :: Pixbuf . new ( file: 'logo.png' )
}
The logo appears in:
Window title bars
Task bars
Alt+Tab switchers
Troubleshooting
GUI Won’t Start
Check GTK3 Installation
ruby -e "require 'gtk3'; puts Gtk::VERSION.join('.')"
Should print GTK version (e.g., “3.24.0”)
Check Display Environment
echo $DISPLAY # Should show :0 or :1
If empty, you’re not in a graphical environment
Try Headless Mode
lich --no-gui --login=CharacterName
Check Logs
tail -f ~/lich/logs/lich.log
Look for GTK-related errors
Dark Mode Not Working
# Check if dark mode is enabled
if defined? ( Gtk )
puts Gtk :: Settings . default . gtk_application_prefer_dark_theme
# => should be true
end
If false, try:
Window Position Issues
Delete saved settings to reset:
rm ~/lich/data/login_gui_settings.yml
The window will reappear at default position on next launch.
Segmentation Faults
Segfaults are usually caused by calling GTK from non-main threads. Always use Gtk.queue { } wrapper.
# WRONG - will crash
Thread . new {
window = Gtk :: Window . new ( :toplevel )
}
# CORRECT - thread-safe
Thread . new {
Gtk . queue {
window = Gtk :: Window . new ( :toplevel )
}
}
Disabling the GUI Permanently
To always run in headless mode:
Option 1: Shell Alias
alias lich = 'lich --no-gui'
Option 2: Wrapper Script
/usr/local/bin/lich-headless
#!/bin/bash
lich --no-gui " $@ "
Option 3: Configuration File
Create a startup script that sets default options:
ARGV << '--no-gui' unless ARGV . include? ( '--gui' )
Configuration Command-line GUI options
Front-ends Supported client applications
Configuration Command-line options and setup
GTK3 Documentation Official GTK3 Ruby bindings