Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

VellumFE

A modern terminal client for GemStone IV, built in Rust.

Features

  • Fast rendering - 60+ FPS with efficient text handling
  • Customizable layouts - Position and size every window
  • Flexible connections - Lich proxy or direct eAccess authentication
  • Rich highlighting - Regex-based text coloring with sound alerts
  • Full keyboard control - Rebindable keys for all actions

Quick Start

# Connect via Lich (most common)
vellum-fe --port 8000

# Direct connection (no Lich required)
vellum-fe --direct --account ACCOUNT --password PASS --character NAME

Configuration

VellumFE stores configuration in ~/.vellum-fe/:

FilePurpose
config.tomlGeneral settings
layout.tomlWindow positions and sizes
keybinds.tomlKeyboard shortcuts
highlights.tomlText highlighting rules
colors.tomlColor palette

Getting Help

Getting Started

This section covers installation and your first connection to GemStone IV.

Requirements

  • Operating System: Windows 10+, macOS 10.15+, or Linux
  • Terminal: A terminal with 256-color or true-color support
  • Connection: Either Lich running, or direct eAccess credentials

Chapters

  1. Installation - Download and set up VellumFE
  2. First Launch - Connect and explore the interface

Installation

Download

Download the latest release from GitHub Releases.

PlatformFile
Windowsvellum-fe-windows.zip
macOSvellum-fe-macos.tar.gz
Linuxvellum-fe-linux.tar.gz

Extract the archive and place vellum-fe (or vellum-fe.exe) somewhere in your PATH.

Building from Source

Requires Rust 1.70+.

git clone https://github.com/Nisugi/VellumFE.git
cd VellumFE
cargo build --release

The binary will be at target/release/vellum-fe.

Windows: OpenSSL for Direct Mode

Direct eAccess authentication requires OpenSSL. Install via vcpkg:

vcpkg install openssl:x64-windows
set VCPKG_ROOT=C:\path\to\vcpkg
cargo build --release

Verify Installation

vellum-fe --version

Should display the version number (e.g., vellum-fe 0.2.0-beta.11).

Configuration Directory

On first run, VellumFE creates ~/.vellum-fe/ with default configuration files.

You can override this location with the VELLUM_FE_DIR environment variable:

export VELLUM_FE_DIR=/custom/path

First Launch

Most players use Lich for scripting. Start Lich first, then:

vellum-fe --port 8000 --character YourCharacter
  • --port - Lich’s listening port (default: 8000)
  • --character - Your character name (used for per-character layouts)

Direct Connection

Connect without Lich using eAccess authentication:

vellum-fe --direct \
  --account YOUR_ACCOUNT \
  --password YOUR_PASSWORD \
  --character YourCharacter \
  --game prime

Games: prime, platinum, fallen, test

Note: Direct mode requires OpenSSL on Windows. See Installation.

The Interface

On successful connection, you’ll see the default layout:

┌─────────────────────────────────────────────────────────┐
│                     Main Window                         │
│  [Game text appears here]                               │
│                                                         │
├─────────────────────────────────────────────────────────┤
│ > [Command Input]                                       │
└─────────────────────────────────────────────────────────┘

Basic Controls

KeyAction
EnterSend command
Page Up/DownScroll main window
Ctrl+CCopy selected text
EscapeClose menus / cancel
F1Open main menu

Mouse Controls

  • Click links to interact with objects
  • Right-click for context menus
  • Scroll wheel to scroll windows
  • Drag window borders to resize (in edit mode)

Next Steps

Configuration

VellumFE uses TOML files for configuration, stored in ~/.vellum-fe/.

Configuration Files

FilePurpose
config.tomlGeneral settings (UI, connection, behavior)
layout.tomlWindow positions, sizes, and properties
keybinds.tomlKeyboard shortcuts
highlights.tomlText highlighting rules
colors.tomlColor palette definitions

Per-Character Configuration

When you specify --character NAME, VellumFE looks for character-specific files:

~/.vellum-fe/
├── config.toml           # Global defaults
├── layout.toml           # Global layout
├── characters/
│   └── CharName/
│       ├── config.toml   # Character overrides
│       └── layout.toml   # Character layout

Character-specific files override global settings.

Editing Configuration

You can edit files directly, or use the in-client menu:

  1. Press F1 to open the main menu
  2. Navigate to Config submenu
  3. Select the file to edit

Changes to layout are saved automatically. Other config changes require restart.

Resetting to Defaults

Delete a configuration file to reset it to defaults on next launch:

rm ~/.vellum-fe/layout.toml

Or delete the entire directory for a full reset:

rm -rf ~/.vellum-fe

config.toml

General client settings including connection, UI behavior, and sound.

Connection

[connection]
host = "127.0.0.1"
port = 8001
character = "YourName"

# For direct connection (optional - can use CLI instead)
account = "your_account"
password = "your_password"  # Stored in plain text!
game = "prime"              # prime, platinum, shattered, test

Tip: For security, pass credentials via CLI: --account X --password Y

User Interface

[ui]
buffer_size = 1000              # Lines kept per window
border_style = "single"         # single, double, rounded, thick, none
color_mode = "direct"           # direct (24-bit), indexed (256-color)

# Text selection
selection_enabled = true
selection_auto_copy = true      # Copy on mouse-up

# Commands
command_echo = true             # Show sent commands in main window
min_command_length = 3          # Min length to save in history

# Drag modifier for moving windows
drag_modifier_key = "ctrl"      # ctrl, alt, or shift

Color Modes

ModeDescription
direct24-bit true color. Use with modern terminals (kitty, alacritty, Windows Terminal)
indexed256-color with standard palette. Fallback for legacy terminals
slot256-color with custom palette. For terminals supporting OSC4

Focus Navigation

Control which windows are focusable with Tab:

[ui.focus]
types = ["text", "tabbedtext"]  # Widget types that can receive focus
exclude = ["bounty", "society"] # Specific windows to skip
order = []                      # Custom focus order (empty = layout order)

