A searchable, tag-based, login-free registry to upload and find
.track parts — instrument packs, waves, motifs, tunings, full songs.
Live at trackyard.p11c.xyz, part of the
game-audio ecosystem.
Drop a .track file — no login, no account. Every upload is loaded
through game-audio and written back out (parse →
Display), which has three effects:
.track.Uploads must also be complete: every instrument used by a note or motif placement, every waveform used by an instrument, and every placed motif must be defined in the file or provided by one of its imports. Incomplete uploads are rejected with a list of what is missing. (If the track has URL imports, this check is deferred to rendering, since the server does not fetch URLs during upload.)
Empty tracks are rejected too: a file that defines no sounds, waves, motifs, tunings, or layers and imports nothing is metadata only, with nothing to share — so description-only uploads do not land in the registry.
You can also select several files at once to upload a group of
related tracks together. Each is given its id up front, and bare
<name>.track imports or jump targets that name a sibling in the
batch are rewritten to that sibling's id — so a suite whose tracks reference each
other (a jump loop, say) goes in as a unit, which is impossible one file at a time.
A batch is all-or-nothing: if any file is invalid, empty, or a duplicate, none are
stored; references matching no sibling, registry track, std:, or URL get
a shared fix form.
Uploading requires agreeing that the track is published under CC0 — everything in the registry is free for anyone to use. The upload limit is 1 MB.
An entry's id is a random identifier, assigned once at first upload and fixed for the entry's whole life, even across reuploads — so download, play, and import links never break. It is independent of the content: a track's music is fingerprinted separately, only for duplicate detection.
Duplicate detection compares that content fingerprint (metadata — title, author, description, tags — excluded), stored per entry and updated on every reupload: uploading music that is already in the registry, even under a different title or tags, is flagged and points you to the existing entry instead of creating a second one. That flag only fires on byte-identical canonical content — change a single note, sound, or wave and it uploads as a new entry.
A changed version of a track is published by reuploading the existing entry (which keeps its id, votes, comments, and dependants), not as a fresh upload — see Editing.
Tracks may import other tracks (@import) under a strict policy.
Allowed are exactly:
| Form | Example | Meaning |
|---|---|---|
std: libraries | @import std:drums |
Instrument banks bundled with game-audio. |
http(s) URLs | @import https://…/lib.track |
Any track on the web. Fetched by the server when rendering and by the browser when playing. |
| Bare registry filenames | @import a1b2c3….track |
Another registry entry by its id. Resolves on the server, in the browser (relative to the download URL), and inside a clone of the mirrored library, where all tracks sit flat in one directory. |
Anything else — relative or absolute local paths from the uploader's machine — triggers a replacement form: each offending import gets a field (with autocomplete over all registry tracks) to substitute a URL or a registry entry, and the upload proceeds with the rewritten imports.
A @jump target (where interactive music continues when a section
ends) is a .track reference too, so it follows the same policy —
localized, validated, and counted as a dependency just like an import. A jump that
loops the track back to itself (@jump <own-filename>) is recognized
and rewritten to the entry's own id automatically, with no fix step.
Bare registry imports and jumps form a graph: each entry page lists its dependencies (the registry tracks it references) and its dependants (the registry tracks that reference it), both as clickable links to those entries.
Every entry carries two kinds of tags:
song or part (has playable layers or not),
pack (imports other tracks but defines nothing of its own, like a
bundle), plus sounds, waves, motifs,
tunings for whatever the file defines.nes, lead, boss-theme, …).The file's own ## Tags section (under # Meta) is the
source of truth: tag edits are written back into the stored .track, so
a part stays self-describing outside the registry too.
Tags are normalized to lowercase a-z, 0-9 and
-; anything else becomes a dash. Boss Theme,
boss_theme and boss-theme are the same tag. At most 16
tags of up to 32 characters each.
Ownership is a visitor cookie — still no login. The uploader (and the admin) can edit an entry's metadata: title, author, description, and tags.
Uploading redirects straight to the edit page, pre-filled from the file's own metadata. The tag menu lists every existing registry tag with its usage count, filters as you type, and offers a marked (new) chip when the name matches nothing — adding and removing tags works without page reloads.
The content is editable too, but only by replacing it, never by silent drift:
@import of another
registry track (picked from an autocomplete list) to this track and re-stores it.The uploader (or an admin) can also delete an entry — from its
edit page or straight from the listing. Deleted tracks move to deleted/
inside the data directory; they are never destroyed.
Any visitor can leave a comment on an entry, with an optional display name (shown
before the timestamp, or anonymous if left blank); comments appear on the
entry page. A comment's own author (recognized by the visitor cookie, marked
you) or an admin can delete it — no one else. Every posted comment is also
appended to an
append-only comments.log in the data directory (one JSON object per
line), kept even after the comment is deleted, so the operator can review
problematic ones. That log stays local: it is gitignored and never mirrored.
The index filters by at most one author (?author=…, from a clickable
author name), at most one content facet (?auto=waves), any number of
free tags (?tag=nes&tag=lead, narrowing by all of them), and a text
search over title, author, description and tags — all combinable. Clicking a chip
sets or adds that filter, and each active filter shows as a removable pill. Results
are paginated at 24 per page. Sort criteria: newest, most downloaded, most liked
(the default), best like/dislike ratio, most controversial; each reversible.
Anyone can vote 👍/👎 (one vote per visitor, toggleable). Downloads are counted per entry.
# Subtitles) are listed as
lyrics.#url=… opens a
track in the editor to build on, #import=… pulls it in as an import.Play, remix, import, and export open in a new tab, so a slow render or a jump to the editor never replaces the page you were browsing.
| URL | What it serves |
|---|---|
/ | Index: search, filters, upload form. |
/entry/<id> | Entry page with previews. |
/entry/<id>/edit | Metadata + tag editor (owner/admin). |
/download/<id>.track | Canonical download (stable, CORS-open). |
/tracks/<author>/<title>.track | Human-readable alias of the download,
ready for @import. Follows metadata edits; the id URL is the stable one. |
/export/<id>/wav, …/mp3 | Rendered audio. |
/preview/<id>/<layer|sound|wave>/<n> | Preview snippets. |
/admin | Admin login. |
If the data directory is a Git repository, the server commits and pushes all
track changes about once a minute — the registry doubles as a public, forkable
library. Only canonical .track files are published; the rendered audio
cache, deleted entries, and the JSON index (it contains visitor ids) are kept out
via a generated .gitignore.
git -C data init -b master
git -C data remote add origin <public repo url>
A random admin token is printed on the server console at every start. An
Admin link sits in the page header. Logging in at /admin allows
editing and deleting every entry, and deleting any comment. Deleted tracks are moved
to deleted/ inside the data directory, never destroyed; posted comments
are additionally recorded in comments.log (see
Comments) for after-the-fact review.
trackyard [--address host:port] [--data directory] [--public-url url]
[--player-url url] [--editor-url url]
| Flag | Default | Purpose |
|---|---|---|
--address | 0.0.0.0:3000 | Listen address. |
--data | data/ | Storage: canonical tracks, JSON index, audio cache. No database. |
--public-url | http://localhost:3000 |
Base URL used in play/remix/import links. |
--player-url | https://p11c.xyz/plainaudio/ |
plainaudio instance for play links. |
--editor-url | https://p11c.xyz/plainsong/ |
plainsong instance for remix links. |
Source: gitlab.com/porky11/trackyard (Rust, axum + maud + game-audio; MP3 export needs a C compiler at build time).