esapi

package
v2.12.0 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: GPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package esapi provides types and helpers for reading EmulationStation gamelist.xml files.

EmulationStation (ES) has been forked many times; each fork and scraper tool differs in which fields it writes and how it formats media paths. The Game and Folder structs here cover the superset of all known fields. Unknown elements are silently ignored by encoding/xml.

Path format conventions

All path-based media fields (image, thumbnail, video, etc.) accept three path formats, which ES resolves at runtime:

  • Absolute: /home/pi/.emulationstation/downloaded_images/snes/game.png
  • System-relative: ./media/images/game.png (relative to system ROM folder)
  • Home-relative: ~/.emulationstation/downloaded_images/snes/game.png

ES will try to write paths as system-relative or home-relative when saving so that installations remain portable across machines.

Fork / version landscape

This file comments each media field with observed differences across:

  • Aloshi (original ES, ~2014)
  • RetroPie fork (RetroPie/EmulationStation)
  • Batocera fork (batocera-linux/batocera-emulationstation, MetaData.cpp)
  • ES-DE (EmulationStation Desktop Edition)
  • AmberELEC / EmuELEC forks
  • Recalbox fork
  • Skyscraper scraper (muldjord/skyscraper) output
  • ARRM scraper output
  • Pegasus frontend (compatible reader)

Index

Constants

View Source
const ESDateFormat = "20060102T150405"

ESDateFormat is the strftime-style format EmulationStation uses for releasedate and lastplayed: "%Y%m%dT%H%M%S". In Go's time package this translates to the layout below. Some scrapers omit the time component and write only the date portion ("19950311T000000").

Variables

This section is empty.

Functions

func APIEmuKill

func APIEmuKill() error

func APILaunch

func APILaunch(path string) error

func APINotify

func APINotify(msg string) error

func APIRequest

func APIRequest(path, body string, timeout time.Duration) ([]byte, error)

func FormatESDate added in v2.12.0

func FormatESDate(t time.Time) string

FormatESDate formats a time.Time into the EmulationStation datetime string format ("YYYYMMDDTHHMMSS") used by releasedate and lastplayed fields.

func IsAvailable

func IsAvailable() bool

IsAvailable checks if the EmulationStation API server is running

func ParseESDate added in v2.12.0

func ParseESDate(s string) (time.Time, error)

ParseESDate parses an EmulationStation datetime string into a time.Time. ES stores dates as "YYYYMMDDTHHMMSS" (e.g. "19950311T000000") using ESDateFormat. Zone-less ES timestamps are treated as UTC (time.Parse with a layout that has no timezone produces a time with UTC location). Callers that need local-time semantics must convert the result with time.In or time.ParseInLocation. Returns the zero time and an error if the string is empty or malformed.

func ParseRating added in v2.12.0

func ParseRating(s string) (float64, error)

ParseRating parses an ES rating string (a float between "0" and "1") into a float64. Returns 0 and an error if the string is empty, malformed, or outside [0, 1].

Types

type Folder added in v2.12.0

type Folder struct {
	XMLName xml.Name `xml:"folder"`

	// Path is the subfolder path, typically relative to the system ROM folder.
	Path string `xml:"path"`

	Name string `xml:"name,omitempty"`
	Desc string `xml:"desc,omitempty"`

	// Image and Thumbnail follow the same fork/path differences as in Game.
	Image     string `xml:"image,omitempty"`
	Thumbnail string `xml:"thumbnail,omitempty"`

	// Some forks (Batocera, ES-DE) also support video and marquee on folders.
	Video   string `xml:"video,omitempty"`
	Marquee string `xml:"marquee,omitempty"`
}

Folder represents a <folder> entry in the gamelist. Folders support a smaller set of metadata than games. Most path-based media fields follow the same fork differences as in Game — see Game field comments.

type Game

