{
  "lexicon": 1,
  "id": "net.bisks.war.ruleset",
  "defs": {
    "main": {
      "type": "record",
      "description": "A set of house rules for a game of WAR, written via putRecord to a fixed rkey rather than created fresh each time. Three conventions share this collection, distinguished only by which rkey they're written to (not by anything in the record itself): rkey 'current' in a player's own repo is the rules their own future games use (also read from @bisks.net's repo as the shared baseline, and from the game ref @antiali.as's own repo as their personal rules); rkey 'for-ref' in the super-ref's (@norvid-studies.bsky.social) own repo is the ruleset they are imposing on the game ref, which outranks the ref's own 'current' record. Written and read by war (https://war.bisks.net).",
      "key": "any",
      "record": {
        "type": "object",
        "required": ["warCards", "aceRank", "midWarBust", "roundCap", "jokers", "updatedAt"],
        "properties": {
          "warCards": {
            "type": "string",
            "knownValues": ["1", "2", "3"],
            "description": "How many face-down cards are laid before the deciding flip in a war. '3' is the classic rule."
          },
          "aceRank": {
            "type": "string",
            "knownValues": ["high", "low"],
            "description": "Whether an ace beats the king ('high', classic) or ranks below a 2 ('low')."
          },
          "midWarBust": {
            "type": "string",
            "knownValues": ["concede", "split"],
            "description": "What happens when a side can't fully cover a war: 'concede' ends the game for them (classic), 'split' divides the pot evenly and continues the game."
          },
          "roundCap": {
            "type": "string",
            "knownValues": ["none", "26", "52"],
            "description": "Caps the game length in rounds, most cards held at the cap wins ('none' plays to the last card, the classic rule)."
          },
          "jokers": {
            "type": "string",
            "knownValues": ["off", "on"],
            "description": "Whether 2 wild joker cards are added to the deck ('on'), beating every other card (and each other, which starts a war)."
          },
          "note": {
            "type": "string",
            "maxLength": 1200,
            "maxGraphemes": 300,
            "description": "Optional free-text note explaining the change, capped client-side at 300 characters. Only ever written on a 'for-ref' record (the super-ref's note to the game ref on why these rules); a 'current' record instead carries its change notes inside each history entry below."
          },
          "history": {
            "type": "array",
            "maxLength": 10,
            "items": { "type": "ref", "ref": "#historyEntry" },
            "description": "The last up to 10 rule changes made to this record, most recent first, each a full snapshot of the rules that became active at that point — lets a later change be restored verbatim. Only ever written on a 'current' record; a 'for-ref' record has no history of its own."
          },
          "updatedAt": {
            "type": "string",
            "format": "datetime",
            "description": "When this ruleset was last written, as an ISO 8601 datetime."
          }
        }
      }
    },
    "historyEntry": {
      "type": "object",
      "required": ["by", "note", "at", "rules"],
      "properties": {
        "by": {
          "type": "string",
          "format": "handle",
          "description": "Bluesky handle of whoever made this change."
        },
        "note": {
          "type": "string",
          "maxLength": 1200,
          "maxGraphemes": 300,
          "description": "Free-text note about the change (may be empty). Client-generated notes include things like 'reset to defaults by admin' or 'restored by <handle> (<role>): <label>'."
        },
        "at": {
          "type": "string",
          "format": "datetime",
          "description": "When this change was made, as an ISO 8601 datetime."
        },
        "rules": {
          "type": "ref",
          "ref": "#ruleValues",
          "description": "Snapshot of the five rule knobs as they became active at this change."
        }
      }
    },
    "ruleValues": {
      "type": "object",
      "required": ["warCards", "aceRank", "midWarBust", "roundCap", "jokers"],
      "properties": {
        "warCards": { "type": "string", "knownValues": ["1", "2", "3"] },
        "aceRank": { "type": "string", "knownValues": ["high", "low"] },
        "midWarBust": { "type": "string", "knownValues": ["concede", "split"] },
        "roundCap": { "type": "string", "knownValues": ["none", "26", "52"] },
        "jokers": { "type": "string", "knownValues": ["off", "on"] }
      }
    }
  }
}
