fch

package module
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 11 Imported by: 0

README

fch-decoder

fch-decoder

Go Reference Go Report Card Go Version Latest Release

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.

Tools

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.

Installation

Go

Install the library:

go get github.com/lanchelms/fch-decoder

Install 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@latest
Docker

Pull 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:latest

Or run them directly:

docker run --rm -v "$PWD/testdata:/data:ro" \
  ghcr.io/lanchelms/fch-decoder-fchdump:latest \
  --character /data/Steam_222222_bortson.fch
docker 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 :9108

The bundled docker-compose.yml is for fchprom. Configure it with FCHPROM_CHARACTERS_DIR and FCHPROM_PORT.

fchdump

fchdump requires --character or the CHARACTER environment variable and writes formatted JSON to stdout.

fchdump --character testdata/Steam_222222_bortson.fch

fchedit

fchedit 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 0

fchprom

fchprom serves metrics from a Valheim characters_local directory.

--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 :9108

Compose example:

FCHPROM_CHARACTERS_DIR="$HOME/.config/unity3d/IronGate/Valheim/characters_local" \
FCHPROM_PORT=9108 \
docker compose up fchprom

Go Library

Use 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)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Encode

func Encode(w io.Writer, c *Character) error

func EncodeBytes

func EncodeBytes(c *Character) ([]byte, error)

func PlayerStatIndexByName

func PlayerStatIndexByName(name string) (int, bool)

func PlayerStatNames

func PlayerStatNames() []string

PlayerStatNames returns known player stat names in saved stat order.

func SkillNames

func SkillNames() []string

SkillNames returns known skill names sorted alphabetically.

func SkillTypeByName

func SkillTypeByName(name string) (int32, bool)

Types

type Character

type Character struct {
	FileLength      uint32      `json:"fileLength"`
	Version         uint32      `json:"version"`
	PlayerStatCount uint32      `json:"playerStatCount"`
	PlayerStats     []StatEntry `json:"playerStats,omitempty"`
	Map             MapSection  `json:"map"`
	Player          PlayerData  `json:"player"`
	Trailer         Trailer     `json:"trailer"`
	RemainingBytes  int         `json:"remainingBytes"`
}

func Decode

func Decode(r io.Reader) (*Character, error)

func DecodeBytes

func DecodeBytes(data []byte) (character *Character, err error)

func (*Character) AddInventoryItem

func (c *Character) AddInventoryItem(item Item)

AddInventoryItem appends item to the character inventory.

func (*Character) CreditCraftedItem

func (c *Character) CreditCraftedItem(item Item) Item

CreditCraftedItem credits character as crafter when item is a recipe output and does not already have explicit crafter metadata.

func (*Character) PlaceInventoryItem

func (c *Character) PlaceInventoryItem(item Item) error

PlaceInventoryItem adds item to the first empty normal inventory slot.

func (*Character) PutInventoryItem

func (c *Character) PutInventoryItem(item Item, replace bool) error

PutInventoryItem adds item unless its grid slot is occupied. When replace is true, the item at the same grid slot is overwritten.

func (*Character) RemoveInventoryItem

func (c *Character) RemoveInventoryItem(name string) error

RemoveInventoryItem removes the first inventory item with an exact name match.

func (*Character) SetPlayerStat

func (c *Character) SetPlayerStat(index int, name string, value float32) error

SetPlayerStat sets a player stat by index and keeps PlayerStatCount synchronized.

func (*Character) SetSkill

func (c *Character) SetSkill(skillType int32, level float32)

SetSkill updates an existing skill or appends a new skill record.

func (*Character) UpsertCustomData

func (c *Character) UpsertCustomData(key string, value string)

UpsertCustomData updates player custom data by key or appends it.

func (*Character) UpsertEnemyStat

func (c *Character) UpsertEnemyStat(name string, value float32)

UpsertEnemyStat updates an enemy stat by case-insensitive name or appends it.

func (*Character) UpsertMaterialStat

func (c *Character) UpsertMaterialStat(name string, value float32)

UpsertMaterialStat updates a material stat by case-insensitive name or appends it.

func (*Character) Validate

func (c *Character) Validate() error

Validate verifies that the character matches the file shape this package can safely edit.

type Food

type Food struct {
	Name string  `json:"name"`
	Time float32 `json:"time"`
}

type GuardianPower

type GuardianPower struct {
	Name     string  `json:"name"`
	Cooldown float32 `json:"cooldown"`
}

type Item

type Item struct {
	Name        string      `json:"name"`
	Stack       int32       `json:"stack"`
	Durability  float32     `json:"durability"`
	GridX       int32       `json:"gridX"`
	GridY       int32       `json:"gridY"`
	Equipped    bool        `json:"equipped"`
	Quality     int32       `json:"quality"`
	Variant     int32       `json:"variant"`
	CrafterID   uint64      `json:"crafterId"`
	CrafterName string      `json:"crafterName"`
	CustomData  []TextEntry `json:"customData,omitempty"`
	WorldLevel  uint32      `json:"worldLevel"`
	PickedUp    bool        `json:"pickedUp"`
}

type ItemCatalog

type ItemCatalog struct {
	// contains filtered or unexported fields
}

ItemCatalog holds Valheim ObjectDB item prefab metadata.

func Items

func Items() *ItemCatalog

Items returns the embedded Valheim item catalog.

func (*ItemCatalog) List

