Usage Guide
Detailed usage patterns and examples for Valheim Save Tools Python API.
Table of Contents
Basic Usage
Installation and Setup
from valheim_save_tools_py import ValheimSaveTools
# Basic initialization (auto-detects JAR and Java)
vst = ValheimSaveTools()
# With verbose output for debugging
vst = ValheimSaveTools(verbose=True)
# With custom paths
vst = ValheimSaveTools(
jar_path="/path/to/valheim-save-tools.jar",
java_path="/path/to/java"
)
Usage Patterns
The API supports three main usage patterns:
Pattern 1: Direct Method Calls
Simple, straightforward operations:
vst = ValheimSaveTools()
# File conversion - returns parsed data
data = vst.to_json("world.db")
print(f"Version: {data['version']}")
# Also save to file
data = vst.to_json("world.db", "backup.json")
vst.from_json("backup.json", "world_restored.db")
# Global keys
keys = vst.list_global_keys("world.db")
vst.add_global_key("world.db", "defeated_gdking")
vst.remove_global_key("world.db", "defeated_eikthyr")
vst.clear_all_global_keys("world.db")
# Structure operations
vst.clean_structures("world.db", threshold=25)
vst.reset_world("world.db")
When to use:
- Simple one-off operations
- Scripts with linear logic
- Quick file conversions
Pattern 2: Method Chaining (Builder Pattern)
Chain multiple operations elegantly:
vst = ValheimSaveTools()
# Process and save
result = (vst.process("world.db")
.clean_structures(threshold=30)
.reset_world()
.add_global_key("defeated_eikthyr")
.add_global_key("defeated_gdking")
.save("cleaned_world.db"))
# Process and export to JSON - returns data
data = (vst.process("world.db")
.clean_structures()
.reset_world()
.to_json("cleaned_world.json"))
print(f"Processed world has {len(data.get('globalKeys', []))} keys")
# Multiple operations, overwrite original
(vst.process("world.db")
.clean_structures(threshold=40)
.reset_world()
.save()) # No output = overwrite original
When to use:
- Multiple operations on same file
- Complex transformations
- When you need intermediate results
Pattern 3: Context Manager
Automatic cleanup and resource management:
vst = ValheimSaveTools()
# Automatically processes and saves to original file
with vst.process("world.db") as processor:
processor.clean_structures(threshold=30)
processor.reset_world()
processor.add_global_key("defeated_eikthyr")
# Temp files cleaned up automatically!
# Chaining also works in context manager
with vst.process("world.db") as processor:
processor.clean_structures() \
.reset_world() \
.add_global_key("defeated_gdking")
When to use:
- Guaranteed cleanup of temp files
- Exception-safe operations
- Pythonic resource management
- When modifying original file in-place
File Types
World Data Files (.db)
Contains actual world data including terrain, structures, items, etc.
# Convert to JSON for backup
vst.to_json("Dedicated.db", "world_backup.json")
# Clean structures
vst.clean_structures("Dedicated.db", threshold=30)
# Reset world
vst.reset_world("Dedicated.db")
# Manage global keys
vst.add_global_key("Dedicated.db", "defeated_eikthyr")
World Metadata Files (.fwl)
Contains world metadata (name, seed, etc.)
# Convert to JSON to inspect
vst.to_json("Dedicated.fwl", "metadata.json")
# Restore from JSON
vst.from_json("metadata.json", "Dedicated.fwl")
Character Files (.fch)
Contains character data (inventory, skills, etc.)
# Backup character
vst.to_json("MyCharacter.fch", "character_backup.json")
# Restore character
vst.from_json("character_backup.json", "MyCharacter.fch")
JSON Files
Human-readable converted format:
# Convert any save file to JSON
vst.to_json("world.db") # -> world.json
vst.to_json("world.fwl") # -> world.json
vst.to_json("character.fch") # -> character.json
# Convert back to binary
vst.from_json("world.json") # -> world.db
Item Parsing
Parse and analyze Valheim inventory and item data from base64-encoded binary format.
Basic Item Parsing
from valheim_save_tools_py import parse_items_from_base64
# Parse inventory data (typically from JSON save files)
base64_data = "AQAAAAIAAAAKQXhlQnJvbnpl..."
items = parse_items_from_base64(base64_data)
# Display all items
for i, item in enumerate(items, 1):
print(f"{i}. {item['name']}")
print(f" Stack: {item['stack']}")
print(f" Durability: {item['durability']:.1f}%")
print(f" Quality: {item['quality']}")
print(f" Position: ({item['pos_x']}, {item['pos_y']})")
if item['equipped']:
print(f" [EQUIPPED]")
if item['crafter_name']:
print(f" Crafted by: {item['crafter_name']}")
Extract Item Data from Save Files
from valheim_save_tools_py import ValheimSaveTools, parse_items_from_base64
vst = ValheimSaveTools()
# Convert character file to JSON
char_data = vst.to_json("MyCharacter.fch")
# Extract and parse inventory (if available in the JSON)
if 'inventory' in char_data:
inventory_b64 = char_data['inventory']
items = parse_items_from_base64(inventory_b64)
print(f"Character has {len(items)} items")
# List equipped gear
equipped = [item for item in items if item['equipped']]
print("\nEquipped items:")
for item in equipped:
print(f" - {item['name']} (Quality {item['quality']})")
Filter and Analyze Items
from valheim_save_tools_py import parse_items_from_base64
items = parse_items_from_base64(base64_data)
# Find all weapons
weapons = [item for item in items if any(
w in item['name'] for w in ['Sword', 'Axe', 'Bow', 'Spear', 'Mace']
)]
# Find damaged items
damaged = [item for item in items if item['durability'] < 50.0]
# Find high-quality items
high_quality = [item for item in items if item['quality'] >= 4]
# Calculate total weight (example - you'd need item weights)
stacks = sum(item['stack'] for item in items)
print(f"Total item stacks: {stacks}")
# Find items by crafter
player_crafted = [item for item in items if item['crafter_name'] == 'PlayerName']
Inventory Statistics
from valheim_save_tools_py import parse_items_from_base64
from collections import Counter
items = parse_items_from_base64(base64_data)
# Count item types
item_counts = Counter(item['name'] for item in items)
print("\nInventory breakdown:")
for item_name, count in item_counts.most_common():
print(f" {item_name}: {count}")
# Equipment analysis
equipped_count = sum(1 for item in items if item['equipped'])
total_durability = sum(item['durability'] for item in items if item['durability'] > 0)
avg_durability = total_durability / len([i for i in items if i['durability'] > 0])
print(f"\nStats:")
print(f" Total items: {len(items)}")
print(f" Equipped: {equipped_count}")
print(f" Average durability: {avg_durability:.1f}%")
# Quality distribution
quality_counts = Counter(item['quality'] for item in items)
print("\nQuality levels:")
for quality in sorted(quality_counts.keys()):
print(f" Level {quality}: {quality_counts[quality]} items")
Advanced: Custom Binary Parsing
For custom parsing needs, use the ValheimItemReader class directly:
from valheim_save_tools_py import ValheimItemReader
import base64
# Decode base64
binary_data = base64.b64decode(base64_string)
# Create reader
reader = ValheimItemReader(binary_data)
# Read header manually
version = reader.read_int32()
num_items = reader.read_int32()
print(f"Data version: {version}")
print(f"Item count: {num_items}")
# Read items with custom logic
items = []
for i in range(num_items):
try:
item = reader.read_item()
# Custom filtering during parsing
if item['quality'] >= 3: # Only high-quality items
items.append(item)
except Exception as e:
print(f"Error reading item {i}: {e}")
break
print(f"Found {len(items)} high-quality items")
Item Data Structure
Each parsed item contains:
{
'name': 'SwordIron', # Item ID/name
'stack': 1, # Quantity in stack
'durability': 75.5, # Current durability
'pos_x': 3, # Inventory X position
'pos_y': 1, # Inventory Y position
'equipped': True, # Is currently equipped
'quality': 2, # Quality/upgrade level
'variant': 0, # Item variant
'crafter_id': 987654321, # Crafter's player ID
'crafter_name': 'Warrior' # Crafter's name
}
Common Workflows
Workflow 1: Backup Before Modify
Always create backups before modifying save files:
vst = ValheimSaveTools()
# 1. Create backup
backup = vst.to_json("world.db", "world_backup.json")
print(f"Backup created: {backup}")
# 2. Modify the world
vst.clean_structures("world.db", threshold=30)
vst.reset_world("world.db")
# 3. If something goes wrong, restore:
# vst.from_json("world_backup.json", "world.db")
Workflow 2: Complete World Cleanup
Clean and reset world while preserving boss defeats:
vst = ValheimSaveTools()
# 1. Get current boss defeats
boss_keys = [k for k in vst.list_global_keys("world.db")
if k.startswith("defeated_")]
# 2. Clean and reset
with vst.process("world.db") as p:
p.clean_structures(threshold=30)
p.reset_world()
# 3. Restore boss defeats
for boss in boss_keys:
p.add_global_key(boss)
Workflow 3: Batch Process Multiple Worlds
from pathlib import Path
vst = ValheimSaveTools()
world_dir = Path("./worlds")
for db_file in world_dir.glob("*.db"):
print(f"Processing {db_file.name}...")
# Backup
vst.to_json(str(db_file), str(db_file.with_suffix('.json')))
# Clean
vst.clean_structures(str(db_file), threshold=25)
print(f"✓ {db_file.name} processed")
Workflow 4: Create World Variants
vst = ValheimSaveTools()
base_world = "world.db"
# Easy mode - all bosses defeated
(vst.process(base_world)
.reset_world()
.add_global_key("defeated_eikthyr")
.add_global_key("defeated_gdking")
.add_global_key("defeated_bonemass")
.save("world_easy.db"))
# Hard mode - no bosses defeated
(vst.process(base_world)
.reset_world()
.clear_all_global_keys()
.save("world_hard.db"))
Workflow 5: Migration Between Servers
vst = ValheimSaveTools()
# Export from source server
source = "server1_world.db"
vst.to_json(source, "world_transfer.json")
# Clean before transfer
(vst.process(source)
.clean_structures(threshold=50)
.to_json("world_transfer_cleaned.json"))
# Import to target server
target = "server2_world.db"
vst.from_json("world_transfer_cleaned.json", target)
Best Practices
1. Always Create Backups
# Good
vst.to_json("world.db", "backup.json")
vst.clean_structures("world.db")
# Even better - use context manager
backup = vst.to_json("world.db", "backup_before_cleanup.json")
with vst.process("world.db") as p:
p.clean_structures()
2. Validate Files Before Processing
from valheim_save_tools_py import ValheimSaveTools
# Validate before processing
if not ValheimSaveTools.is_db_file("world.db"):
print("Error: Not a valid .db file")
exit(1)
vst = ValheimSaveTools()
vst.clean_structures("world.db")
3. Use Context Managers for Safety
# Automatic cleanup even if errors occur
try:
with vst.process("world.db") as p:
p.clean_structures()
p.reset_world()
except Exception as e:
print(f"Error: {e}")
# Temp files still cleaned up!
4. Start with Conservative Thresholds
# Start conservative
vst.clean_structures("world.db", threshold=10)
# Gradually increase if needed
vst.clean_structures("world.db", threshold=25) # Recommended
vst.clean_structures("world.db", threshold=50) # Aggressive
5. Use Verbose Mode for Debugging
# Enable verbose output during development/debugging
vst = ValheimSaveTools(verbose=True)
vst.clean_structures("world.db")
# Disable for production
vst = ValheimSaveTools(verbose=False)
Tips and Tricks
Tip 1: Check Boss Status
vst = ValheimSaveTools()
keys = vst.list_global_keys("world.db")
bosses = {
"Eikthyr": "defeated_eikthyr",
"The Elder": "defeated_gdking",
"Bonemass": "defeated_bonemass",
"Moder": "defeated_dragon",
"Yagluth": "defeated_goblinking",
"The Queen": "defeated_queen"
}
print("Boss Status:")
for name, key in bosses.items():
status = "✓" if key in keys else "✗"
print(f"{status} {name}")
Tip 2: Conditional Processing
vst = ValheimSaveTools()
keys = vst.list_global_keys("world.db")
# Only clean if certain bosses defeated
if "defeated_dragon" in keys:
print("Late game - aggressive cleaning")
vst.clean_structures("world.db", threshold=50)
else:
print("Early game - conservative cleaning")
vst.clean_structures("world.db", threshold=10)
Tip 3: Progressive Backups
from datetime import datetime
vst = ValheimSaveTools()
# Create timestamped backup
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup = f"world_backup_{timestamp}.json"
vst.to_json("world.db", backup)
print(f"Backup created: {backup}")
Tip 4: Dry Run with JSON Export
# Export to JSON to inspect before modifying
vst.to_json("world.db", "world_inspect.json")
# Inspect the JSON file manually
# ... review changes needed ...
# Then modify original
vst.clean_structures("world.db")
Tip 5: Error Recovery
vst = ValheimSaveTools()
try:
# Create safety backup
backup = vst.to_json("world.db", "safety_backup.json")
# Risky operation
vst.reset_world("world.db")
except Exception as e:
print(f"Error occurred: {e}")
print("Restoring from backup...")
vst.from_json(backup, "world.db")
print("Restored successfully")
Troubleshooting
Issue: “JAR file not found”
# Solution: Specify JAR path explicitly
vst = ValheimSaveTools(jar_path="/path/to/valheim-save-tools.jar")
Issue: “Java not found”
# Solution: Specify Java path or install Java 17+
vst = ValheimSaveTools(java_path="/path/to/java")
Issue: File not modified
# Make sure you're using the right file type
# Global keys only work with .db files
if ValheimSaveTools.is_db_file("world.db"):
vst.add_global_key("world.db", "defeated_eikthyr")
Issue: Permission errors
Make sure:
- Files are not read-only
- You have write permissions
- Files are not in use by Valheim
- Backup files before modifying
See examples/ for complete working examples.