Target List

Configure the targets widget display:

[target_list]
status_position = "end"         # "end" or "start"
truncation_mode = "noun"        # "full" or "noun"
excluded_nouns = ["arm", "coal"]

[target_list.status_abbrev]
stunned = "stu"
frozen = "frz"
dead = "ded"

Highlights

Global toggles for the highlight system:

[highlights]
sounds_enabled = true           # Play sounds on match
replace_enabled = true          # Apply text replacements
redirect_enabled = true         # Route lines to other windows
coloring_enabled = true         # Apply color highlighting

Sound

[sound]
enabled = true
volume = 0.7                    # 0.0 to 1.0
cooldown_ms = 500               # Min time between sounds
startup_music = true

Text-to-Speech

[tts]
enabled = false
rate = 1.0                      # 0.5 (slow) to 2.0 (fast)
volume = 1.0
speak_thoughts = true
speak_speech = true
speak_main = false              # Usually too noisy

Stream Routing

Control how unsubscribed text streams are handled:

[streams]
# Streams to silently discard
drop_unsubscribed = [
  "speech", "whisper", "talk",
  "targetcount", "playercount"
]

fallback = "main"               # Route unknown streams here
room_in_main = true             # Show room text in main (DR only)

Logging

Capture raw XML for debugging:

[logging]
enabled = false
# dir = "logs"
# timestamps = true

Event Patterns

Regex patterns for countdown timers:

[event_patterns.stun_rounds]
pattern = '^\s*You are stunned for ([0-9]+) rounds?'
event_type = "stun"
action = "set"
duration_capture = 1
duration_multiplier = 5.0
enabled = true

layout.toml

Defines window positions, sizes, and properties.

Basic Structure

terminal_width = 120
terminal_height = 40

[[windows]]
name = "main"
widget_type = "text"
row = 0
col = 0
rows = 37
cols = 120

Window Properties

Required

PropertyTypeDescription
namestringUnique identifier
widget_typestringWidget type (see Widgets)
rowintegerTop row position (0 = top)
colintegerLeft column position (0 = left)
rowsintegerHeight in rows
colsintegerWidth in columns

Optional

PropertyTypeDefaultDescription
visiblebooltrueShow window
show_borderbooltrueDraw border
border_stylestring"single"single, double, rounded, thick
border_colorstring"#808080"Border color
border_sidesstring"all"Which sides: all, none, top, bottom, left, right, or combinations
titlestring-Custom title
show_titlebooltrueShow title in border
buffer_sizeinteger1000Lines to keep (text windows)
background_colorstring-Background color
text_colorstring-Default text color
transparent_backgroundboolfalseSee-through background

Size Constraints

[[windows]]
name = "compass"
widget_type = "compass"
min_rows = 3
max_rows = 5
min_cols = 7
max_cols = 15

Widget-Specific Properties

Text Windows

[[windows]]
name = "main"
widget_type = "text"
streams = ["main"]              # Streams to display
buffer_size = 10000
compact = false                 # Remove blank lines

Tabbed Text

[[windows]]
name = "channels"
widget_type = "tabbedtext"
buffer_size = 5000

[[windows.tabs]]
name = "Speech"
streams = ["speech"]
show_timestamps = true

[[windows.tabs]]
name = "Thoughts"
streams = ["thoughts"]

Progress Bars

[[windows]]
name = "health"
widget_type = "progress"
stat = "health"                 # health, mana, stamina, spirit, encumbrance
bar_color = "#00FF00"
show_percentage = true

Countdowns

[[windows]]
name = "roundtime"
widget_type = "countdown"
id = "roundtime"                # roundtime, casttime, stuntime

Room Window

[[windows]]
name = "room"
widget_type = "room"
show_desc = true
show_objs = true
show_players = true
show_exits = true
show_name = true

Example Layout

terminal_width = 160
terminal_height = 50

# Main game text - left side
[[windows]]
name = "main"
widget_type = "text"
streams = ["main"]
row = 0
col = 0
rows = 45
cols = 100
buffer_size = 10000

# Channels - right side
[[windows]]
name = "channels"
widget_type = "tabbedtext"
row = 0
col = 100
rows = 30
cols = 60
buffer_size = 2000

[[windows.tabs]]
name = "Speech"
streams = ["speech"]

[[windows.tabs]]
name = "Thoughts"
streams = ["thoughts"]

# Status bars
[[windows]]
name = "health"
widget_type = "progress"
stat = "health"
row = 30
col = 100
rows = 1
cols = 60

# Command input - bottom
[[windows]]
name = "command_input"
widget_type = "command_input"
row = 47
col = 0
rows = 3
cols = 160

Hidden Windows

Set visible = false to define windows that can be shown later via the menu:

[[windows]]
name = "society"
widget_type = "text"
streams = ["society"]
visible = false
# ... position and size still required

Show via: Menu → Windows → Add Window → Text Windows → Society

keybinds.toml

Keyboard shortcuts for client actions and game commands.

Basic Format

[keybinds]
"ctrl+s" = "save_layout"
"f1" = "menu"
"ctrl+c" = "copy"
"numpad1" = { command = "go southwest" }

Key Names

Modifiers

Combine with +: ctrl+shift+a, alt+f1

ModifierName
Controlctrl
Altalt
Shiftshift

Special Keys

KeyName
Function keysf1 through f12
Arrow keysup, down, left, right
Navigationhome, end, pageup, pagedown
Editinginsert, delete, backspace
Otherenter, tab, escape, space
Numpadnumpad0-numpad9, numpad_add, numpad_subtract, etc.

Action Types

Client Actions

"f1" = "menu"                   # Open main menu
"ctrl+c" = "copy"               # Copy selection
"pageup" = "scroll_up"          # Scroll focused window
"pagedown" = "scroll_down"
"ctrl+home" = "scroll_top"
"ctrl+end" = "scroll_bottom"
"ctrl+s" = "save_layout"
"ctrl+tab" = "focus_next"       # Cycle window focus
"escape" = "cancel"             # Close menu/cancel

