Expand README: format, statuses, contribution flow, consumption
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user