S3maphoreDocs
api

Playlist and Track Metadata

Add display metadata to playlists and tracks with YAML files.

Metadata is separate from playlist behavior. A Lua playlist file defines what can play; a YAML metadata file gives S3maphore the names and descriptive information to show when it plays.

Put a .yaml or .yml file under the same VFS Playlists/ directory as the Lua playlist files. S3maphore loads both formats automatically.

Metadata file format

Metadata is divided into playlists and tracks:

playlists:
  my-mod/explore:
    title: My Mod Explore Music
    artist: Example Artist
    album: The Example Collection
    year: 2026
    genre: Ambient
    description: Exploration music for the example region.
    source: Example Mod
    composer: Example Composer
    license: CC BY-SA 4.0

tracks:
  music/my-mod/explore/first-song.mp3:
    title: Across the Bitter Coast
    artist: Example Artist
    album: The Example Collection
    year: 2026
    genre: Ambient
    description: A quiet walk along the coast.
    source: Example Mod
    composer: Example Composer
    license: CC BY-SA 4.0

Metadata fields describe provenance as well as display text. title is the human-facing display title; prefer the canonical release title when one is known, otherwise use a stable descriptive or filename-derived title. artist is the credited artist or project, composer is the composer when known, and album is the actual musical album or release containing the track—not merely the name of a mod. source identifies the originating game, mod, or package. For tracks, it should identify the source of the exact VFS asset; for playlists, it identifies the package or content set defining the logical playlist. license is recorded only when the exact license or usage terms are known; S3maphore does not infer licenses from a source or artist.

The playlist key is the playlist's id. The track key is the track's full VFS path. Both keys are normalized before lookup, so use the same paths and IDs you use in the playlist definition.

String values are shorthand for a title-only metadata table:

playlists:
  my-mod/explore: My Mod Explore Music
tracks:
  music/my-mod/explore/first-song.mp3: Across the Bitter Coast

Table values must contain a string title. The supported fields are:

FieldTypeMeaning
titlestringHuman-facing display title; prefer a known canonical release title, otherwise use a stable descriptive or filename-derived title. Required for table values.
artiststring?Credited artist or project name.
albumstring?Actual musical album or release containing the track.
yearinteger?Release year.
genrestring?Genre label.
descriptionstring?Longer description.
sourcestring?Originating game, mod, or package; for tracks, the source of the exact VFS asset, and for playlists, the package or content set defining the logical playlist.
composerstring?Composer, when known.
licensestring?Exact known license or usage terms; do not infer.

Adding metadata to an existing playlist

Do not put metadata fields inside the playlist table. Add a YAML entry keyed by the existing playlist ID or track VFS path:

return {
    {
        id = 'my-mod/explore',
        priority = PlaylistPriority.Explore,
        tracks = {
            'music/my-mod/explore/first-song.mp3',
        },
        isValidCallback = function()
            return not Playback.state.isInCombat
        end,
    },
}
playlists:
  my-mod/explore: My Mod Explore Music
tracks:
  music/my-mod/explore/first-song.mp3: Across the Bitter Coast

This works the same way when tracks are discovered from the playlist ID's folder. Metadata names the resulting playlist and track; it does not add tracks, register playlists, or change selection rules.

Normalization and collisions

Playlist IDs and track paths are normalized to lowercase, forward-slash paths with redundant separators removed. Metadata lookups therefore behave consistently even when the Lua definition uses different capitalization.

If multiple YAML files define the same normalized playlist ID or track path, the later-loaded entry replaces the earlier one and S3maphore logs an override message. Keep one metadata owner per key unless an intentional override is part of the mod's design.

Malformed playlist or metadata files abort S3maphore initialization. S3maphore does not continue with a partially loaded music configuration. A metadata table without a string title is invalid.

Reading metadata from Lua

The public registry is available as I.S3maphore.playlistMetadata:

local S3maphore = require('openmw.interfaces').S3maphore
local registry = S3maphore.playlistMetadata

local playlist = registry.getPlaylistMetadata('my-mod/explore')
local track = registry.getTrackMetadata('music/my-mod/explore/first-song.mp3')
local displayName = registry.getPlaylistDisplayName('my-mod/explore')

The returned metadata tables are read-only. Unknown playlist IDs and track paths return nil; getPlaylistDisplayName falls back to the supplied playlist ID when no title is registered.

The registry also provides iterators for tooling and UI:

MethodResult
getPlaylistDisplayName(id)Metadata title, or the original ID when no metadata exists.
getPlaylistMetadata(id)Playlist metadata table, or nil.
getTrackMetadata(path)Track metadata table, or nil.
iterPlaylists()Iterator over normalized playlist IDs and metadata.
iterTracks()Iterator over normalized VFS paths and metadata.
loadYamlFile(path)Loads or reloads one metadata file. Advanced, loader-facing operation; malformed input raises an error. Ordinary integrations should let S3maphore discover metadata automatically.

I.S3maphore.getCurrentTrackInfo() returns the metadata for the current playlist and track as two values. The track banner appears only when both metadata entries are available and track information is enabled; it does not fall back to the playlist ID or track path. See I.S3maphore for the interface method and Events for track-change notifications.

Metadata is not a localization file. The registry stores the values supplied by YAML and does not choose translations for them. If a music pack needs localized display text, it must provide that behavior separately rather than assuming metadata keys are passed through OpenMW's l10n system.