Game Commands

"numpad1" = { command = "go southwest" }
"numpad5" = { command = "look" }
"f2" = { command = "stance defensive" }

Macros (Multiple Commands)

"ctrl+h" = { macro = "hide\npause 2\nstalk" }

Common Keybinds

[keybinds]
# Navigation
"numpad1" = { command = "go southwest" }
"numpad2" = { command = "go south" }
"numpad3" = { command = "go southeast" }
"numpad4" = { command = "go west" }
"numpad5" = { command = "look" }
"numpad6" = { command = "go east" }
"numpad7" = { command = "go northwest" }
"numpad8" = { command = "go north" }
"numpad9" = { command = "go northeast" }
"numpad_add" = { command = "go out" }
"numpad_subtract" = { command = "go up" }
"numpad_multiply" = { command = "go down" }

# Client
"f1" = "menu"
"ctrl+c" = "copy"
"ctrl+s" = "save_layout"
"pageup" = "scroll_up"
"pagedown" = "scroll_down"
"escape" = "cancel"

# Search
"ctrl+f" = "search"
"ctrl+pageup" = "prev_search_match"
"ctrl+pagedown" = "next_search_match"

Available Actions

ActionDescription
menuOpen main menu
copyCopy selected text
scroll_up / scroll_downScroll focused window
scroll_top / scroll_bottomJump to top/bottom
focus_next / focus_prevCycle window focus
save_layoutSave current layout
cancelClose menu or cancel operation
searchOpen search in focused window
prev_search_match / next_search_matchCycle search results

highlights.toml

Text highlighting rules for coloring, sounds, and redirects.

Basic Format

[[highlights]]
name = "my_highlight"
pattern = "pattern to match"
foreground = "#FF0000"

Pattern Matching

Literal Match (Fast)

[[highlights]]
name = "death_cry"
pattern = "death cry"           # Exact text match
foreground = "#FF0000"

Regex Match

[[highlights]]
name = "creature_attack"
pattern = "^A .+ (swings|claws|lunges)"
is_regex = true
foreground = "#FFA500"

Styling Options

[[highlights]]
name = "whisper"
pattern = "whispers,"
foreground = "#9370DB"          # Text color
background = "#1a1a2e"          # Background color
bold = true
italic = true
underline = true

Colors

