Decode, inspect, edit, and export metrics from Valheim .fch character files.
Use it as a Go library, one-shot JSON dumper, character editor, or Prometheus
scrape target.
fchdump decodes one .fch file to formatted JSON.
fchedit validates and edits character data, writing changes in place or to a
copy.
fchprom serves Prometheus metrics from a Valheim character directory.
Go programs can import github.com/lanchelms/fch-decoder for structured
decode and encode behavior.
Install the library:
go get github.com/lanchelms/fch-decoderInstall the command-line tools:
go install github.com/lanchelms/fch-decoder/cmd/fchdump@latest
go install github.com/lanchelms/fch-decoder/cmd/fchedit@latest
go install github.com/lanchelms/fch-decoder/cmd/fchprom@latestPull the published images:
docker pull ghcr.io/lanchelms/fch-decoder-fchdump:latest
docker pull ghcr.io/lanchelms/fch-decoder-fchedit:latest
docker pull ghcr.io/lanchelms/fch-decoder-fchprom:latestOr run them directly:
docker run --rm -v "$PWD/testdata:/data:ro" \
ghcr.io/lanchelms/fch-decoder-fchdump:latest \
--character /data/Steam_222222_bortson.fchdocker run --rm -p 9108:9108 \
-v "$HOME/.config/unity3d/IronGate/Valheim/characters_local:/characters:ro" \
ghcr.io/lanchelms/fch-decoder-fchprom:latest \
--dir /characters --addr :9108The bundled docker-compose.yml is for fchprom. Configure it with
FCHPROM_CHARACTERS_DIR and FCHPROM_PORT.
fchdump requires --character or the CHARACTER environment variable and
writes formatted JSON to stdout.
fchdump --character testdata/Steam_222222_bortson.fchfchedit accepts these global flags:
--character STRING Character file to edit, also read from CHARACTER.
--out STRING Write to this path instead of updating the input file.
--dry-run Validate and summarize the edit without writing.
--no-backup Do not create a backup before editing in place.
Commands:
set skill <skill> <level>
set enemy <name> <value>
set material <name> <value>
set player-stat <stat> <value>
add inventory <item>
remove inventory <name>
list skills
list player-stats
list items
list inventory
Examples:
fchedit --character character.fch set skill Run 50
fchedit --character character.fch --dry-run add inventory 'Wood,stack=50,quality=1'
fchedit --character character.fch --out edited.fch set player-stat Deaths 0fchprom serves metrics from a Valheim characters_local directory.
Exported character metrics:
valheim_character_skills{player,skill}valheim_character_crafting{player,recipe}valheim_character_enemies{player,enemy}valheim_character_stats{player,stat}valheim_character_distance{player,mode}valheim_character{player,state}valheim_character_worlds{player,world}
--dir STRING Valheim characters_local directory.
--addr STRING Address to serve Prometheus metrics on. Default: :9108.
--metrics-path STRING Prometheus metrics path. Default: /metrics.
--workers INT Maximum files to decode in parallel. Default: 16.
--cache-ttl DURATION How long to reuse decoded metrics. Default: 5s.
Local example:
fchprom --dir "$HOME/.config/unity3d/IronGate/Valheim/characters_local" --addr :9108Compose example:
FCHPROM_CHARACTERS_DIR="$HOME/.config/unity3d/IronGate/Valheim/characters_local" \
FCHPROM_PORT=9108 \
docker compose up fchpromUse the Go package when you want structured character data inside your own application.
package main
import (
"fmt"
"os"
fch "github.com/lanchelms/fch-decoder"
)
func main() {
file, err := os.Open("character.fch")
if err != nil {
panic(err)
}
defer file.Close()
character, err := fch.Decode(file)
if err != nil {
panic(err)
}
fmt.Println(character.Player.Name)
}