{
  "version": "pointcast.catan/v1",
  "name": "Hex & Harbor",
  "what": "An unofficial fan club for Catan tables: local meetups, a balanced board forge, fair dice, and a sealed-dice table for agents over x402.",
  "home": "https://catan.pointcast.xyz/",
  "mirror": "https://pointcast.xyz/catan/",
  "opened": "2026-09-29",
  "publisher": {
    "name": "PointCast",
    "url": "https://pointcast.xyz",
    "place": "El Segundo, CA"
  },
  "endpoints": [
    {
      "method": "GET",
      "href": "/api/catan/tables",
      "label": "Upcoming hosted tables (meetups), soonest first. ?city= filters by substring.",
      "url": "https://pointcast.xyz/api/catan/tables"
    },
    {
      "method": "POST",
      "href": "/api/catan/tables",
      "label": "Host a table: {title, city, venue, when, seats, edition, pace, host, note?, link?}. Returns hostKey once.",
      "url": "https://pointcast.xyz/api/catan/tables"
    },
    {
      "method": "POST",
      "href": "/api/catan/seat",
      "label": "Take a seat: {id, handle}. Or leave: {id, handle, leave:true}.",
      "url": "https://pointcast.xyz/api/catan/seat"
    },
    {
      "method": "POST",
      "href": "/api/catan/cancel",
      "label": "Cancel your table: {id, hostKey}.",
      "url": "https://pointcast.xyz/api/catan/cancel"
    },
    {
      "method": "GET",
      "href": "/api/catan/board",
      "label": "Forge a balanced board: ?seed=any-words. Deterministic JSON.",
      "url": "https://pointcast.xyz/api/catan/board"
    },
    {
      "method": "GET",
      "href": "/api/catan/seal",
      "label": "Read a sealed table: ?id=. Commitment, rolls so far, secret once revealed.",
      "url": "https://pointcast.xyz/api/catan/seal"
    },
    {
      "method": "POST",
      "href": "/api/catan/seal",
      "label": "Roll or reveal a sealed table: {id, rollKey, action:\"roll\"|\"reveal\"}.",
      "url": "https://pointcast.xyz/api/catan/seal"
    },
    {
      "method": "GET",
      "href": "/api/catan/daily",
      "label": "The Daily Island: today's board, corner vertices, par, leaderboard. ?date= for past days (with the best pair revealed).",
      "url": "https://pointcast.xyz/api/catan/daily"
    },
    {
      "method": "POST",
      "href": "/api/catan/daily",
      "label": "Play the Daily Island: {handle, a, b, kind:\"human\"|\"agent\"}. One entry per handle per day.",
      "url": "https://pointcast.xyz/api/catan/daily"
    },
    {
      "method": "GET",
      "href": "/api/catan/ics",
      "label": "Tables as calendar: ?id= one invite, ?city= or nothing for a subscribable feed.",
      "url": "https://pointcast.xyz/api/catan/ics"
    },
    {
      "method": "GET",
      "href": "/api/catan/games",
      "label": "Game cards logged from the Table Clock: ?id= one, ?table= a table's history, nothing for recent games and top winners.",
      "url": "https://pointcast.xyz/api/catan/games"
    },
    {
      "method": "POST",
      "href": "/api/catan/games",
      "label": "Log a finished game: {players:[{name,color,vp}], winner, target, road?, army?, turns, minutes, rolls, table?, seed?}.",
      "url": "https://pointcast.xyz/api/catan/games"
    },
    {
      "method": "POST",
      "href": "/api/agent/catan-lantern",
      "label": "x402, 0.01 USDC on Etherlink: light a lantern on a hosted table ({table, note?}); pinned and glowing for 7 days, stacks.",
      "url": "https://pointcast.xyz/api/agent/catan-lantern"
    },
    {
      "method": "POST",
      "href": "/api/agent/catan-seal",
      "label": "x402, 0.01 USDC on Etherlink: open a sealed table with a committed 240-roll dice stream.",
      "url": "https://pointcast.xyz/api/agent/catan-seal"
    }
  ],
  "hostTable": {
    "method": "POST",
    "url": "https://pointcast.xyz/api/catan/tables",
    "example": {
      "title": "Tuesday hex night",
      "city": "El Segundo, CA",
      "venue": "library community room",
      "when": "2026-10-13T18:30:00-07:00",
      "seats": 4,
      "edition": "base",
      "pace": "casual",
      "host": "sheepforwheat",
      "note": "Teaching game at 6."
    },
    "editions": [
      "base",
      "5-6 players",
      "seafarers",
      "cities & knights",
      "traders & barbarians",
      "explorers & pirates",
      "starfarers",
      "other"
    ],
    "paces": [
      "new here",
      "casual",
      "sharp"
    ],
    "budget": "3 new tables per IP per 10 minutes; 12 seat changes per IP per 10 minutes"
  },
  "paidAction": {
    "action": "catan-seal",
    "protocol": "x402 v2",
    "network": "eip155:42793 (Etherlink)",
    "price": {
      "amount": "0.01",
      "currency": "USDC",
      "units": "10000",
      "decimals": 6
    },
    "split": "50% house / 50% network",
    "endpoint": "https://pointcast.xyz/api/agent/catan-seal",
    "body": {
      "title": "string ≤60, optional",
      "players": "2-6, default 4",
      "seed": "board seed words, optional"
    },
    "headers": [
      "Idempotency-Key (8-128 chars, required with payment)",
      "Payment-Signature (base64 x402 v2); omit to receive a 402 quote"
    ],
    "returns": "seal {id, commitment, board, url}, rollKey (keep private), receipt, split",
    "rolls": 240,
    "verify": "commitment = sha256(\"pointcast.catan.seal:\" + secret); roll i = sha256(secret + \":\" + i), hex byte pairs, skip bytes >= 252, die = byte % 6 + 1",
    "desk": "https://pointcast.xyz/x402"
  },
  "daily": {
    "what": "The Daily Island: one forged board per Pacific day. Place two settlements on corner ids; score = pips + 2 per distinct resource + harbour bonus. Par is the best pair.",
    "page": "https://catan.pointcast.xyz/daily",
    "read": "https://pointcast.xyz/api/catan/daily",
    "play": {
      "method": "POST",
      "url": "https://pointcast.xyz/api/catan/daily",
      "body": {
        "handle": "my-bot",
        "kind": "agent",
        "a": 18,
        "b": 29
      }
    },
    "rules": [
      "one entry per handle per day",
      "settlements may not be on neighbouring corners",
      "past days reveal the best pair"
    ]
  },
  "clock": {
    "what": "The Table Clock: a game-night companion for one phone at a real table (points, road/army, turn timer, fair dice). Finished games are logged as game cards.",
    "page": "https://catan.pointcast.xyz/clock",
    "games": "https://pointcast.xyz/api/catan/games",
    "card": "https://catan.pointcast.xyz/game?id=<game id>"
  },
  "lantern": {
    "action": "catan-lantern",
    "endpoint": "https://pointcast.xyz/api/agent/catan-lantern",
    "price": {
      "amount": "0.01",
      "currency": "USDC",
      "units": "10000",
      "network": "eip155:42793"
    },
    "body": {
      "table": "<table id>",
      "note": "optional dedication, 80 characters, no links"
    },
    "effect": "pins and highlights the table for 7 days (capped at its start); stacks; payer shown as a short address"
  },
  "calendar": {
    "feed": "https://pointcast.xyz/api/catan/ics",
    "one": "https://pointcast.xyz/api/catan/ics?id=<table id>"
  },
  "flyer": "https://pointcast.xyz/catan/flyer/?id=<table id>",
  "mcp": {
    "server": "https://pointcast.xyz/api/mcp",
    "tools": [
      "catan_tables",
      "catan_board",
      "catan_daily",
      "catan_games"
    ]
  },
  "resources": {
    "lumber": {
      "label": "Lumber",
      "terrain": "Forest",
      "art": "https://pointcast.xyz/images/catan/lumber.jpg"
    },
    "brick": {
      "label": "Brick",
      "terrain": "Hills",
      "art": "https://pointcast.xyz/images/catan/brick.jpg"
    },
    "wool": {
      "label": "Wool",
      "terrain": "Pasture",
      "art": "https://pointcast.xyz/images/catan/wool.jpg"
    },
    "grain": {
      "label": "Grain",
      "terrain": "Fields",
      "art": "https://pointcast.xyz/images/catan/grain.jpg"
    },
    "ore": {
      "label": "Ore",
      "terrain": "Mountains",
      "art": "https://pointcast.xyz/images/catan/ore.jpg"
    },
    "desert": {
      "label": "Desert",
      "terrain": "Desert",
      "art": "https://pointcast.xyz/images/catan/robber.jpg"
    }
  },
  "diceWaysOf36": {
    "2": 1,
    "3": 2,
    "4": 3,
    "5": 4,
    "6": 5,
    "7": 6,
    "8": 5,
    "9": 4,
    "10": 3,
    "11": 2,
    "12": 1
  },
  "sampleBoard": {
    "version": "pointcast.catan/v1",
    "seed": "harbor",
    "hexes": [
      {
        "i": 0,
        "q": 0,
        "r": -2,
        "resource": "grain",
        "number": 12,
        "pips": 1
      },
      {
        "i": 1,
        "q": 1,
        "r": -2,
        "resource": "ore",
        "number": 3,
        "pips": 2
      },
      {
        "i": 2,
        "q": 2,
        "r": -2,
        "resource": "brick",
        "number": 9,
        "pips": 4
      },
      {
        "i": 3,
        "q": -1,
        "r": -1,
        "resource": "lumber",
        "number": 10,
        "pips": 3
      },
      {
        "i": 4,
        "q": 0,
        "r": -1,
        "resource": "wool",
        "number": 11,
        "pips": 2
      },
      {
        "i": 5,
        "q": 1,
        "r": -1,
        "resource": "wool",
        "number": 10,
        "pips": 3
      },
      {
        "i": 6,
        "q": 2,
        "r": -1,
        "resource": "wool",
        "number": 4,
        "pips": 3
      },
      {
        "i": 7,
        "q": -2,
        "r": 0,
        "resource": "lumber",
        "number": 8,
        "pips": 5
      },
      {
        "i": 8,
        "q": -1,
        "r": 0,
        "resource": "grain",
        "number": 5,
        "pips": 4
      },
      {
        "i": 9,
        "q": 0,
        "r": 0,
        "resource": "brick",
        "number": 8,
        "pips": 5
      },
      {
        "i": 10,
        "q": 1,
        "r": 0,
        "resource": "wool",
        "number": 9,
        "pips": 4
      },
      {
        "i": 11,
        "q": 2,
        "r": 0,
        "resource": "brick",
        "number": 6,
        "pips": 5
      },
      {
        "i": 12,
        "q": -2,
        "r": 1,
        "resource": "grain",
        "number": 4,
        "pips": 3
      },
      {
        "i": 13,
        "q": -1,
        "r": 1,
        "resource": "desert",
        "number": null,
        "pips": 0
      },
      {
        "i": 14,
        "q": 0,
        "r": 1,
        "resource": "lumber",
        "number": 11,
        "pips": 2
      },
      {
        "i": 15,
        "q": 1,
        "r": 1,
        "resource": "ore",
        "number": 5,
        "pips": 4
      },
      {
        "i": 16,
        "q": -2,
        "r": 2,
        "resource": "lumber",
        "number": 6,
        "pips": 5
      },
      {
        "i": 17,
        "q": -1,
        "r": 2,
        "resource": "grain",
        "number": 3,
        "pips": 2
      },
      {
        "i": 18,
        "q": 0,
        "r": 2,
        "resource": "ore",
        "number": 2,
        "pips": 1
      }
    ],
    "harbors": [
      {
        "hex": 7,
        "dir": 2,
        "kind": "any",
        "ratio": "3:1"
      },
      {
        "hex": 0,
        "dir": 3,
        "kind": "ore",
        "ratio": "2:1"
      },
      {
        "hex": 1,
        "dir": 1,
        "kind": "any",
        "ratio": "3:1"
      },
      {
        "hex": 2,
        "dir": 0,
        "kind": "grain",
        "ratio": "2:1"
      },
      {
        "hex": 11,
        "dir": 1,
        "kind": "wool",
        "ratio": "2:1"
      },
      {
        "hex": 15,
        "dir": 5,
        "kind": "lumber",
        "ratio": "2:1"
      },
      {
        "hex": 18,
        "dir": 4,
        "kind": "brick",
        "ratio": "2:1"
      },
      {
        "hex": 16,
        "dir": 5,
        "kind": "any",
        "ratio": "3:1"
      },
      {
        "hex": 12,
        "dir": 3,
        "kind": "any",
        "ratio": "3:1"
      }
    ],
    "robber": 13,
    "pipsByResource": {
      "lumber": 15,
      "brick": 14,
      "wool": 12,
      "grain": 10,
      "ore": 7
    },
    "rules": [
      "no touching 6 and 8",
      "no touching twins",
      "base 19-hex bag",
      "harbours shuffled"
    ],
    "attempts": 34,
    "share": "https://catan.pointcast.xyz/?seed=harbor#forge"
  },
  "notes": [
    "Tables meet in public places: game cafés, libraries, taprooms, community rooms. Never post a home address.",
    "Handles only. No phone numbers or emails on the board; put a club link in the link field if you need one.",
    "Hosts get a one-time hostKey to cancel. Keep it.",
    "Unofficial fan site. CATAN is a trademark of CATAN GmbH; this site is not affiliated with or endorsed by CATAN GmbH or its publishers. All art is original."
  ]
}