Use hex colors (#RRGGBB) or named colors:

  • Basic: red, green, blue, yellow, cyan, magenta, white, black
  • Extended: gray, orange, purple, pink, brown

Sound Alerts

[[highlights]]
name = "dead"
pattern = "appears dead"
foreground = "#00FF00"
sound = "ding.wav"              # File in ~/.vellum-fe/sounds/
sound_volume = 0.8              # 0.0 to 1.0

Text Replacement

[[highlights]]
name = "shorten_deaths"
pattern = "The death cry of"
replace = "†"
foreground = "#FF0000"

Stream Redirect

Route matching lines to another window:

[[highlights]]
name = "loot_to_window"
pattern = "^You gather"
redirect = "loot"               # Window name

Full Example

# Creature deaths
[[highlights]]
name = "creature_dead"
pattern = "appears dead"
foreground = "#00FF00"
bold = true
sound = "kill.wav"

# Player speech
[[highlights]]
name = "says"
pattern = ' (says|asks|exclaims),'
is_regex = true
foreground = "#87CEEB"

# Whispers (with background)
[[highlights]]
name = "whisper"
pattern = "whispers,"
foreground = "#DDA0DD"
background = "#2a1a2a"
italic = true

# Stun warning
[[highlights]]
name = "stunned"
pattern = "You are stunned"
foreground = "#FF4500"
bold = true
sound = "alert.wav"

# Treasure (redirect to loot window)
[[highlights]]
name = "loot"
pattern = "^(You gather|You search)"
is_regex = true
foreground = "#FFD700"
redirect = "loot"

Priority

Highlights are applied in order. Later patterns can override earlier ones.

Disabling

Disable without deleting via config.toml:

[highlights]
sounds_enabled = false          # Disable all sounds
coloring_enabled = false        # Disable all coloring

colors.toml

Custom color palette definitions.

Basic Format

[colors]
my_red = "#FF0000"
soft_blue = "#5588AA"
dark_bg = "#1a1a1a"

Using Custom Colors

Reference in other config files:

# In highlights.toml
[[highlights]]
name = "danger"
pattern = "attacks you"
foreground = "my_red"           # Uses color from colors.toml

# In layout.toml
[[windows]]
name = "combat"
border_color = "soft_blue"
background_color = "dark_bg"

Preset Colors

VellumFE recognizes these named colors without definition:

NameHex
black#000000
red#FF0000
green#00FF00
yellow#FFFF00
blue#0000FF
magenta#FF00FF
cyan#00FFFF
white#FFFFFF
gray / grey#808080
orange#FFA500
purple#800080
pink#FFC0CB

Example Palette

[colors]
# UI colors
border_normal = "#404040"
border_focused = "#5588AA"
border_alert = "#FF4040"

# Text colors
text_normal = "#CCCCCC"
text_dim = "#666666"
text_bright = "#FFFFFF"

# Creature states
dead = "#00FF00"
stunned = "#FFFF00"
frozen = "#00FFFF"

# Communication
speech = "#87CEEB"
whisper = "#DDA0DD"
thoughts = "#9370DB"

# Combat
damage_minor = "#FFFF00"
damage_major = "#FFA500"
damage_critical = "#FF0000"

Color Formats

All colors must be specified as hex:

# Supported formats
color1 = "#RGB"                 # 3-digit (expanded to 6)
color2 = "#RRGGBB"              # 6-digit (most common)

# Not supported
color3 = "rgb(255, 0, 0)"       # CSS format - won't work
color4 = "255, 0, 0"            # Raw values - won't work

Widgets

Widgets are the visual building blocks of your layout. Each widget type displays specific game information.

Widget Types

TypePurpose
textScrollable game text
tabbedtextMultiple streams in tabs
progressHealth, mana, stamina bars
countdownRoundtime, cast time timers
compassAvailable exits
handItems in hands
indicatorStatus conditions
dashboardMulti-indicator panel
roomRoom name, description, exits
injury_dollBody part injuries
active_effectsBuffs and debuffs
targetsCreatures in room
playersPlayers in room
itemsItems on ground
inventoryCarried items
spellsKnown spells
containerContainer contents

Common Properties

All widgets share these properties:

[[windows]]
name = "my_widget"              # Unique identifier
widget_type = "text"            # Widget type
row = 0                         # Top position
col = 0                         # Left position
rows = 10                       # Height
cols = 40                       # Width
visible = true                  # Show/hide
show_border = true
border_style = "single"         # single, double, rounded, thick
border_color = "#808080"
title = "Custom Title"

Adding Widgets

  1. Via Menu: F1 → Windows → Add Window → [Category] → [Widget]
  2. Via Command: .addwindow widgetname
  3. Via Config: Edit layout.toml directly

Categories

Widgets are organized into categories in the Add Window menu:

CategoryWidgets
Text Windowstext, tabbedtext
Statusprogress, countdown, hand, indicator, dashboard
Navigationcompass, room
Entitytargets, players, items
Listsinventory, spells, container
Otherinjury_doll, active_effects

Text Windows

Scrollable text display for game output.

Basic Usage

[[windows]]
name = "main"
widget_type = "text"
streams = ["main"]
row = 0
col = 0
rows = 30
cols = 80
buffer_size = 10000

Properties

PropertyTypeDefaultDescription
streamsarray[]Stream IDs to display
buffer_sizeinteger1000Lines to keep in memory
compactboolfalseRemove blank lines
show_timestampsboolfalsePrefix lines with time
timestamp_positionstring"end""start" or "end"

Common Streams

StreamContent
mainPrimary game output
speechPlayer dialogue
thoughtsESP/telepathy
combatCombat messages
deathDeath messages
familiarFamiliar messages
groupGroup information
logonsLogin/logout
societySociety messages
bountyBounty information

Examples

Main Window

[[windows]]
name = "main"
widget_type = "text"
streams = ["main"]
buffer_size = 10000

Speech Window

[[windows]]
name = "speech"
widget_type = "text"
streams = ["speech"]
buffer_size = 2000
show_timestamps = true
timestamp_position = "start"

Combat Log (Compact)

[[windows]]
name = "combat"
widget_type = "text"
streams = ["combat"]
buffer_size = 500
compact = true

Scrolling

  • Page Up / Page Down - Scroll when focused
  • Mouse wheel - Scroll under cursor
  • Home / End - Jump to top/bottom
  • Auto-scrolls when new text arrives (unless scrolled back)

Tabbed Text Windows

Multiple text streams organized into switchable tabs.

Basic Usage

[[windows]]
name = "channels"
widget_type = "tabbedtext"
row = 0
col = 80
rows = 20
cols = 40
buffer_size = 2000

[[windows.tabs]]
name = "Speech"
streams = ["speech"]

[[windows.tabs]]
name = "Thoughts"
streams = ["thoughts"]

[[windows.tabs]]
name = "Combat"
streams = ["combat"]

Properties

PropertyTypeDefaultDescription
buffer_sizeinteger5000Lines per tab

Tab Properties

PropertyTypeDefaultDescription
namestringrequiredTab label
streamsarrayrequiredStream IDs for this tab
show_timestampsboolfalseShow timestamps
timestamp_positionstring"end""start" or "end"
ignore_activityboolfalseDon’t highlight on new content

Tab Switching

  • Click tab name to switch
  • Activity indicator shows which tabs have new content

Example: Communication Hub

[[windows]]
name = "comms"
widget_type = "tabbedtext"
row = 0
col = 100
rows = 25
cols = 60
buffer_size = 3000

[[windows.tabs]]
name = "Speech"
streams = ["speech"]
show_timestamps = true

[[windows.tabs]]
name = "Thoughts"
streams = ["thoughts"]
show_timestamps = true

[[windows.tabs]]
name = "Whispers"
streams = ["whisper"]
show_timestamps = true

[[windows.tabs]]
name = "Group"
streams = ["group"]
ignore_activity = true

Example: Game Activity

[[windows]]
name = "activity"
widget_type = "tabbedtext"
buffer_size = 1000

[[windows.tabs]]
name = "Combat"
streams = ["combat"]

[[windows.tabs]]
name = "Deaths"
streams = ["death"]

[[windows.tabs]]
name = "Arrivals"
streams = ["logons"]
ignore_activity = true

Progress Bars

Display character vitals as visual bars.

Basic Usage

[[windows]]
name = "health"
widget_type = "progress"
stat = "health"
row = 0
col = 0
rows = 1
cols = 20

Properties

PropertyTypeDefaultDescription
statstringrequiredStat to display
bar_colorstringautoBar fill color
show_percentagebooltrueShow % value
show_labelbooltrueShow stat name

Available Stats

StatDescription
healthHit points
manaMana points
staminaStamina points
spiritSpirit points
encumbranceCarry weight
mindMental state (DR)
concentrationConcentration (DR)

Examples

Minimal Health Bar

[[windows]]
name = "health"
widget_type = "progress"
stat = "health"
rows = 1
cols = 15
show_label = false

Colored Mana Bar

[[windows]]
name = "mana"
widget_type = "progress"
stat = "mana"
bar_color = "#4169E1"
rows = 1
cols = 20

Stacked Vitals

[[windows]]
name = "health"
widget_type = "progress"
stat = "health"
row = 0
col = 0
rows = 1
cols = 25
bar_color = "#FF4040"

[[windows]]
name = "mana"
widget_type = "progress"
stat = "mana"
row = 1
col = 0
rows = 1
cols = 25
bar_color = "#4169E1"

[[windows]]
name = "stamina"
widget_type = "progress"
stat = "stamina"
row = 2
col = 0
rows = 1
cols = 25
bar_color = "#32CD32"

Color Behavior

Without bar_color, bars change color based on value:

  • Green (high) → Yellow (medium) → Red (low)

Countdowns

Display roundtime, cast time, and stun timers.

Basic Usage

[[windows]]
name = "roundtime"
widget_type = "countdown"
id = "roundtime"
row = 0
col = 0
rows = 1
cols = 15

Properties

PropertyTypeDefaultDescription
idstringrequiredTimer type
labelstringautoCustom label
bar_colorstringautoBar color

Timer Types

IDDescription
roundtimeAction roundtime (RT)
casttimeSpell cast time (CT)
stuntimeStun duration

Examples

Roundtime Bar

[[windows]]
name = "rt"
widget_type = "countdown"
id = "roundtime"
rows = 1
cols = 20
bar_color = "#FFD700"

Cast Time

[[windows]]
name = "ct"
widget_type = "countdown"
id = "casttime"
rows = 1
cols = 15
bar_color = "#9370DB"

Stun Timer

[[windows]]
name = "stun"
widget_type = "countdown"
id = "stuntime"
rows = 1
cols = 15
bar_color = "#FF4500"

Display

  • Shows remaining seconds with visual bar
  • Bar depletes as time passes
  • Empty/hidden when not active

Compass

Displays available room exits with directional arrows.

Basic Usage

[[windows]]
name = "compass"
widget_type = "compass"
row = 0
col = 0
rows = 3
cols = 7

Properties

PropertyTypeDefaultDescription
stylestring"arrows"Display style

Size Requirements

  • Minimum: 3 rows × 7 columns
  • Recommended: 3×7 or 5×9

Display

  N
W ◆ E
  S
  • Available exits shown with arrows
  • Unavailable directions dimmed
  • Supports all 10 directions: N, S, E, W, NE, NW, SE, SW, Up, Down, Out

Example

[[windows]]
name = "compass"
widget_type = "compass"
row = 0
col = 0
rows = 3
cols = 7
show_border = true
border_style = "rounded"

Hands

Display items held in left and right hands.

Basic Usage

[[windows]]
name = "right_hand"
widget_type = "hand"
hand = "right"
row = 0
col = 0
rows = 1
cols = 25

Properties

PropertyTypeDefaultDescription
handstringrequired"left" or "right"

Examples

Right Hand

[[windows]]
name = "right"
widget_type = "hand"
hand = "right"
rows = 1
cols = 30
title = "R:"

Left Hand

[[windows]]
name = "left"
widget_type = "hand"
hand = "left"
rows = 1
cols = 30
title = "L:"

Side by Side

[[windows]]
name = "right_hand"
widget_type = "hand"
hand = "right"
row = 0
col = 0
rows = 1
cols = 25
show_border = false
title = "R:"

[[windows]]
name = "left_hand"
widget_type = "hand"
hand = "left"
row = 0
col = 25
rows = 1
cols = 25
show_border = false
title = "L:"

Interaction

  • Click item name to interact
  • Right-click for context menu
  • Shows “Empty” when nothing held

Status Indicators

Display character status conditions (kneeling, hidden, webbed, etc).

Basic Usage

[[windows]]
name = "status"
widget_type = "indicator"
id = "kneeling"
row = 0
col = 0
rows = 1
cols = 3

Properties

PropertyTypeDefaultDescription
idstringrequiredStatus to track
active_colorstringautoColor when active
inactive_colorstring"gray"Color when inactive

Available Statuses

IDDescription
kneelingKneeling position
sittingSitting position
proneLying down
stunnedStunned
webbedWebbed
hiddenHidden
invisibleInvisible
deadDead
bleedingBleeding
poisonedPoisoned
diseasedDiseased

Examples

Single Indicator

[[windows]]
name = "hidden_indicator"
widget_type = "indicator"
id = "hidden"
rows = 1
cols = 3
active_color = "#00FF00"

Status Row

[[windows]]
name = "kneel"
widget_type = "indicator"
id = "kneeling"
row = 0
col = 0
rows = 1
cols = 3

[[windows]]
name = "hide"
widget_type = "indicator"
id = "hidden"
row = 0
col = 3
rows = 1
cols = 3

[[windows]]
name = "stun"
widget_type = "indicator"
id = "stunned"
row = 0
col = 6
rows = 1
cols = 3

Display

  • Shows abbreviated status code (3 chars)
  • Active: colored, Inactive: dimmed
  • Example: KNE (kneeling), HID (hidden)

Dashboard

Configurable grid of status indicators in a single widget.

Basic Usage

[[windows]]
name = "dashboard"
widget_type = "dashboard"
row = 0
col = 0
rows = 2
cols = 12

Properties

PropertyTypeDefaultDescription
indicatorsarrayallWhich indicators to show
columnsintegerautoGrid columns

Display

Shows multiple status indicators in a compact grid:

┌──────────┐
│KNE SIT HID│
│STU WEB BLE│
└──────────┘
  • Active indicators are highlighted
  • Inactive indicators are dimmed

Custom Indicators

[[windows]]
name = "dashboard"
widget_type = "dashboard"
indicators = ["kneeling", "hidden", "stunned", "webbed"]
columns = 2

Available Indicators

  • kneeling, sitting, prone
  • stunned, webbed, hidden
  • invisible, dead
  • bleeding, poisoned, diseased

Example: Combat Dashboard

[[windows]]
name = "combat_status"
widget_type = "dashboard"
row = 0
col = 0
rows = 2
cols = 15
indicators = ["stunned", "webbed", "prone", "bleeding"]
columns = 2
show_border = true
title = "Status"

Room Window

Displays current room information: name, description, objects, players, and exits.

Basic Usage

[[windows]]
name = "room"
widget_type = "room"
row = 0
col = 0
rows = 10
cols = 50

Properties

PropertyTypeDefaultDescription
show_namebooltrueShow room name
show_descbooltrueShow description
show_objsbooltrueShow objects/creatures
show_playersbooltrueShow other players
show_exitsbooltrueShow obvious exits

Examples

Full Room Display

[[windows]]
name = "room"
widget_type = "room"
rows = 12
cols = 60
show_name = true
show_desc = true
show_objs = true
show_players = true
show_exits = true

Compact (Name + Exits Only)

[[windows]]
name = "room"
widget_type = "room"
rows = 3
cols = 40
show_name = true
show_desc = false
show_objs = false
show_players = false
show_exits = true

Description Only

[[windows]]
name = "room"
widget_type = "room"
rows = 8
cols = 50
show_name = true
show_desc = true
show_objs = false
show_players = false
show_exits = false

Display

┌─ Town Square ─────────────────────────┐
│ The center of town bustles with       │
│ activity. A large fountain dominates  │
│ the square.                           │
│                                       │
│ You also see a town guard.            │
│ Also here: Adventurer, Merchant       │
│ Obvious exits: north, east, south     │
└───────────────────────────────────────┘

Interaction

  • Click creature/player names to interact
  • Right-click for context menu

Injury Display

Shows body part injuries as a visual “paper doll”.

Basic Usage

[[windows]]
name = "injuries"
widget_type = "injury_doll"
row = 0
col = 0
rows = 10
cols = 15

Display

    [Head]
[L.Arm][Chest][R.Arm]
   [L.Leg][R.Leg]
  • Each body part changes color based on injury severity
  • Green (healthy) → Yellow (minor) → Orange (moderate) → Red (severe)

Size Requirements

  • Minimum: 8 rows × 12 columns
  • Recommended: 10×15

Example

[[windows]]
name = "injuries"
widget_type = "injury_doll"
row = 0
col = 0
rows = 10
cols = 15
show_border = true
border_style = "rounded"
title = "Injuries"

Body Parts Tracked

  • Head, Neck
  • Chest, Abdomen, Back
  • Left/Right Arm
  • Left/Right Hand
  • Left/Right Leg
  • Left/Right Eye

Active Effects

Displays active spells, buffs, debuffs, and cooldowns.

Basic Usage

[[windows]]
name = "effects"
widget_type = "active_effects"
row = 0
col = 0
rows = 10
cols = 30

Properties

PropertyTypeDefaultDescription
categorystring"all"Filter by type

Categories

CategoryContent
allEverything
spellActive spells
buffBeneficial effects
debuffHarmful effects
cooldownAbility cooldowns

Display

Shows effect name with remaining duration:

┌─ Active Effects ──────┐
│ Spirit Shield   12:34 │
│ Haste            3:45 │
│ Bless            8:20 │
└───────────────────────┘

Example

[[windows]]
name = "buffs"
widget_type = "active_effects"
category = "spell"
rows = 8
cols = 25
show_border = true
title = "Spells"

Targets

Lists creatures in the current room with status indicators.

Basic Usage

[[windows]]
name = "targets"
widget_type = "targets"
row = 0
col = 0
rows = 10
cols = 35

Display

┌─ Targets [03] ────────────┐
│ > a mud hog [stunned]     │
│   a mud hog               │
│   a large rat [dead]      │
└───────────────────────────┘
  • > marks your current target
  • Status shown in brackets
  • Count in title

Configuration

Configure via config.toml:

[target_list]
status_position = "end"         # "end" or "start"
truncation_mode = "noun"        # "full" or "noun"
excluded_nouns = ["arm", "coal"]

[target_list.status_abbrev]
stunned = "stu"
frozen = "frz"
dead = "ded"

Interaction

  • Click creature to target
  • Right-click for context menu
  • Drag to inventory to loot

Example

[[windows]]
name = "targets"
widget_type = "targets"
row = 0
col = 100
rows = 12
cols = 30
show_border = true
border_color = "#AA4444"
title = "Enemies"

Players

Lists other players in the current room.

Basic Usage

[[windows]]
name = "players"
widget_type = "players"
row = 0
col = 0
rows = 8
cols = 25

Display

┌─ Players [02] ──────┐
│ Adventurer          │
│ Merchant (sitting)  │
└─────────────────────┘
  • Shows player names
  • Status in parentheses (sitting, kneeling, etc.)
  • Count in title

Interaction

  • Click player name to interact
  • Right-click for context menu

Example

[[windows]]
name = "players"
widget_type = "players"
row = 0
col = 100
rows = 8
cols = 25
show_border = true
title = "Also Here"

Items

Lists non-creature objects on the ground (dropped items, loot, furniture).

Basic Usage

[[windows]]
name = "items"
widget_type = "items"
row = 0
col = 0
rows = 10
cols = 30

Display

┌─ Items [04] ──────────────┐
│ a silver ring             │
│ some gold coins           │
│ a wooden chest            │
│ a torn scroll             │
└───────────────────────────┘
  • Shows item names from room
  • Count in title
  • Updates when room changes or items are dropped/picked up

Interaction

  • Click item to interact (look, get)
  • Right-click for context menu
  • Drag to inventory to pick up

Example

[[windows]]
name = "loot"
widget_type = "items"
row = 20
col = 100
rows = 8
cols = 30
show_border = true
title = "Ground"

Note

Items widget shows objects from the room description that are NOT creatures. Creatures appear in the Targets widget instead.

Inventory

Displays items carried on your character.

Basic Usage

[[windows]]
name = "inventory"
widget_type = "inventory"
row = 0
col = 0
rows = 15
cols = 35

Display

Shows items from the inv stream:

┌─ Inventory ────────────────┐
│ a leather backpack         │
│ a silver ring              │
│ some gold coins            │
│ a steel sword              │
└────────────────────────────┘

Interaction

  • Click item to interact
  • Right-click for context menu
  • Drag items to rearrange or drop

Example

[[windows]]
name = "inventory"
widget_type = "inventory"
row = 0
col = 100
rows = 20
cols = 40
show_border = true
title = "Carried Items"

Updating

Inventory updates when you:

  • Type inventory command
  • Pick up or drop items
  • Open/close containers

Spells

Displays known spells from the spell list.

Basic Usage

[[windows]]
name = "spells"
widget_type = "spells"
row = 0
col = 0
rows = 20
cols = 35

Display

Shows spells from the Spells stream:

┌─ Spells ───────────────────┐
│ Spirit Warding I (101)     │
│ Spirit Barrier (102)       │
│ Spirit Defense (103)       │
└────────────────────────────┘

Interaction

  • Click spell to prepare/cast
  • Right-click for context menu

Example

[[windows]]
name = "spells"
widget_type = "spells"
row = 0
col = 120
rows = 25
cols = 35
show_border = true
title = "Known Spells"

Note

Spell list is populated at login. Use spell command in-game to refresh.

Containers

Displays contents of open containers (bags, backpacks, chests).

Basic Usage

Container windows are created dynamically when you look in a container.

Enabling Containers

Enable container windows via command:

.containers

Or via menu: F1 → Config → Toggle Containers

Behavior

When enabled:

  1. Look in a container (look in backpack)
  2. A window appears showing contents
  3. Window closes when you close/leave the container

Display

┌─ leather backpack ─────────┐
│ a silver ring              │
│ some gold coins            │
│ a healing herb             │
└────────────────────────────┘

Interaction

  • Click items to interact
  • Right-click for context menu
  • Drag items to inventory or other containers

Manual Container Window

Create a persistent container window:

[[windows]]
name = "my_bag"
widget_type = "container"
container_title = "backpack"
row = 0
col = 100
rows = 10
cols = 30

The container_title must match the container name in-game.

Customization

Create your perfect interface with custom layouts, highlights, keybinds, and sounds.

Topics

Quick Start

Custom Layout

  1. Press F1 → Windows → Add Window
  2. Position and resize windows
  3. Press Ctrl+S to save

Add Highlights

Edit ~/.vellum-fe/highlights.toml:

[[highlights]]
name = "death"
pattern = "appears dead"
foreground = "#00FF00"
bold = true
sound = "kill.wav"

Custom Keybinds

Edit ~/.vellum-fe/keybinds.toml:

[keybinds]
"f2" = { command = "stance offensive" }
"f3" = { command = "stance defensive" }

Sound Alerts

  1. Place .wav files in ~/.vellum-fe/sounds/
  2. Reference in highlights:
[[highlights]]
name = "whisper"
pattern = "whispers to you"
sound = "whisper.wav"

Creating Layouts

Design custom window arrangements for different playstyles.

Using the Window Editor

  1. Press F1 → Windows → Edit Window → [window name]
  2. Modify position, size, and properties
  3. Save changes (applied immediately)

Or via command: .edit windowname

Adding Windows

Via Menu

F1 → Windows → Add Window → [Category] → [Widget]

Via Command

.addwindow targets
.addwindow text mywindow

Via Config

Edit ~/.vellum-fe/layout.toml:

[[windows]]
name = "mywindow"
widget_type = "text"
streams = ["main"]
row = 0
col = 0
rows = 20
cols = 60

Positioning

Grid Coordinates

row = 0       # Top edge (0 = top)
col = 0       # Left edge (0 = left)
rows = 20     # Height
cols = 60     # Width

Overlapping

Windows can overlap. Later windows in the file render on top.

Saving

  • Ctrl+S - Save current layout
  • F1 → Config → Save Layout - Same thing
  • Changes to window positions via drag are saved automatically

Example Layouts

Hunting Layout

terminal_width = 160
terminal_height = 50

# Main game text
[[windows]]
name = "main"
widget_type = "text"
streams = ["main"]
row = 0
col = 0
rows = 40
cols = 100

# Targets on right
[[windows]]
name = "targets"
widget_type = "targets"
row = 0
col = 100
rows = 15
cols = 30

# Items below targets
[[windows]]
name = "items"
widget_type = "items"
row = 15
col = 100
rows = 10
cols = 30

# Vitals
[[windows]]
name = "health"
widget_type = "progress"
stat = "health"
row = 25
col = 100
rows = 1
cols = 30

# Roundtime
[[windows]]
name = "rt"
widget_type = "countdown"
id = "roundtime"
row = 26
col = 100
rows = 1
cols = 30

# Command input
[[windows]]
name = "command_input"
widget_type = "command_input"
row = 47
col = 0
rows = 3
cols = 160

Minimal Layout

terminal_width = 80
terminal_height = 24

[[windows]]
name = "main"
widget_type = "text"
streams = ["main"]
row = 0
col = 0
rows = 21
cols = 80

[[windows]]
name = "command_input"
widget_type = "command_input"
row = 21
col = 0
rows = 3
cols = 80

Per-Character Layouts

Save layouts per character:

~/.vellum-fe/characters/CharName/layout.toml

Use --character NAME to load character-specific layout.

Highlight Patterns

Color and style game text based on patterns.

Basic Highlight

[[highlights]]
name = "player_speech"
pattern = " says,"
foreground = "#87CEEB"

Pattern Types

Literal (Default)

Fast exact matching:

pattern = "appears dead"

Regex

Flexible pattern matching:

pattern = "^A .+ attacks"
is_regex = true

Styling Options

[[highlights]]
name = "important"
pattern = "IMPORTANT"
foreground = "#FF0000"      # Text color
background = "#330000"      # Background color
bold = true
italic = true
underline = true

Sound Alerts

[[highlights]]
name = "whisper_alert"
pattern = "whispers to you"
foreground = "#DDA0DD"
sound = "whisper.wav"       # In ~/.vellum-fe/sounds/
sound_volume = 0.8          # 0.0 to 1.0

Text Replacement

[[highlights]]
name = "shorten"
pattern = "The death cry of"
replace = "†"
foreground = "#FF0000"

Stream Redirect

Route lines to another window:

[[highlights]]
name = "loot_redirect"
pattern = "^You gather"
is_regex = true
redirect = "loot"           # Window name

Common Patterns

# Combat
[[highlights]]
name = "creature_dead"
pattern = "appears dead"
foreground = "#00FF00"
bold = true
sound = "kill.wav"

[[highlights]]
name = "you_hit"
pattern = "^You .+ (swing|slash|thrust)"
is_regex = true
foreground = "#FFFF00"

[[highlights]]
name = "you_miss"
pattern = "^A clean miss"
foreground = "#808080"

# Communication
[[highlights]]
name = "says"
pattern = " says,"
foreground = "#87CEEB"

[[highlights]]
name = "whisper"
pattern = "whispers,"
foreground = "#DDA0DD"
italic = true

[[highlights]]
name = "thoughts"
pattern = "^You hear .+ thinking,"
is_regex = true
foreground = "#9370DB"

# Warnings
[[highlights]]
name = "stunned"
pattern = "You are stunned"
foreground = "#FF4500"
bold = true
sound = "alert.wav"

[[highlights]]
name = "bleeding"
pattern = "Blood runs down"
foreground = "#FF0000"
sound = "danger.wav"

Disabling Highlights

In config.toml:

[highlights]
sounds_enabled = false      # Disable sounds
coloring_enabled = false    # Disable colors
replace_enabled = false     # Disable replacements

Keybind Actions

Customize keyboard shortcuts for commands and actions.

Basic Keybind

[keybinds]
"f2" = { command = "stance offensive" }

Key Format

modifier+key

Modifiers

  • ctrl - Control key
  • alt - Alt key
  • shift - Shift key

Combine: ctrl+shift+a

Key Names

KeysNames
Lettersa through z
Numbers0 through 9
Functionf1 through f12
Arrowsup, down, left, right
Navigationhome, end, pageup, pagedown
Numpadnumpad0-numpad9, numpad_add, etc.
Otherenter, tab, escape, space, backspace

Action Types

Game Commands

"f2" = { command = "stance offensive" }
"numpad5" = { command = "look" }

Macros (Multiple Commands)

"ctrl+h" = { macro = "hide\npause 2\nstalk" }

Client Actions

"f1" = "menu"
"ctrl+c" = "copy"
"pageup" = "scroll_up"

Available Actions

ActionDescription
menuOpen main menu
copyCopy selection
scroll_upScroll focused window up
scroll_downScroll focused window down
scroll_topJump to top
scroll_bottomJump to bottom
focus_nextFocus next window
focus_prevFocus previous window
save_layoutSave current layout
cancelClose menu/cancel
searchSearch in window

Example Configuration

[keybinds]
# Navigation (numpad)
"numpad1" = { command = "go sw" }
"numpad2" = { command = "go s" }
"numpad3" = { command = "go se" }
"numpad4" = { command = "go w" }
"numpad5" = { command = "look" }
"numpad6" = { command = "go e" }
"numpad7" = { command = "go nw" }
"numpad8" = { command = "go n" }
"numpad9" = { command = "go ne" }
"numpad_add" = { command = "go out" }
"numpad_subtract" = { command = "go up" }
"numpad_multiply" = { command = "go down" }

# Combat stances
"f2" = { command = "stance offensive" }
"f3" = { command = "stance defensive" }
"f4" = { command = "stance guarded" }

# Quick actions
"f5" = { command = "look in my backpack" }
"f6" = { command = "inventory" }

# Macros
"ctrl+h" = { macro = "hide\npause 2\nstalk" }
"ctrl+l" = { macro = "search\npause 1\nloot" }

# Client
"f1" = "menu"
"ctrl+s" = "save_layout"
"ctrl+c" = "copy"
"escape" = "cancel"

Sound Alerts

Audio notifications for game events.

Setup

  1. Create sounds directory: ~/.vellum-fe/sounds/
  2. Add .wav files
  3. Reference in highlights

Using Sounds

In highlights.toml:

[[highlights]]
name = "death_alert"
pattern = "appears dead"
foreground = "#00FF00"
sound = "kill.wav"
sound_volume = 0.8

Sound Properties

PropertyTypeDefaultDescription
soundstring-Filename in sounds directory
sound_volumefloat1.0Volume (0.0 to 1.0)

Global Settings

In config.toml:

[sound]
enabled = true
volume = 0.7              # Master volume
cooldown_ms = 500         # Min time between sounds
startup_music = true      # Play music on launch

Disabling Sounds

All Sounds

[sound]
enabled = false

Highlight Sounds Only

[highlights]
sounds_enabled = false

Example Sounds Setup

Directory structure:

~/.vellum-fe/sounds/
├── kill.wav
├── alert.wav
├── whisper.wav
├── danger.wav
└── loot.wav

Highlights:

[[highlights]]
name = "kill"
pattern = "appears dead"
sound = "kill.wav"

[[highlights]]
name = "stunned"
pattern = "You are stunned"
sound = "alert.wav"
sound_volume = 1.0

[[highlights]]
name = "whisper"
pattern = "whispers to you"
sound = "whisper.wav"
sound_volume = 0.5

[[highlights]]
name = "bleeding"
pattern = "Blood runs down"
sound = "danger.wav"

Supported Formats

  • WAV (recommended)
  • MP3
  • OGG
  • FLAC

Troubleshooting

No sound playing?

  1. Check [sound] enabled = true in config.toml
  2. Check [highlights] sounds_enabled = true
  3. Verify file exists in sounds directory
  4. Check file format is supported
  5. Try increasing volume