Skip to main content

Usage Examples

This page demonstrates practical usage scenarios for the FG Character Extractor, from basic single-file extraction to advanced batch processing workflows.

Basic Usage

Extract from Current Directory

The simplest usage assumes db.xml is in your current directory:
# Navigate to your campaign directory
cd ~/Fantasy\ Grounds/campaigns/MyCampaign/

# Run extraction
fg-char-extract
Output:
2026/03/08 14:30:15 INFO Character extracted successfully filename=character_id-00001_5.xml
2026/03/08 14:30:15 INFO Character extracted successfully filename=character_id-00002_3.xml

Extract from Specific File

Specify the full path to any Fantasy Grounds database:
macOS/Linux
fg-char-extract ~/Fantasy\ Grounds/campaigns/LostMinesOfPhandelver/db.xml
Windows
fg-char-extract "C:\Users\YourName\AppData\Roaming\SmiteWorks\Fantasy Grounds\campaigns\LostMinesOfPhandelver\db.xml"
Use quotes around paths with spaces to ensure proper parsing.

Campaign Management

Backup All Characters

Create a backup directory for extracted characters:
# Create backup directory
mkdir -p ~/fg-backups/$(date +%Y-%m-%d)

# Extract to backup location
cd ~/fg-backups/$(date +%Y-%m-%d)
fg-char-extract ~/Fantasy\ Grounds/campaigns/MyCampaign/db.xml
This creates a timestamped backup:
~/fg-backups/
  └── 2026-03-08/
      ├── character_id-00001_5.xml
      ├── character_id-00002_3.xml
      └── character_id-00003_7.xml

Extract and Archive

Combine extraction with compression for long-term storage:
#!/bin/bash
# backup-campaign.sh

CAMPAIGN="MyCampaign"
BACKUP_DIR=~/fg-backups/$(date +%Y-%m-%d)-$CAMPAIGN
SOURCE="$HOME/Fantasy Grounds/campaigns/$CAMPAIGN/db.xml"

mkdir -p "$BACKUP_DIR"
cd "$BACKUP_DIR"

# Extract characters
fg-char-extract "$SOURCE"

# Create archive
tar -czf characters-$(date +%Y%m%d).tar.gz character_*.xml

# Optionally remove individual XML files
# rm character_*.xml

echo "Backup complete: $BACKUP_DIR"

Batch Processing

Process Multiple Campaigns

Extract characters from all campaigns:
#!/bin/bash
# extract-all-campaigns.sh

CAMPAIGNS_DIR=~/Fantasy\ Grounds/campaigns
OUTPUT_DIR=~/fg-extracts

for campaign in "$CAMPAIGNS_DIR"/*; do
  if [ -d "$campaign" ] && [ -f "$campaign/db.xml" ]; then
    campaign_name=$(basename "$campaign")
    echo "Processing: $campaign_name"
    
    mkdir -p "$OUTPUT_DIR/$campaign_name"
    cd "$OUTPUT_DIR/$campaign_name"
    
    fg-char-extract "$campaign/db.xml"
  fi
done

echo "All campaigns processed!"
Output structure:
~/fg-extracts/
  ├── LostMinesOfPhandelver/
  │   ├── character_id-00001_3.xml
  │   └── character_id-00002_3.xml
  ├── CurseOfStrahd/
  │   ├── character_id-00001_7.xml
  │   └── character_id-00002_6.xml
  └── StormKingsThunder/
      └── character_id-00001_9.xml

Automated Daily Backups

Set up a cron job for automatic daily backups:
crontab
# Run daily at 3 AM
0 3 * * * /home/yourusername/scripts/backup-campaign.sh >> /home/yourusername/fg-backups/backup.log 2>&1
Regular automated backups protect against data loss and make character recovery easier.

Character Analysis

Count Characters by Level

Use extracted files to analyze your campaign:
#!/bin/bash
# count-by-level.sh

for file in character_*.xml; do
  # Extract level from filename (format: character_id-xxxxx_LEVEL.xml)
  level=$(echo "$file" | sed 's/.*_\([0-9]*\)\.xml/\1/')
  echo "$level"
done | sort -n | uniq -c
Example output:
   2 3
   1 5
   3 7

Extract Character Names

Parse XML to list all character names:
#!/bin/bash
# list-characters.sh

for file in character_*.xml; do
  name=$(grep '<name type="string">' "$file" | sed 's/.*<name[^>]*>\([^<]*\)<.*/\1/')
  level=$(echo "$file" | sed 's/.*_\([0-9]*\)\.xml/\1/')
  echo "$name (Level $level)"
