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.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://black-site.napplet/spec/schemas/black-site-campaign.v1.json",
"title": "Black Site campaign",
"description": "A Black Site campaign, version 1: an ordered list of maps played back to back, with optional rules. It is published as the content of a kind 35859 event, and the event's d tag is its id. See spec/campaign-format.md.",
"type": "object",
"additionalProperties": false,
"required": ["version", "name", "stages"],
"properties": {
"version": { "const": 1 },
"name": { "description": "Display name.", "type": "string", "minLength": 1, "maxLength": 32 },
"desc": { "description": "One-line description shown in the campaign list.", "type": "string", "maxLength": 200 },
"rules": { "$ref": "#/$defs/rules" },
"stages": {
"description": "Maps in play order.",
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": { "$ref": "#/$defs/stage" }
}
},
"$defs": {
"hex64": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
"rules": {
"type": "object",
"additionalProperties": false,
"properties": {
"completionBonus": { "description": "Paid on top of the funds hold when the last map is cleared, before the difficulty money multiplier.", "type": "integer", "minimum": 0, "maximum": 1000000, "default": 3000 },
"quitPenalty": { "description": "Taken from the hold when a player quits a map partway through.", "type": "integer", "minimum": 0, "maximum": 100000, "default": 400 },
"difficulty": { "description": "Lock the campaign to one difficulty. Without it, the player picks the difficulty when starting.", "enum": ["easy", "normal", "hard"] },
"carryInventory": { "description": "Weapons and items carry over from one map to the next. When false, every map starts with the player's loadout.", "type": "boolean", "default": true },
"restoreHealth": { "description": "Health and armour are restored between maps.", "type": "boolean", "default": true }
}
},
"stage": {
"description": "One map in the campaign: either a built-in map, or a published map pinned to an exact version.",
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": ["builtin"],
"properties": {
"builtin": { "description": "Id of a map that ships with the game.", "enum": ["town", "docks", "desert", "snow", "refinery"] },
"briefing": { "$ref": "#/$defs/briefing" }
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["address", "x"],
"properties": {
"address": { "description": "Map event address: 35858:<author pubkey hex>:<map id>.", "type": "string", "pattern": "^35858:[0-9a-f]{64}:[a-z0-9][a-z0-9-]{0,31}$" },
"x": { "description": "SHA-256 of the map JSON this campaign was built with (the map event's x tag at the time). It pins the stage to that exact version.", "$ref": "#/$defs/hex64" },
"relays": { "description": "Relays where the map event can be found.", "type": "array", "maxItems": 5, "items": { "type": "string", "pattern": "^wss://" } },
"briefing": { "$ref": "#/$defs/briefing" }
}
}
]
},
"briefing": { "description": "Shown before the map starts, as plain text.", "type": "string", "maxLength": 500 }
}
}
