Minimal Layout
Create a clean, distraction-free interface with maximum text visibility.
Goal
Build a minimalist layout with:
- Maximum screen space for game text
- Essential information only
- Keyboard-centric design
- Low resource usage
- Quick load times
Prerequisites
- Basic Two-Face familiarity
- Preference for simple interfaces
- Keyboard navigation skills
Design Philosophy
The minimal layout follows these principles:
- Less is More - Only show what you actively need
- Text First - Game output takes priority
- Keyboard Driven - Reduce mouse dependency
- Performance - Fewer widgets = faster rendering
Layout Overview
┌────────────────────────────────────────────────────────────┐
│ │
│ │
│ │
│ Game Text │
│ (Full Screen) │
│ │
│ │
│ │
├────────────────────────────────────────────────────────────┤
│ HP: ████████░░ 82% MP: ████░░░░░░ 40% RT: 3 > [input] │
└────────────────────────────────────────────────────────────┘
Step 1: Create the Layout
Create ~/.two-face/layout.toml:
# Minimal Layout - Maximum Text, Minimum UI
# Clean, fast, keyboard-driven
# ═══════════════════════════════════════════════════════════
# MAIN TEXT - Full Width, Maximum Height
# ═══════════════════════════════════════════════════════════
[[widgets]]
type = "text"
name = "main"
title = ""
x = 0
y = 0
width = 100
height = 90
streams = ["main", "room", "combat", "thoughts", "speech"]
scrollback = 3000
auto_scroll = true
border = false
padding = 1
# ═══════════════════════════════════════════════════════════
# STATUS BAR - Compact Bottom Row
# ═══════════════════════════════════════════════════════════
# Health (compact)
[[widgets]]
type = "progress"
name = "health"
title = "HP"
x = 0
y = 91
width = 15
height = 3
data_source = "vitals.health"
color = "health"
show_percentage = true
border = false
# Mana (compact)
[[widgets]]
type = "progress"
name = "mana"
title = "MP"
x = 16
y = 91
width = 15
height = 3
data_source = "vitals.mana"
color = "mana"
show_percentage = true
border = false
# Roundtime (compact)
[[widgets]]
type = "countdown"
name = "roundtime"
title = "RT"
x = 32
y = 91
width = 8
height = 3
data_source = "roundtime"
border = false
# Command Input (rest of row)
[[widgets]]
type = "command_input"
name = "input"
x = 41
y = 91
width = 59
height = 9
history_size = 500
prompt = "> "
border = false
That’s it. Four widgets total.
Step 2: Minimal Theme
Create ~/.two-face/colors.toml:
[theme]
name = "Minimal"
# Clean, high-contrast colors
background = "#000000"
text = "#cccccc"
text_dim = "#666666"
# No visible borders
border = "#000000"
border_focused = "#333333"
# Vitals - visible but not distracting
health = "#00aa00"
health_low = "#aaaa00"
health_critical = "#aa0000"
mana = "#0066aa"
stamina = "#aa6600"
# Status bar background
status_bg = "#111111"
Step 3: Keyboard-Centric Keybinds
Create ~/.two-face/keybinds.toml:
# ═══════════════════════════════════════════════════════════
# CORE NAVIGATION - Always Available
# ═══════════════════════════════════════════════════════════
# Cardinal directions
[keybinds."numpad8"]
macro = "north"
[keybinds."numpad2"]
macro = "south"
[keybinds."numpad4"]
macro = "west"
[keybinds."numpad6"]
macro = "east"
# Diagonal
[keybinds."numpad7"]
macro = "northwest"
[keybinds."numpad9"]
macro = "northeast"
[keybinds."numpad1"]
macro = "southwest"
[keybinds."numpad3"]
macro = "southeast"
# Special movement
[keybinds."numpad5"]
macro = "out"
[keybinds."numpad_plus"]
macro = "go"
[keybinds."numpad_minus"]
macro = "climb"
# ═══════════════════════════════════════════════════════════
# ESSENTIAL COMMANDS - Function Keys
# ═══════════════════════════════════════════════════════════
[keybinds."f1"]
macro = "look"
[keybinds."f2"]
macro = "inventory"
[keybinds."f3"]
macro = "experience"
[keybinds."f4"]
macro = "health"
[keybinds."f5"]
macro = "stance defensive"
[keybinds."f6"]
macro = "stance offensive"
[keybinds."f7"]
macro = "hide"
[keybinds."f8"]
macro = "search"
# ═══════════════════════════════════════════════════════════
# QUICK ACTIONS - Ctrl Keys
# ═══════════════════════════════════════════════════════════
[keybinds."ctrl+a"]
macro = "attack target"
[keybinds."ctrl+s"]
macro = "search;loot"
[keybinds."ctrl+g"]
macro = "get $input"
[keybinds."ctrl+d"]
macro = "drop $input"
# ═══════════════════════════════════════════════════════════
# SCROLLING - Page Keys
# ═══════════════════════════════════════════════════════════
[keybinds."page_up"]
action = "scroll_up"
[keybinds."page_down"]
action = "scroll_down"
[keybinds."home"]
action = "scroll_top"
[keybinds."end"]
action = "scroll_bottom"
# Half-page scroll
[keybinds."ctrl+page_up"]
action = "scroll_half_up"
[keybinds."ctrl+page_down"]
action = "scroll_half_down"
# ═══════════════════════════════════════════════════════════
# FOCUS
# ═══════════════════════════════════════════════════════════
[keybinds."escape"]
action = "focus_input"
# Toggle between main and input (since only 2 widgets)
[keybinds."tab"]
action = "next_widget"
Step 4: Minimal Highlights
Create ~/.two-face/highlights.toml:
# Minimal highlighting - only essential patterns
# ═══════════════════════════════════════════════════════════
# CRITICAL ALERTS
# ═══════════════════════════════════════════════════════════
[[highlights]]
pattern = "(?i)you are stunned"
fg = "black"
bg = "yellow"
bold = true
[[highlights]]
pattern = "(?i)you have died"
fg = "black"
bg = "red"
bold = true
# ═══════════════════════════════════════════════════════════
# PLAYER INTERACTION
# ═══════════════════════════════════════════════════════════
# Whispers (important)
[[highlights]]
pattern = "(\\w+) whispers,"
fg = "magenta"
# Your name mentioned
[[highlights]]
pattern = "\\bYOURNAME\\b"
fg = "cyan"
bold = true
# ═══════════════════════════════════════════════════════════
# COMBAT (Subtle)
# ═══════════════════════════════════════════════════════════
# Hits
[[highlights]]
pattern = "\\*\\*.+\\*\\*"
fg = "red"
# Death
[[highlights]]
pattern = "falls dead"
fg = "yellow"
# ═══════════════════════════════════════════════════════════
# NAVIGATION AIDS
# ═══════════════════════════════════════════════════════════
# Room name
[[highlights]]
pattern = "^\\[.+\\]$"
fg = "white"
bold = true
# Exits
[[highlights]]
pattern = "Obvious (exits|paths):"
fg = "gray"
Step 5: No Triggers (Optional)
For truly minimal setup, skip triggers entirely. Or add only critical ones:
Create ~/.two-face/triggers.toml:
# Only life-saving triggers
[[triggers]]
name = "death_alert"
pattern = "You have died"
command = ".notify DEAD!"
priority = 100
[[triggers]]
name = "stun_alert"
pattern = "(?i)you are stunned"
command = ".notify Stunned"
priority = 100
cooldown = 2000
Alternative: Ultra-Minimal
For absolute minimalism, use just two widgets:
# Ultra-minimal - text and input only
[[widgets]]
type = "text"
name = "main"
x = 0
y = 0
width = 100
height = 92
streams = ["main", "room", "combat", "thoughts", "speech"]
scrollback = 2000
border = false
[[widgets]]
type = "command_input"
name = "input"
x = 0
y = 93
width = 100
height = 7
prompt = "> "
border = false
No status bars, no indicators. Pure text adventure.
Alternative: Vertical Split
If you want some separation without complexity:
# Two-column minimal
[[widgets]]
type = "text"
name = "main"
x = 0
y = 0
width = 70
height = 92
streams = ["main", "room", "combat"]
border = false
[[widgets]]
type = "text"
name = "chat"
x = 71
y = 0
width = 29
height = 92
streams = ["thoughts", "speech", "whisper"]
border_color = "gray"
[[widgets]]
type = "command_input"
name = "input"
x = 0
y = 93
width = 100
height = 7
prompt = "> "
border = false
Testing Your Setup
Performance Test
- Launch Two-Face
- Check startup time (should be fast)
- Scroll rapidly (should be smooth)
- Send many commands (no lag)
Functionality Test
- Text displays clearly
- Scrolling works (Page Up/Down)
- Commands execute
- Vital bars update
- RT countdown works
Keyboard-Only Test
Try a session without using the mouse:
- Navigate rooms with numpad
- Use F-keys for common commands
- Type commands directly
- Scroll with Page keys
Performance Tips
Reduce Scrollback
Less history = less memory:
scrollback = 1000 # Instead of 5000+
Disable Animations
If supported:
[performance]
animations = false
smooth_scroll = false
Simple Highlights
Complex regex patterns slow parsing:
# Fast (literal string)
pattern = "You are stunned"
# Slower (complex regex)
pattern = "(?i)you\\s+are\\s+(?:completely\\s+)?stunned"
Fewer Streams
Combining streams reduces processing:
# All in one (fastest)
streams = ["main"]
# Separated (more processing)
streams = ["main", "room", "combat", "thoughts"]
Customization
Adding Status on Demand
Create a keybind to show/hide status:
[keybinds."ctrl+h"]
action = "toggle_widget"
widget = "health"
Temporary Expansion
For complex situations, temporarily switch layouts:
.layout hunting # Switch to full layout
.layout minimal # Back to minimal
Color Adjustments
For different lighting conditions:
Day Mode (brighter):
background = "#1a1a1a"
text = "#e0e0e0"
Night Mode (darker):
background = "#000000"
text = "#909090"
Troubleshooting
Missing Information
If you need data not shown:
- Add minimal widget for that data
- Use keybind macros (F3 = experience)
- Create triggers for notifications
Accidental Scrollback
Enable auto-scroll:
auto_scroll = true
Or use End key to jump to bottom.
Can’t See Status
Check border settings - borders might be same color as background:
border = false # Hide borders entirely
Input Too Small
Increase input height:
height = 9 # More space for long commands
Philosophy
The minimal layout works best when you:
- Know the game well
- Prefer typing over clicking
- Want maximum text visibility
- Value performance over features
- Play on smaller screens or terminals
It doesn’t work well when you:
- Need constant visual status monitoring
- Rely heavily on context menus
- Are new to the game
- Want rich visual feedback
Choose the approach that matches your playstyle.
See Also
- Your First Layout - For more features
- Performance Optimization
- Creating Themes