Expand README: format, statuses, contribution flow, consumption

This commit is contained in:
2026-07-31 17:49:58 +01:00
parent 295d594936
commit a2e2875449
+141 -1
View File
@@ -1,3 +1,143 @@
# sprite-catalog
Public sprite catalog data — one JSON file per season, with a JSON Schema and validation CI. Consumed by sprite-trade-bot via a configurable raw URL.
The sprite catalog that drives trade matching and giveaways in the Sprites Trading HQ
Discord server. One JSON file per season, validated against a JSON Schema.
This repo is **data, not code**. It is public so anyone can read it, build against it,
or run their own bot from it.
---
## Why JSON
The catalog is a public data source other people consume. JSON is readable in every
language and in the browser with zero dependencies; YAML needs a parser everywhere.
JSON's one real weakness for a hand-maintained file is that it has no comments and is
unforgiving about syntax. Both are covered: the schema in [`schema/`](schema/) gives
editors autocomplete and inline validation as you type, CI rejects malformed files
before merge, and every object accepts a `notes` field for anything you would otherwise
have written as a comment.
---
## Layout
```
schema/sprite-catalog.schema.json the contract — CI and editors both use it
seasons/c7s3.json one file per season, named for the season
seasons/c7s4.json
```
Season files are **append-mostly**. Entries are never deleted — a sprite that leaves
circulation gets `"status": "hidden"`, which drops it out of matching while keeping it
in the inventories of everyone who already holds one.
---
## Format
Variants nest under their base sprite so `base_name` and `row_name` aren't repeated for
every skin. The bot flattens this to one row per variant on load.
```json
{
"season": "c7s3",
"game_mode": "br",
"cross_mode_trading": false,
"sprites": [
{
"base_name": "Example Sprite",
"row_name": "Example Row",
"variants": [
{
"variant": "Default",
"status": "released",
"released_at": "2026-03-14",
"max_stack": 5,
"confirmed": true
},
{
"variant": "Gold",
"status": "unreleased",
"notes": "Datamined; not yet obtainable in game."
}
]
}
]
}
```
### The three statuses
| Status | Meaning |
|---|---|
| `unreleased` | Known but not yet obtainable. Excluded from matching. |
| `released` | Obtainable and tradeable. |
| `hidden` | Dropped out of matching, retained in inventories. **Reversible.** |
`hidden` deliberately replaces a `retired` concept that appeared in earlier drafts.
Sprites usually come back, and if one never does, nothing is lost by having called it
hidden — whereas `retired` implies a permanence the data can't promise.
### Fields worth explaining
- **`confirmed`** — variant lists are assumed-complete guesses until someone is actually
recorded owning one. Unconfirmed variants are deprioritised in autocomplete and left
out of the coverage metric, so a speculative entry can't quietly distort either.
- **`rarity_weight`** — display and analytics only. **The matcher does not read it.**
Rarity matching was removed on purpose: value-matching is how selfish players win and
the pool starves. Trades are N-for-N by count, never by value.
- **`max_stack`** — anything above 1 means spare copies can enter the give pool.
- **`cross_mode_trading`** — defaults to `false`. Leave it there unless the policy is
deliberately changed.
---
## Contributing
1. Fork or branch, edit the season file.
2. Open a PR. CI validates every file in `seasons/` against the schema and fails on
malformed JSON, unknown fields, bad status values, or a `season` value that doesn't
match the filename.
3. A mod merges. The bot picks it up on the next `/mod catalog reload`, which shows a
diff preview ("adds 6 sprites, 14 variants, no removals — apply?") before anything
is written.
The bot's exporter opens a draft PR automatically when it sees a sprite ID it doesn't
recognise, so most additions start here rather than being typed by hand.
**Editor setup** — point your editor at `schema/sprite-catalog.schema.json` and you get
completion and error squiggles inline. In VS Code, add to `.vscode/settings.json`:
```json
{
"json.schemas": [
{ "fileMatch": ["seasons/*.json"], "url": "./schema/sprite-catalog.schema.json" }
]
}
```
---
## Consuming it
The bot fetches raw files over HTTP and caches them in memory — autocomplete has a hard
3-second budget with no defer available, so it never queries a database per keystroke.
The raw URL is configurable via `CATALOG_REPO_RAW`, so you can point a development bot
at your own fork without touching code:
```
CATALOG_REPO_RAW=https://git.thewichersfamily.com/thethreemagi/sprite-catalog/raw/branch/main
```
Nothing about the format is bot-specific. Fetch the JSON and use it however you like.
---
## Note on history
Commits here carry no AI attribution — see [`.githooks/commit-msg`](.githooks/commit-msg),
enabled with `git config core.hooksPath .githooks && chmod +x .githooks/commit-msg`.
Please keep it that way in PRs.