type Game struct {
	XMLName             xml.Name `xml:"game"`
	Developer           string   `xml:"developer,omitempty"`
	Bezel               string   `xml:"bezel,omitempty"`
	Name                string   `xml:"name,omitempty"`
	SortName            string   `xml:"sortname,omitempty"`
	Desc                string   `xml:"desc,omitempty"`
	Image               string   `xml:"image,omitempty"`
	Thumbnail           string   `xml:"thumbnail,omitempty"`
	Video               string   `xml:"video,omitempty"`
	Marquee             string   `xml:"marquee,omitempty"`
	Wheel               string   `xml:"wheel,omitempty"`
	FanArt              string   `xml:"fanart,omitempty"`
	TitleShot           string   `xml:"titleshot,omitempty"`
	Manual              string   `xml:"manual,omitempty"`
	Magazine            string   `xml:"magazine,omitempty"`
	Map                 string   `xml:"map,omitempty"`
	Genre               string   `xml:"genre,omitempty"`
	Cartridge           string   `xml:"cartridge,omitempty"`
	BoxBack             string   `xml:"boxback,omitempty"`
	Mix                 string   `xml:"mix,omitempty"`
	Rating              string   `xml:"rating,omitempty"`
	ReleaseDate         string   `xml:"releasedate,omitempty"`
	ScreenScraperIDAttr string   `xml:"id,attr,omitempty"`
	Path                string   `xml:"path"`
	Publisher           string   `xml:"publisher,omitempty"`
	LastPlayed          string   `xml:"lastplayed,omitempty"`
	Players             string   `xml:"players,omitempty"`
	Tags                string   `xml:"tags,omitempty"`
	Family              string   `xml:"family,omitempty"`
	ArcadeSystemName    string   `xml:"arcadesystemname,omitempty"`
	Emulator            string   `xml:"emulator,omitempty"`
	Core                string   `xml:"core,omitempty"`
	Lang                string   `xml:"lang,omitempty"`
	Region              string   `xml:"region,omitempty"`
	Source              string   `xml:"source,omitempty"`
	CRC32               string   `xml:"crc32,omitempty"`
	MD5                 string   `xml:"md5,omitempty"`
	MultiDisk           string   `xml:"multidisk,omitempty"`
	CheevosHash         string   `xml:"cheevosHash,omitempty"`
	Genres              string   `xml:"genres,omitempty"`
	ScreenScraperID     int      `xml:"id,omitempty"` //nolint:revive // both "id" attr and "id" element exist in real ES forks
	PlayCount           int      `xml:"playcount,omitempty"`
	CheevosID           int      `xml:"cheevosId,omitempty"`
	GameTime            int      `xml:"gametime,omitempty"`
	Favorite            bool     `xml:"favorite,omitempty"`
	Hidden              bool     `xml:"hidden,omitempty"`
	KidGame             bool     `xml:"kidgame,omitempty"`
}

Game represents a single <game> entry in the gamelist.xml.

Fields are marked omitempty so that re-marshalling preserves sparseness; ES itself omits fields whose value matches the type default.

Media path field differences (20+ documented cases)

Each path-type field below carries a comment block describing known fork/scraper differences. The short codes used are:

[Aloshi]   — original Aloshi/EmulationStation (master branch)
[RPI]      — RetroPie fork
[Batocera] — Batocera fork (MetaData.cpp defines the canonical tag names)
[ES-DE]    — EmulationStation Desktop Edition
[AmberELEC]— AmberELEC / EmuELEC forks
[Recalbox] — Recalbox fork
[Sky]      — Skyscraper scraper output
[ARRM]     — ARRM scraper output

type GameList

type GameList struct {
	XMLName xml.Name `xml:"gameList"`
	Games   []Game   `xml:"game"`
	Folders []Folder `xml:"folder"`
}

GameList is the root element of an EmulationStation gamelist.xml file. It may contain any mix of <game> and <folder> children.

func ReadGameListXML

func ReadGameListXML(path string) (GameList, error)

ReadGameListXML opens and unmarshals an EmulationStation gamelist.xml file. Unknown XML elements are silently ignored, so fork-specific fields not present in the target ES version are safe to include.

type RunningGameResponse

type RunningGameResponse struct {
	ID          string `json:"id"`
	Path        string `json:"path"`
	Name        string `json:"name"`
	SystemName  string `json:"systemName"`
	Desc        string `json:"desc"`
	Image       string `json:"image"`
	Video       string `json:"video"`
	Marquee     string `json:"marquee"`
	Thumbnail   string `json:"thumbnail"`
	Rating      string `json:"rating"`
	ReleaseDate string `json:"releaseDate"`
	Developer   string `json:"developer"`
	Genre       string `json:"genre"`
	Genres      string `json:"genres"`
	Players     string `json:"players"`
	Favorite    string `json:"favorite"`
	KidGame     string `json:"kidgame"`
	LastPlayed  string `json:"lastplayed"`
	CRC32       string `json:"crc32"`
	MD5         string `json:"md5"`
	GameTime    string `json:"gametime"`
	Lang        string `json:"lang"`
	CheevosHash string `json:"cheevosHash"`
}

func APIRunningGame

func APIRunningGame() (RunningGameResponse, bool, error)

Jump to

Keyboard shortcuts

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