done | sort
Example output:
Gandalf (Level 5)
Aragorn (Level 7)
Legolas (Level 6)

Integration Examples

Git Version Control

Track character changes over time:
#!/bin/bash
# track-characters.sh

REPO_DIR=~/fg-character-tracking
CAMPAIGN="MyCampaign"

# Initialize repo if needed
if [ ! -d "$REPO_DIR/.git" ]; then
  mkdir -p "$REPO_DIR"
  cd "$REPO_DIR"
  git init
fi

cd "$REPO_DIR"

# Extract latest characters
fg-char-extract ~/Fantasy\ Grounds/campaigns/$CAMPAIGN/db.xml

# Commit changes
git add character_*.xml
git commit -m "Update: $(date +%Y-%m-%d)"

echo "Characters tracked in git"
This allows you to:
  • View character progression over time
  • Recover old character states
  • See what changed between sessions

Share Characters

Extract and share a single character with another DM:
#!/bin/bash
# share-character.sh

CHARACTER_ID="id-00001"
OUTPUT_DIR=~/shared-characters

mkdir -p "$OUTPUT_DIR"
cd "$OUTPUT_DIR"

# Extract all characters
fg-char-extract ~/Fantasy\ Grounds/campaigns/MyCampaign/db.xml

# Find the specific character
character_file=$(ls character_${CHARACTER_ID}_*.xml)

if [ -f "$character_file" ]; then
  echo "Character exported: $character_file"
  echo "Share this file with your DM"
else
  echo "Character $CHARACTER_ID not found"
fi

Troubleshooting Examples

Check for Corrupted Database

Validate your db.xml before extraction:
#!/bin/bash
# validate-db.sh

DB_FILE="$1"

if [ ! -f "$DB_FILE" ]; then
  echo "Error: File not found: $DB_FILE"
  exit 1
fi

# Check if it's valid XML
if xmllint --noout "$DB_FILE" 2>/dev/null; then
  echo "✓ Valid XML"
  
  # Try extraction
  fg-char-extract "$DB_FILE"
  
  if [ $? -eq 0 ]; then
    echo "✓ Extraction successful"
  else
    echo "✗ Extraction failed"
    exit 1
  fi
else
  echo "✗ Invalid XML - database may be corrupted"
  exit 1
fi

Verify Output Files

Ensure all extracted files are valid:
#!/bin/bash
# verify-output.sh

for file in character_*.xml; do
  if xmllint --noout "$file" 2>/dev/null; then
    echo "✓ $file is valid"
  else
    echo "✗ $file is invalid"
  fi
done

Advanced Usage

Custom Output Directory

Run extraction with output in a specific location:
#!/bin/bash
# extract-to-dir.sh

SOURCE="$1"
OUTPUT="$2"

if [ -z "$SOURCE" ] || [ -z "$OUTPUT" ]; then
  echo "Usage: $0 <source-db.xml> <output-directory>"
  exit 1
fi

mkdir -p "$OUTPUT"
cd "$OUTPUT"
fg-char-extract "$SOURCE"
Usage:
./extract-to-dir.sh ~/Fantasy\ Grounds/campaigns/MyCampaign/db.xml ~/exports/session-42

Filter by Level

Extract only high-level characters:
#!/bin/bash
# extract-high-level.sh

MIN_LEVEL=5

# Extract all
fg-char-extract ~/Fantasy\ Grounds/campaigns/MyCampaign/db.xml

# Move high-level characters to separate directory
mkdir -p high-level
for file in character_*.xml; do
  level=$(echo "$file" | sed 's/.*_\([0-9]*\)\.xml/\1/')
  if [ "$level" -ge "$MIN_LEVEL" ]; then
    mv "$file" high-level/
  else
    rm "$file"  # or move to another directory
  fi
done

Performance Tips

Large Database Handling

For very large campaigns with many characters:
# Monitor extraction progress
time fg-char-extract large-campaign.xml

# Example output:
# real    0m2.341s
# user    0m1.892s
# sys     0m0.234s
The tool is memory-efficient and uses streaming XML parsing, so it can handle large databases without loading everything into memory.

Parallel Processing

Process multiple campaigns simultaneously:
#!/bin/bash
# parallel-extract.sh

for campaign in ~/Fantasy\ Grounds/campaigns/*/db.xml; do
  campaign_name=$(basename $(dirname "$campaign"))
  (
    mkdir -p "output/$campaign_name"
    cd "output/$campaign_name"
    fg-char-extract "$campaign"
  ) &
done

wait
echo "All extractions complete!"

Next Steps

Command Reference

Review all command-line options

Output Format

Understand the extracted XML structure

Build docs developers (and LLMs) love