func (c *ItemCatalog) List() []ItemMetadata

List returns all known Valheim item prefab metadata sorted by name.

func (*ItemCatalog) Lookup

func (c *ItemCatalog) Lookup(name string) (ItemMetadata, bool)

Lookup returns metadata for a Valheim item prefab name.

func (*ItemCatalog) Names

func (c *ItemCatalog) Names() []string

Names returns all known Valheim item prefab names sorted by name.

type ItemMetadata

type ItemMetadata struct {
	Name           string   `json:"name"`
	InventoryValid bool     `json:"inventoryValid"`
	Recipes        []string `json:"recipes,omitempty"`
	BaseDurability float32  `json:"baseDurability"`
	DurabilityStep float32  `json:"durabilityStep"`
	MaxQuality     int32    `json:"maxQuality"`
	MaxStack       int32    `json:"maxStack"`
}

ItemMetadata describes a Valheim ObjectDB item prefab that can be written to inventory records.

func (ItemMetadata) Durability

func (m ItemMetadata) Durability(quality int32) float32

Durability returns the default full durability for the requested quality.

type MapSection

type MapSection struct {
	Offset           int    `json:"offset"`
	CompressedLength uint32 `json:"compressedLength"`
	StoredLength     uint32 `json:"storedLength"`
	Raw              []byte `json:"-"`
}

type PlayerData

type PlayerData struct {
	Name             string        `json:"name"`
	PlayerID         uint64        `json:"playerId"`
	StartSeed        string        `json:"startSeed"`
	UsedCheats       bool          `json:"usedCheats"`
	DateCreatedUnix  int64         `json:"dateCreatedUnix"`
	KnownWorlds      []TimedEntry  `json:"knownWorlds,omitempty"`
	KnownWorldKeys   []WorldKey    `json:"knownWorldKeys,omitempty"`
	KnownCommands    []StatEntry   `json:"-"`
	EnemyStats       []StatEntry   `json:"enemyStats,omitempty"`
	MaterialStats    []StatEntry   `json:"materialStats,omitempty"`
	RecipeStats      []StatEntry   `json:"recipeStats,omitempty"`
	GuardianPower    GuardianPower `json:"guardianPower"`
	HasPlayerData    bool          `json:"hasPlayerData"`
	PlayerDataLength uint32        `json:"playerDataLength"`
	PlayerVersion    uint32        `json:"playerVersion"`
	MaxHealth        float32       `json:"maxHealth"`
	Health           float32       `json:"health"`
	MaxStamina       float32       `json:"maxStamina"`
	Stamina          float32       `json:"stamina"`
	MaxEitr          float32       `json:"maxEitr"`
	Eitr             float32       `json:"eitr"`
	TimeSinceDeath   float32       `json:"timeSinceDeath"`
	InventoryVersion uint32        `json:"inventoryVersion"`
	Inventory        []Item        `json:"inventory,omitempty"`
	KnownRecipes     []string      `json:"knownRecipes,omitempty"`
	KnownStations    []Station     `json:"knownStations,omitempty"`
	KnownMaterials   []string      `json:"knownMaterials,omitempty"`
	ShownTutorials   []string      `json:"-"`
	Uniques          []string      `json:"uniques,omitempty"`
	Trophies         []string      `json:"trophies,omitempty"`
	KnownBiomes      []uint32      `json:"knownBiomes,omitempty"`
	PlayerKnownTexts []TextEntry   `json:"-"`
	Beard            string        `json:"beard,omitempty"`
	Hair             string        `json:"hair,omitempty"`
	SkinColor        Vector3       `json:"skinColor"`
	HairColor        Vector3       `json:"hairColor"`
	ModelIndex       uint32        `json:"modelIndex"`
	Foods            []Food        `json:"foods,omitempty"`
	SkillVersion     uint32        `json:"skillVersion,omitempty"`
	Skills           []Skill       `json:"skills,omitempty"`
	CustomData       []TextEntry   `json:"customData,omitempty"`
	// contains filtered or unexported fields
}

type Skill

type Skill struct {
	Type         int32   `json:"type"`
	Name         string  `json:"name,omitempty"`
	Level        float32 `json:"level"`
	DisplayLevel int32   `json:"displayLevel"`
	Accumulator  float32 `json:"accumulator"`
}

type StatEntry

type StatEntry struct {
	Name  string  `json:"name"`
	Value float32 `json:"value"`
}

type Station

type Station struct {
	Name  string `json:"name"`
	Level uint32 `json:"level"`
}

type TextEntry

type TextEntry struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

type TimedEntry

type TimedEntry struct {
	Name    string  `json:"name"`
	Seconds float32 `json:"seconds"`
}

type Trailer

type Trailer struct {
	Offset    int    `json:"offset"`
	Length    uint32 `json:"length"`
	Hash      []byte `json:"hash"`
	HashValid bool   `json:"hashValid"`
}

type Vector3

type Vector3 struct {
	X float32 `json:"x"`
	Y float32 `json:"y"`
	Z float32 `json:"z"`
}

type WorldKey

type WorldKey struct {
	Raw     string  `json:"raw"`
	Key     string  `json:"key,omitempty"`
	Setting string  `json:"setting,omitempty"`
	Seconds float32 `json:"seconds"`
}

Directories

Path Synopsis
cmd
fchdump command
fchedit command
fchprom command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL