games.atmosphere.define

atmosphere.games

{
  "id": "games.atmosphere.define",
  "defs": {
    "all": {
      "type": "object",
      "required": [
        "check",
        "rules"
      ],
      "properties": {
        "check": {
          "type": "string",
          "const": "all"
        },
        "label": {
          "type": "string",
          "maxLength": 120
        },
        "rules": {
          "type": "array",
          "items": {
            "ref": "#rule",
            "type": "ref"
          },
          "maxLength": 16,
          "minLength": 1
        },
        "acquire": {
          "type": "string",
          "format": "uri"
        }
      },
      "description": "Logical AND. Passes only when every sub-rule passes."
    },
    "any": {
      "type": "object",
      "required": [
        "check",
        "rules"
      ],
      "properties": {
        "check": {
          "type": "string",
          "const": "any"
        },
        "label": {
          "type": "string",
          "maxLength": 120
        },
        "rules": {
          "type": "array",
          "items": {
            "ref": "#rule",
            "type": "ref"
          },
          "maxLength": 16,
          "minLength": 1
        },
        "acquire": {
          "type": "string",
          "format": "uri"
        }
      },
      "description": "Logical OR. Passes when at least one sub-rule passes, e.g. 'holds a sheet in any of these systems'."
    },
    "not": {
      "type": "object",
      "required": [
        "check",
        "rule"
      ],
      "properties": {
        "rule": {
          "ref": "#rule",
          "type": "ref"
        },
        "check": {
          "type": "string",
          "const": "not"
        },
        "label": {
          "type": "string",
          "maxLength": 120
        }
      },
      "description": "Logical NOT. Passes only when the sub-rule fails. Use for exclusion gates: 'has not already claimed this reward'."
    },
    "main": {
      "key": "any",
      "type": "record",
      "record": {
        "type": "object",
        "required": [
          "name",
          "url",
          "publisher",
          "category",
          "createdAt"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL at which the game is played, downloaded, or accessed. This is a launch location, not the record's identity."
          },
          "icon": {
            "type": "blob",
            "accept": [
              "image/png",
              "image/webp"
            ],
            "maxSize": 512000,
            "description": "Square icon for compact display contexts. Recommended 256x256 px."
          },
          "name": {
            "type": "string",
            "maxLength": 100,
            "description": "Display name of the experience as shown in portal listings."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 32
            },
            "maxLength": 12,
            "description": "Freeform tags for search and discovery (e.g. 'arcade', 'pixel art', 'multiplayer')."
          },
          "cover": {
            "type": "blob",
            "accept": [
              "image/png",
              "image/jpeg",
              "image/webp"
            ],
            "maxSize": 4000000,
            "description": "Primary cover image. Portals display this as the card thumbnail. Recommended ratio 16:9."
          },
          "media": {
            "type": "array",
            "items": {
              "ref": "#mediaItem",
              "type": "ref"
            },
            "maxLength": 24,
            "description": "Extended media gallery, screenshots, banners, key art, and posters a portal can show on a detail page. 'cover' and 'icon' above stay the primary card images; this is the deeper set, mirroring the rich galleries dedicated game catalogs keep."
          },
          "status": {
            "type": "string",
            "description": "Current availability. Known values: 'live', 'beta', 'coming' (announced but not yet playable), 'archived' (no longer available). Open set; portals may badge or filter on these.",
            "knownValues": [
              "live",
              "beta",
              "coming",
              "archived"
            ]
          },
          "catalog": {
            "type": "array",
            "items": {
              "ref": "#catalogRef",
              "type": "ref"
            },
            "maxLength": 8,
            "description": "Optional links to records in other game catalogs that describe this same title, most often a Pentaract (games.gamesgamesgamesgames.game) entry. This is how a definition borrows rich metadata a dedicated catalog already maintains, genres, platforms, screenshots, release dates, ratings, instead of duplicating it here. Purely supplementary: evaluation never reads these, and the experience is complete without them. Cooperate, don't re-enter."
          },
          "tagline": {
            "type": "string",
            "maxLength": 200,
            "description": "One-line summary shown beneath the title in card views."
          },
          "category": {
            "type": "string",
            "maxLength": 30,
            "description": "Broad type of experience, used for portal filtering and display. Known values: 'browser' (plays in a web browser), 'download' (downloaded and run locally), 'physical' (tabletop or in-person), 'other'. This is an open set, portals should tolerate values they do not recognise.",
            "knownValues": [
              "browser",
              "download",
              "physical",
              "other"
            ]
          },
          "includes": {
            "type": "array",
            "items": {
              "ref": "#lexiconRef",
              "type": "ref"
            },
            "maxLength": 24,
            "description": "Optional player-facing records that change or enrich the experience when present. Use includes[] when the game itself can do something extra for the player: import a character, unlock a cosmetic, grant a bonus, recognise an item, or enable an interoperability perk. An include may have verify logic so portals can badge whether that optional benefit is available. Includes never gate basic play; put hard gates in requires[]. Do not use includes[] merely to tell portals how to read stats, saves, activity, or leaderboard data; use references[] for that."
          },
          "replaces": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "at-uri"
            },
            "maxLength": 12,
            "description": "Definition records this record intentionally supersedes. Used for ownership claims, rekeys, and mergers without encoding platform-specific migration language. A portal may trust a claim only when the replaced source definition names this record's repo DID as developer.did."
          },
          "requires": {
            "type": "array",
            "items": {
              "ref": "#rule",
              "type": "ref"
            },
            "maxLength": 16,
            "description": "Hard playability requirements. Every rule must pass before the game can be played as declared. Do not put recommendations, bonuses, or merely supported records here. Portals surface failures as actionable prompts using each rule's 'acquire' link."
          },
          "trailers": {
            "type": "array",
            "items": {
              "ref": "#video",
              "type": "ref"
            },
            "maxLength": 8,
            "description": "Video trailers and gameplay clips. Hosted externally (YouTube, Vimeo, Twitch) or linked directly so portals can embed or link them."
          },
          "createdAt": {
            "type": "string",
            "format": "datetime"
          },
          "developer": {
            "ref": "#party",
            "type": "ref",
            "description": "The studio or individual who built the experience. Prefer a DID when available so the developer is verifiable on the network."
          },
          "legacyIds": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 80
            },
            "maxLength": 12,
            "description": "Stable identifiers used by older catalogues, score readers, or inventory integrations for this same game. These are compatibility aliases, not canonical identity."
          },
          "publisher": {
            "type": "string",
            "format": "at-uri",
            "description": "Stable AT-URI identifying the account that publishes and maintains this definition, normally at:// followed by the publishing DID. It must name the same repository that contains this record; portals should reject a mismatch."
          },
          "updatedAt": {
            "type": "string",
            "format": "datetime"
          },
          "references": {
            "type": "array",
            "items": {
              "ref": "#reference",
              "type": "ref"
            },
            "maxLength": 24,
            "description": "Non-gating records that describe where this game's portable data lives and how portals or tools may read it. Use references[] for stats, saves, activity, sessions, replays, leaderboard entries, validation records, labels, grants, profiles, or other context that summarizes play. A reference is a reading recipe, not a player benefit: it may carry display metrics and an optional verify rule for trusted presentation, but it does not by itself say the game uses that record during play. Put hard access rules in requires[] and optional gameplay/perk integrations in includes[]."
          },
          "releasedAt": {
            "type": "string",
            "format": "datetime",
            "description": "When this experience became publicly available."
          },
          "description": {
            "type": "string",
            "maxLength": 2000,
            "description": "Full description of the experience. Plain text; portals may render line breaks."
          },
          "statNamespace": {
            "type": "string",
            "maxLength": 80,
            "description": "Deprecated compatibility hint. Use references[] with role 'activity' or 'stats' to describe player activity records and display metrics."
          },
          "migratedFromAtUri": {
            "type": "string",
            "format": "at-uri",
            "description": "Deprecated compatibility field. Use 'replaces' for clean definition lineage. Exact URI of a previous definition republished into this repository during an ownership claim. Portals must accept this lineage only when the source definition names this repository DID as developer.did; lineage by itself is not proof of ownership."
          }
        }
      },
      "description": "Published to the publisher's own repository, one record per game. Use a stable, readable record key and update that same record in place. The record's at:// URI is its canonical identity; 'url' is an access location and may change. A portal must not merge definitions solely because their URLs match."
    },
    "rule": {
      "type": "object",
      "required": [
        "check"
      ],
      "properties": {
        "op": {
          "type": "string",
          "description": "For field: comparison operator.",
          "knownValues": [
            "exists",
            "notExists",
            "isViewer",
            "eq",
            "neq",
            "gt",
            "gte",
            "lt",
            "lte"
          ]
        },
        "nsid": {
          "type": "string",
          "format": "nsid",
          "description": "Collection read by record, field, matches, or vouch."
        },
        "rkey": {
          "type": "string",
          "maxLength": 50,
          "description": "For field: record key, default 'self'; 'any' scans the collection."
        },
        "rule": {
          "ref": "#rule",
          "type": "ref",
          "description": "For not: nested rule to negate."
        },
        "check": {
          "type": "string",
          "description": "Rule discriminator. Known values are open for forward compatibility; an unknown value must not pass.",
          "knownValues": [
            "record",
            "field",
            "matches",
            "vouch",
            "all",
            "any",
            "not"
          ]
        },
        "field": {
          "type": "string",
          "maxLength": 200,
          "description": "For field: dot-path to test."
        },
        "label": {
          "type": "string",
          "maxLength": 120,
          "description": "Human-readable requirement."
        },
        "rules": {
          "type": "array",
          "items": {
            "ref": "#rule",
            "type": "ref"
          },
          "maxLength": 16,
          "minLength": 1,
          "description": "For all or any: nested rules."
        },
        "acquire": {
          "type": "string",
          "format": "uri",
          "description": "URL where a player can fulfil this requirement."
        },
        "filters": {
          "type": "array",
          "items": {
            "ref": "#filter",
            "type": "ref"
          },
          "maxLength": 8,
          "minLength": 1,
          "description": "For matches or vouch: conditions that must hold on one record."
        },
        "authority": {
          "type": "string",
          "format": "did",
          "description": "For vouch: stable DID of the record issuer."
        },
        "valueString": {
          "type": "string",
          "maxLength": 1000,
          "description": "String comparison value."
        },
        "valueBoolean": {
          "type": "boolean",
          "description": "Boolean comparison value."
        },
        "valueInteger": {
          "type": "integer",
          "description": "Integer comparison value."
        }
      },
      "description": "One recursive playability rule, discriminated by 'check'. Lexicon does not permit a union as a top-level definition, so this object carries the fields used by all seven variants. Evaluators enforce each variant's required fields: record(check,nsid); field(check,nsid,field,op); matches(check,nsid,filters); vouch(check,authority,nsid); all/any(check,rules); not(check,rule). Unknown check values evaluate as unknown, never as pass."
    },
    "field": {
      "type": "object",
      "required": [
        "check",
        "nsid",
        "field",
        "op"
      ],
      "properties": {
        "op": {
          "type": "string",
          "description": "How to test the field. exists/notExists check presence; eq/neq/gt/gte/lt/lte compare to a value; isViewer matches the signed-in player by their account ID (DID) and takes no value.",
          "knownValues": [
            "exists",
            "notExists",
            "isViewer",
            "eq",
            "neq",
            "gt",
            "gte",
            "lt",
            "lte"
          ]
        },
        "nsid": {
          "type": "string",
          "format": "nsid"
        },
        "rkey": {
          "type": "string",
          "maxLength": 50,
          "description": "Record key. Defaults to 'self'. Use 'any' to pass if any record in the collection satisfies the condition."
        },
        "check": {
          "type": "string",
          "const": "field"
        },
        "field": {
          "type": "string",
          "maxLength": 200,
          "description": "Dot-path to the property to evaluate (e.g. 'score.total', 'level'). Array traversal is not supported."
        },
        "label": {
          "type": "string",
          "maxLength": 120
        },
        "acquire": {
          "type": "string",
          "format": "uri"
        },
        "valueString": {
          "type": "string",
          "maxLength": 1000,
          "description": "String comparison value. For value-taking operators, set exactly one of valueString, valueInteger, or valueBoolean."
        },
        "valueBoolean": {
          "type": "boolean",
          "description": "Boolean comparison value."
        },
        "valueInteger": {
          "type": "integer",
          "description": "Integer comparison value. Use for numeric gt/gte/lt/lte checks."
        }
      },
      "description": "Fetches a record from the player's repository and tests one field. Covers required fields, score thresholds, flags, and enum matches."
    },
    "party": {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "did": {
          "type": "string",
          "format": "did",
          "description": "AT Protocol DID of this entity's account, if they have one. On an atmosphere.games-managed provisional definition, this is also the sole DID eligible to claim it by republishing with exact replaces[] lineage."
        },
        "url": {
          "type": "string",
          "format": "uri",
          "description": "Website for this entity."
        },
        "name": {
          "type": "string",
          "maxLength": 100,
          "description": "Display name of the entity."
        }
      },
      "description": "A named entity (developer, publisher, studio) associated with the experience."
    },
    "video": {
      "type": "object",
      "required": [
        "title"
      ],
      "properties": {
        "url": {
          "type": "string",
          "format": "uri",
          "description": "Full URL to the video, used when no platform/videoId is given."
        },
        "title": {
          "type": "string",
          "maxLength": 120,
          "description": "Label for the clip (e.g. 'Launch Trailer')."
        },
        "videoId": {
          "type": "string",
          "maxLength": 120,
          "description": "Platform video id (e.g. a YouTube id). Combined with 'platform' to build an embed."
        },
        "platform": {
          "type": "string",
          "description": "Where the video lives. 'direct' means the url points straight at a video file or page.",
          "knownValues": [
            "youtube",
            "vimeo",
            "twitch",
            "direct"
          ]
        },
        "thumbnail": {
          "type": "blob",
          "accept": [
            "image/png",
            "image/jpeg",
            "image/webp"
          ],
          "maxSize": 2000000,
          "description": "Optional still frame shown before the video plays."
        }
      },
      "description": "A trailer or gameplay clip. Provide a platform + videoId (preferred, so portals embed natively) or a direct url."
    },
    "vouch": {
      "type": "object",
      "required": [
        "check",
        "authority",
        "nsid"
      ],
      "properties": {
        "nsid": {
          "type": "string",
          "format": "nsid",
          "description": "The kind of record to look for in that account's repo (e.g. equipment.rpg.give)."
        },
        "check": {
          "type": "string",
          "const": "vouch"
        },
        "label": {
          "type": "string",
          "maxLength": 120
        },
        "acquire": {
          "type": "string",
          "format": "uri"
        },
        "filters": {
          "type": "array",
          "items": {
            "ref": "#filter",
            "type": "ref"
          },
          "maxLength": 8,
          "description": "Conditions the record must meet, written exactly like a matches rule. Put the 'isViewer' operator on the field that names the player (e.g. recipient) to require the record reference the signed-in player; add value conditions (e.g. item equals jet_pack) to pin a specific grant. With no filters, any record of this kind on the authority's repo passes."
        },
        "authority": {
          "type": "string",
          "format": "did",
          "description": "Stable DID of the account that issues the record (for example an item provider, guild, or tournament organiser). Handles are not accepted because they are mutable. A player can never be their own authority."
        }
      },
      "description": "Passes when a trusted account's repo holds a record that meets the given conditions, optionally one that references the signed-in player. Because the record lives on the issuer's repo, not the player's, it cannot be forged. Use it for item grants, awards, memberships, approvals, licences, or any record one account publishes about another. Example: 'games.protoimsg.app has an equipment.rpg.give whose recipient is this player and whose item is jet_pack.'"
    },
    "filter": {
      "type": "object",
      "required": [
        "field",
        "op"
      ],
      "properties": {
        "op": {
          "type": "string",
          "description": "How to test the field. exists/notExists check presence; eq/neq/gt/gte/lt/lte compare to a value; isViewer matches the signed-in player by their account ID (DID) and takes no value.",
          "knownValues": [
            "exists",
            "notExists",
            "isViewer",
            "eq",
            "neq",
            "gt",
            "gte",
            "lt",
            "lte"
          ]
        },
        "field": {
          "type": "string",
          "maxLength": 200,
          "description": "Dot-path to the field."
        },
        "valueString": {
          "type": "string",
          "maxLength": 1000,
          "description": "String comparison value. For value-taking operators, set exactly one typed value property."
        },
        "valueBoolean": {
          "type": "boolean",
          "description": "Boolean comparison value."
        },
        "valueInteger": {
          "type": "integer",
          "description": "Integer comparison value. Use for numeric gt/gte/lt/lte checks."
        }
      },
      "description": "A single condition on a record's contents, used by matches and vouch. Most operators compare the field to a value. The special 'isViewer' operator takes no value and passes when the field identifies the signed-in player by their account ID (DID). It accepts the DID directly or an at:// URI whose repo is the player, and never matches on a handle, since handles can change. This is how a static definition points at whoever is reading it."
    },
    "record": {
      "type": "object",
      "required": [
        "check",
        "nsid"
      ],
      "properties": {
        "nsid": {
          "type": "string",
          "format": "nsid",
          "description": "Collection to check on the player's PDS (e.g. 'actor.rpg.sprite')."
        },
        "check": {
          "type": "string",
          "const": "record"
        },
        "label": {
          "type": "string",
          "maxLength": 120,
          "description": "Human-readable requirement shown when gated (e.g. 'An rpg.actor sprite')."
        },
        "acquire": {
          "type": "string",
          "format": "uri",
          "description": "URL to send players who fail, so they can fulfil the requirement."
        }
      },
      "description": "Passes if the player's PDS holds at least one record in the given collection. The simplest gate: 'does this person participate in this lexicon at all?'"
    },
    "matches": {
      "type": "object",
      "required": [
        "check",
        "nsid",
        "filters"
      ],
      "properties": {
        "nsid": {
          "type": "string",
          "format": "nsid"
        },
        "check": {
          "type": "string",
          "const": "matches"
        },
        "label": {
          "type": "string",
          "maxLength": 120
        },
        "acquire": {
          "type": "string",
          "format": "uri"
        },
        "filters": {
          "type": "array",
          "items": {
            "ref": "#filter",
            "type": "ref"
          },
          "maxLength": 8,
          "minLength": 1,
          "description": "All filters must match on the same record (AND semantics within one record)."
        }
      },
      "description": "Scans the player's collection and passes if any single record satisfies all filters simultaneously. Use to find a record by content rather than by key, e.g. 'holds item X', 'has membership tier Y'."
    },
    "mediaItem": {
      "type": "object",
      "required": [
        "image"
      ],
      "properties": {
        "alt": {
          "type": "string",
          "maxLength": 300,
          "description": "Accessibility caption describing the image."
        },
        "type": {
          "type": "string",
          "description": "What kind of image this is, so portals can place it (e.g. 'banner' across the top, 'screenshot' in a gallery).",
          "knownValues": [
            "screenshot",
            "banner",
            "artwork",
            "poster",
            "background",
            "logo",
            "thumbnail"
          ]
        },
        "image": {
          "type": "blob",
          "accept": [
            "image/png",
            "image/jpeg",
            "image/webp",
            "image/gif"
          ],
          "maxSize": 8000000,
          "description": "The image blob, stored on the developer's PDS."
        },
        "width": {
          "type": "integer",
          "description": "Pixel width, if known, lets portals reserve layout space before the blob loads."
        },
        "height": {
          "type": "integer",
          "description": "Pixel height, if known."
        }
      },
      "description": "One image in the experience's media gallery."
    },
    "reference": {
      "type": "object",
      "required": [
        "role",
        "nsid"
      ],
      "properties": {
        "nsid": {
          "type": "string",
          "format": "nsid",
          "description": "Collection to read."
        },
        "path": {
          "type": "string",
          "maxLength": 200,
          "description": "Optional dot-path to the relevant payload within the record, e.g. 'clunscannon' inside actor.rpg.stats/self."
        },
        "rkey": {
          "type": "string",
          "maxLength": 50,
          "description": "Record key to read from a player's repo. Defaults to 'self'; use 'any' when a portal should scan the collection."
        },
        "role": {
          "type": "string",
          "description": "Why this collection is relevant. 'stats' and 'leaderboard' are for card summaries; 'activity' for player counts/recent activity; 'validation' for trusted attestations such as actor.rpg.master.",
          "knownValues": [
            "activity",
            "stats",
            "leaderboard",
            "save",
            "replay",
            "session",
            "profile",
            "inventory",
            "grant",
            "validation",
            "label",
            "other"
          ]
        },
        "label": {
          "type": "string",
          "maxLength": 120,
          "description": "Human label for this reference."
        },
        "verify": {
          "ref": "#rule",
          "type": "ref",
          "description": "Optional rule that validates this reference before displaying it as trusted. Example: an actor.rpg.master vouch for a player's actor.rpg.stats system."
        },
        "acquire": {
          "type": "string",
          "format": "uri",
          "description": "Optional URL where a player can create or manage this record."
        },
        "display": {
          "type": "array",
          "items": {
            "ref": "#referenceDisplay",
            "type": "ref"
          },
          "maxLength": 8,
          "description": "Small metrics a portal may render on cards or profiles."
        },
        "filters": {
          "type": "array",
          "items": {
            "ref": "#filter",
            "type": "ref"
          },
          "maxLength": 8,
          "description": "Optional filters used when rkey is 'any' or authority is set. Conditions must match on one record."
        },
        "purpose": {
          "type": "string",
          "maxLength": 300,
          "description": "Why a portal or game reads this data."
        },
        "authority": {
          "type": "string",
          "format": "did",
          "description": "When the referenced record lives in a trusted authority repo instead of the player's repo, this DID names that repo."
        }
      },
      "description": "A non-gating record surface relevant to stats, saves, leaderboards, activity, sessions, replays, validation, labels, grants, inventory, profile enrichment, or other portal-readable context. A reference is a recipe for reading and presenting records. It is not an eligibility rule and not a promise that the game gives the player a benefit for owning that record. Put play gates in requires[] and optional gameplay integrations in includes[]."
    },
    "catalogRef": {
      "type": "object",
      "required": [
        "uri"
      ],
      "properties": {
        "uri": {
          "type": "string",
          "format": "at-uri",
          "description": "AT-URI of the external catalog record (e.g. at://did:web:gamesgamesgamesgames.games/games.gamesgamesgamesgames.game/3mgjih2bzdp2l)."
        },
        "name": {
          "type": "string",
          "maxLength": 100,
          "description": "Display name of the referenced entry, so portals can show it without resolving the record."
        },
        "borrow": {
          "type": "array",
          "items": {
            "type": "string",
            "knownValues": [
              "media",
              "trailers",
              "genres",
              "platforms",
              "releases",
              "ratings",
              "description",
              "summary"
            ]
          },
          "maxLength": 8,
          "description": "Advisory hints naming which parts of the referenced record a portal may display alongside this experience (e.g. pull screenshots and genres from Pentaract rather than duplicating them here). Display guidance only, never affects eligibility."
        },
        "source": {
          "type": "string",
          "maxLength": 60,
          "description": "Short label for the catalog this points at (e.g. 'pentaract')."
        }
      },
      "description": "A pointer to a record in another catalog that already describes this title in depth, most usefully a games.gamesgamesgamesgames.game record on The Pentaract, which carries genres, platforms, release dates, age ratings, and a full media gallery. The definition stays self-contained (eligibility never depends on it); the reference simply lets a portal fetch that richer metadata and show it alongside, so we build on existing game databases instead of re-entering everything."
    },
    "lexiconRef": {
      "type": "object",
      "required": [
        "nsid"
      ],
      "properties": {
        "nsid": {
          "type": "string",
          "format": "nsid"
        },
        "verify": {
          "ref": "#rule",
          "type": "ref",
          "description": "Optional rule that detects or authenticates this feature, typically a player-record match or a vouch in an issuer's separate grant collection. Portals may badge the feature when it passes. It never gates access."
        },
        "acquire": {
          "type": "string",
          "format": "uri",
          "description": "Optional URL where a player can obtain this record."
        },
        "purpose": {
          "type": "string",
          "maxLength": 200,
          "description": "The player-visible benefit this record unlocks or enriches when present. Shown to players."
        }
      },
      "description": "An optional player-facing record collection this game can use when present. This is about gameplay behavior or player benefit, not portal analytics. Example: an rpg.actor sprite can appear in the game, or an equipment item can unlock a bonus. 'verify' may inspect the player's record or an issuer-controlled grant collection so portals can badge whether the benefit is available."
    },
    "referenceDisplay": {
      "type": "object",
      "required": [
        "key",
        "label",
        "path"
      ],
      "properties": {
        "key": {
          "type": "string",
          "maxLength": 80,
          "description": "Stable metric key within this definition, e.g. 'bestDistance'."
        },
        "path": {
          "type": "string",
          "maxLength": 200,
          "description": "Dot-path to the value, relative to the reference path when set."
        },
        "unit": {
          "type": "string",
          "maxLength": 20,
          "description": "Unit suffix such as 'm', 'XP', or 'pts'."
        },
        "label": {
          "type": "string",
          "maxLength": 80,
          "description": "Short label shown before or beside the value."
        },
        "format": {
          "type": "string",
          "description": "Presentation hint for the value.",
          "knownValues": [
            "string",
            "integer",
            "number",
            "distance",
            "percent",
            "duration",
            "datetime",
            "boolean"
          ]
        },
        "divideBy": {
          "type": "integer",
          "minimum": 1,
          "description": "Integer divisor applied before display, e.g. divideBy 10 for decimeters to meters."
        },
        "priority": {
          "type": "integer",
          "description": "Lower numbers display first."
        },
        "aggregate": {
          "type": "string",
          "description": "How to reduce multiple records. Defaults to 'first' for fixed rkey records and 'count' for collection scans.",
          "knownValues": [
            "first",
            "count",
            "max",
            "min",
            "sum",
            "latest",
            "exists"
          ]
        },
        "multiplyBy": {
          "type": "integer",
          "description": "Integer multiplier applied before display. Use with divideBy for rational scaling."
        },
        "maximumFractionDigits": {
          "type": "integer",
          "maximum": 6,
          "minimum": 0,
          "description": "Decimal precision for numeric display."
        }
      },
      "description": "A declarative display metric derived from a referenced record or collection. Portals may ignore unsupported formats or aggregates."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1,
  "description": "An AT Protocol game definition: a publisher's self-contained declaration of a playable experience, its presentation, the records a player must hold to play, and records the game can optionally use. Evaluators resolve requirements through AT Protocol repository reads; no game server or central eligibility database is required."
}

Validate Record

Validate a record against games.atmosphere.define

Validation Options
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:q2fua5gykeuir2hs2gkssygo
CID
bafyreia6xhfyhiqfvvemb3wsoyzvljooysgvh55hrp52uuwsmobrtsil54
Indexed At
2026-07-18 02:21 UTC
AT-URI
at://did:plc:q2fua5gykeuir2hs2gkssygo/com.atproto.lexicon.schema/games.atmosphere.define

Version History (7 versions)

Lexicon Garden

@