SOURCE / PINNED RELEASE
Made of little things.
Black Site
- Release
- 666bc7c74ebd…
- Author-recorded commit
- 05e95af79676…
- License
- LICENSE
- Author’s source reference
- nostr://npub12lm3rxsva8kfempyjkxupt09e02n3fezurkyadyqfejdc5e0r2kscqty6r/wss%3A%2F%2Fgit.napplet.soy%2F/n-d2225ddc391
Archive hash verified: 1544e072e245c4a8…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# Black Site data specifications
Everything another napplet or app needs to read, write or publish Black Site data. This folder stands on its own, so you can copy it or vendor it as a whole.
## Specs
| Spec | What it defines | Nostr |
|---|---|---|
| [map-format.md](map-format.md) | Map JSON v1: coordinates, every placeable asset, generation and build order | none (the file itself) |
| [map-event.md](map-event.md) | Publishing and loading custom maps. The JSON lives on Blossom and is fetched through NAP-RESOURCE | kind **35858**, addressable |
| [campaign-format.md](campaign-format.md) | Campaign JSON v1 (ordered stages, rules, briefings) and its event | kind **35859**, addressable, JSON in `content` |
| [remix-lineage.md](remix-lineage.md) | Remixing maps and campaigns, with credit for every parent, the original and all authors | NIP-22 style `A`/`a`, `E`/`e`, `K`/`k`, `P`/`p` tags on 35858 and 35859 |
## Schemas (JSON Schema draft 2020-12)
| Schema | Validates |
|---|---|
| [schemas/black-site-map.schema.json](schemas/black-site-map.schema.json) | A map JSON file |
| [schemas/black-site-campaign.schema.json](schemas/black-site-campaign.schema.json) | A campaign JSON document (a kind 35859 event's `content`) |
## Reference code (ES modules, no dependencies)
| Module | Exports |
|---|---|
| [lib/validate-map.mjs](lib/validate-map.mjs) | `validateMap`, `MAP_FORMAT`, `MAP_VERSION`, `DEFAULT_MAP_SIZE` |
| [lib/map-event.mjs](lib/map-event.mjs) | `MAP_EVENT_KIND`, `mapEventTemplate`, `parseMapEvent`, `mapResourceUrls`, `readMapBytes`, `MAX_MAP_BYTES` |
| [lib/validate-campaign.mjs](lib/validate-campaign.mjs) | `validateCampaign`, `campaignRules`, `DEFAULT_RULES`, `BUILTIN_MAP_IDS`, `DIFFICULTY_IDS` |
| [lib/campaign-event.mjs](lib/campaign-event.mjs) | `CAMPAIGN_EVENT_KIND`, `campaignEventTemplate`, `parseCampaignEvent`, `stageMapFilter`, `stageMapRef` |
| [lib/lineage.mjs](lib/lineage.mjs) | `remixTags`, `parseLineage`, `REMIX_KINDS`, `MAX_LINEAGE_AUTHORS` |
The validators return `[]` for valid data, or readable `"path: problem"` strings. They cover everything the schemas do, plus rules a schema can't express, such as bounds, rect corner order, doors on walls, and map ids that must match their events. Treat the validators as the final word.
## Examples
- [examples/maps/outpost.json](examples/maps/outpost.json): a small hand-built map
- [examples/campaigns/black-site.json](examples/campaigns/black-site.json): the game's built-in campaign
- [examples/campaigns/border-run.json](examples/campaigns/border-run.json): built-in and published maps, with custom rules
## Napplet domains used
| Domain | For |
|---|---|
| NAP-OUTBOX | Querying and publishing kind 35858 and 35859 events, and reading authors' kind 10063 Blossom server lists |
| NAP-RESOURCE | Fetching map JSON as `blossom:<sha256>`, falling back to `https://<server>/<sha256>.json` |
| NAP-UPLOAD | Uploading map JSON to Blossom before publishing |
## Versioning
- Every document and event carries a `version`.
- Additive, optional fields keep the version. Changing the meaning of existing fields bumps it.
- Readers must treat a newer version as "can't load", not as invalid data.
- Kinds 35858 and 35859 aren't yet in [registry-of-kinds](https://github.com/nostr-protocol/registry-of-kinds).
The game's tests (`pnpm test:spec`) check every example and built-in map against these specs.
