SOURCE / PINNED RELEASE
Made of little things.
Black Site Map Editor
- Release
- 32a57733b7e9…
- Author-recorded commit
- 3f54890f542f…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.shakespeare.diy%2F/black-site-map-editor
Archive hash verified: 7a4b1abbac7db5b0…. 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-map.v1.json",
"title": "Black Site map",
"description": "One Black Site map, version 1. Coordinates are integer tiles on the authored `size` grid, origin top-left. A rect is [x0, y0, x1, y1] with both corners inclusive. See spec/map-format.md.",
"type": "object",
"additionalProperties": false,
"required": ["format", "version", "id", "name", "theme", "start", "exfil"],
"properties": {
"$schema": { "type": "string" },
"format": { "const": "black-site-map" },
"version": { "const": 1 },
"id": {
"description": "Stable unique id. It also seeds procedural generation unless `generate.seed` is set.",
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{0,31}$"
},
"name": { "description": "Display name, shown upper-case in the HUD.", "type": "string", "minLength": 1, "maxLength": 32 },
"desc": { "description": "One-line briefing shown in map selection.", "type": "string", "maxLength": 200 },
"size": {
"description": "Authored grid size [width, height] in tiles. Defaults to [64, 44]. The outer ring of tiles is always a wall.",
"type": "array",
"prefixItems": [
{ "type": "integer", "minimum": 16, "maximum": 256 },
{ "type": "integer", "minimum": 16, "maximum": 256 }
],
"items": false,
"minItems": 2,
"default": [64, 44]
},
"theme": { "$ref": "#/$defs/theme" },
"generate": { "$ref": "#/$defs/generate" },
"spawns": { "$ref": "#/$defs/spawns" },
"start": { "description": "Player insertion tile.", "$ref": "#/$defs/point" },
"exfil": { "description": "Helipad tile where extraction is called.", "$ref": "#/$defs/point" },
"water": { "description": "Water ('w'). Blocks movement only. With `generate.expand` it stretches across the bands and reaches the far map edge.", "$ref": "#/$defs/areas" },
"paved": { "description": "Pavement ('='), shifted with `generate.expand` but never stretched. Footsteps sound like wood.", "$ref": "#/$defs/areas" },
"roads": { "description": "Roads ('='). With `generate.expand` they stretch across the bands and reach the far map edge.", "$ref": "#/$defs/areas" },
"walls": { "description": "Free-standing walls ('#'), such as compound fences.", "$ref": "#/$defs/areas" },
"buildings": { "type": "array", "items": { "$ref": "#/$defs/building" } },
"containers": { "description": "Shipping containers ('K'). They block movement, bullets and sight.", "type": "array", "items": { "$ref": "#/$defs/container" } },
"tanks": { "description": "Fuel tanks ('o'), 3x3 tiles from the given top-left corner. They block movement, bullets and sight.", "type": "array", "items": { "$ref": "#/$defs/point" } },
"pipes": { "description": "Pipelines ('p'), low cover.", "$ref": "#/$defs/areas" },
"crates": { "description": "Crates ('c'), low cover.", "$ref": "#/$defs/areas" },
"wrecks": { "description": "Vehicle wrecks ('v'), low cover.", "$ref": "#/$defs/areas" },
"sandbags": { "description": "Sandbags ('h'), low cover.", "$ref": "#/$defs/areas" },
"enemies": { "type": "array", "items": { "$ref": "#/$defs/enemy" } },
"caches": { "type": "array", "items": { "$ref": "#/$defs/cache" } }
},
"$defs": {
"coord": { "type": "integer", "minimum": 0, "maximum": 255 },
"point": {
"description": "[x, y]",
"type": "array",
"prefixItems": [{ "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }],
"items": false,
"minItems": 2
},
"rect": {
"description": "[x0, y0, x1, y1], inclusive, with x0 <= x1 and y0 <= y1",
"type": "array",
"prefixItems": [{ "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }],
"items": false,
"minItems": 4
},
"area": { "description": "A single tile [x, y] or a rect [x0, y0, x1, y1].", "oneOf": [{ "$ref": "#/$defs/point" }, { "$ref": "#/$defs/rect" }] },
"areas": { "type": "array", "items": { "$ref": "#/$defs/area" } },
"rgb": {
"type": "array",
"prefixItems": [
{ "type": "integer", "minimum": 0, "maximum": 255 },
{ "type": "integer", "minimum": 0, "maximum": 255 },
{ "type": "integer", "minimum": 0, "maximum": 255 }
],
"items": false,
"minItems": 3
},
"theme": {
"type": "object",
"additionalProperties": false,
"required": ["ground", "road", "style"],
"properties": {
"ground": { "description": "Base ground colour.", "$ref": "#/$defs/rgb" },
"road": { "description": "Road and pavement colour.", "$ref": "#/$defs/rgb" },
"style": { "description": "Ground texture and footstep sound.", "enum": ["grass", "concrete", "sand", "snow"] },
"markings": { "description": "false: roads are drawn as dirt tracks with no lane markings, and sound like sand.", "type": "boolean", "default": true },
"clutter": {
"description": "Tiles that `generate.cover` scatters. Repeat an entry to weight it: 'b' barrel, 'c' crate, 'T' tree, 'h' sandbags.",
"type": "array",
"items": { "enum": ["b", "c", "T", "h"] },
"minItems": 1,
"default": ["b", "c"]
}
}
},
"generate": {
"description": "Seeded procedural content, the same on every build. Leave it out for an exact, hand-built map.",
"type": "object",
"additionalProperties": false,
"properties": {
"expand": { "description": "Build the level at 1.5x `size` by opening one vertical and one horizontal empty band through the layout.", "type": "boolean", "default": false },
"buildings": { "description": "Up to this many extra buildings (with guards and caches) on clear open ground.", "type": "integer", "minimum": 0, "maximum": 64, "default": 0 },
"cover": { "description": "Up to this many clutter clusters (from `theme.clutter`) on clear open ground.", "type": "integer", "minimum": 0, "maximum": 400, "default": 0 },
"seed": { "description": "RNG seed. Defaults to a hash of `id`.", "type": "integer", "minimum": 0, "maximum": 4294967295 }
}
},
"spawns": {
"description": "Random extras added at reachable tiles on every deployment (different each run).",
"type": "object",
"additionalProperties": false,
"properties": {
"extraEnemies": { "description": "Extra enemies as a fraction of the placed ones (0.2 adds 20%). They never spawn within 18 tiles of `start`.", "type": "number", "minimum": 0, "maximum": 2, "default": 0 },
"extraCaches": { "description": "Extra supply caches on indoor floor tiles.", "type": "integer", "minimum": 0, "maximum": 20, "default": 0 }
}
},
"building": {
"description": "A walled building: `r` is the outer wall ring, the inside becomes indoor floor (',').",
"type": "object",
"additionalProperties": false,
"required": ["r"],
"properties": {
"r": { "description": "Outer rect, at least 3x3.", "$ref": "#/$defs/rect" },
"doors": { "description": "Wall tiles turned into doorways. Two side-by-side tiles make a normal door.", "type": "array", "items": { "$ref": "#/$defs/point" } },
"walls": { "description": "Interior walls.", "$ref": "#/$defs/areas" }
}
},
"container": {
"description": "[x0, y0, x1, y1, colour], where colour is '#rrggbb'",
"type": "array",
"prefixItems": [
{ "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" },
{ "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" }
],
"items": false,
"minItems": 5
},
"enemy": {
"description": "[x, y] for a guard who holds position, or [x, y, \"p\"] for a patroller.",
"type": "array",
"prefixItems": [{ "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }, { "const": "p" }],
"items": false,
"minItems": 2
},
"cache": {
"description": "[x, y] for random loot, [x, y, \"weapons\"] to always include a weapon, [x, y, \"start\"] for the ammo and bandage starter cache.",
"type": "array",
"prefixItems": [{ "$ref": "#/$defs/coord" }, { "$ref": "#/$defs/coord" }, { "enum": ["start", "weapons"] }],
"items": false,
"minItems": 2
}
}
}
