Back to Black Site Map Editor
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.

src/vendor/black-site-map.schema.json
{
  "$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
    }
  }
}