games.atmosphere.define

rpg.actor

Schema Diff

+24 -269

From

CID
bafyreif5i4hkn7z...
Indexed At
2026-07-18 02:43 UTC
View this version

To

CID
bafyreic2nt3ziqe...
Indexed At
2026-07-18 04:19 UTC
View this version

Compatibility Analysis

Breaking Changes Detected

98 breaking changes, 6 non-breaking changes.

Breaking Changes (98)
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#lexiconRef", src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.nsid", kind: "prop", name: Some("nsid") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#reference", src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.role", kind: "prop", name: Some("role") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#reference", src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.nsid", kind: "prop", name: Some("nsid") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#referenceDisplay", src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.key", kind: "prop", name: Some("key") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#referenceDisplay", src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.path", kind: "prop", name: Some("path") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#referenceDisplay", src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.label", kind: "prop", name: Some("label") }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#field.valueBoolean" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#field.valueInteger" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#field.valueString" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#filter.valueBoolean" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#filter.valueInteger" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#filter.valueString" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.acquire" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.nsid" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.purpose" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.verify" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#recordUse.display" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#recordUse.display:items" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.acquire" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.authority" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.display" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.display:items" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.filters" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.filters:items" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.label" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.nsid" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.path" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.purpose" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.rkey" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.role" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#reference.verify" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.aggregate" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.divideBy" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.format" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.key" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.label" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.maximumFractionDigits" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.multiplyBy" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.path" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.priority" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.unit" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#rule.valueBoolean" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#rule.valueInteger" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define#rule.valueString" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.includes" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.includes:items" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.references" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.references:items" }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.valueBoolean", kind: "prop", name: Some("valueBoolean") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.valueInteger", kind: "prop", name: Some("valueInteger") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.valueString", kind: "prop", name: Some("valueString") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.valueBoolean", kind: "prop", name: Some("valueBoolean") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.valueInteger", kind: "prop", name: Some("valueInteger") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.valueString", kind: "prop", name: Some("valueString") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.acquire", kind: "prop", name: Some("acquire") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.purpose", kind: "prop", name: Some("purpose") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.verify", kind: "prop", name: Some("verify") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#lexiconRef.verify", tgt: "games.atmosphere.define#rule", kind: "ref", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.display", kind: "prop", name: Some("display") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#recordUse.display", tgt: "games.atmosphere.define#recordUse.display:items", kind: "items", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#recordUse.display:items", tgt: "games.atmosphere.define#referenceDisplay", kind: "ref", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.acquire", kind: "prop", name: Some("acquire") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.authority", kind: "prop", name: Some("authority") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.display", kind: "prop", name: Some("display") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.filters", kind: "prop", name: Some("filters") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.label", kind: "prop", name: Some("label") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.path", kind: "prop", name: Some("path") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.purpose", kind: "prop", name: Some("purpose") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.rkey", kind: "prop", name: Some("rkey") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.verify", kind: "prop", name: Some("verify") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference.display", tgt: "games.atmosphere.define#reference.display:items", kind: "items", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference.display:items", tgt: "games.atmosphere.define#referenceDisplay", kind: "ref", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference.filters", tgt: "games.atmosphere.define#reference.filters:items", kind: "items", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference.filters:items", tgt: "games.atmosphere.define#filter", kind: "ref", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#reference.verify", tgt: "games.atmosphere.define#rule", kind: "ref", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.aggregate", kind: "prop", name: Some("aggregate") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.divideBy", kind: "prop", name: Some("divideBy") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.format", kind: "prop", name: Some("format") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.maximumFractionDigits", kind: "prop", name: Some("maximumFractionDigits") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.multiplyBy", kind: "prop", name: Some("multiplyBy") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.priority", kind: "prop", name: Some("priority") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.unit", kind: "prop", name: Some("unit") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.valueBoolean", kind: "prop", name: Some("valueBoolean") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.valueInteger", kind: "prop", name: Some("valueInteger") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.valueString", kind: "prop", name: Some("valueString") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body", tgt: "games.atmosphere.define:body.includes", kind: "prop", name: Some("includes") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body", tgt: "games.atmosphere.define:body.references", kind: "prop", name: Some("references") }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body.includes", tgt: "games.atmosphere.define:body.includes:items", kind: "items", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body.includes:items", tgt: "games.atmosphere.define#lexiconRef", kind: "ref", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body.references", tgt: "games.atmosphere.define:body.references:items", kind: "items", name: None }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body.references:items", tgt: "games.atmosphere.define#reference", kind: "ref", name: None }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#rule.op", sort: "knownValues", old_value: "[\"exists\",\"notExists\",\"isViewer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]", new_value: "[\"exists\",\"notExists\",\"isPlayer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]" }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#field.op", sort: "knownValues", old_value: "[\"exists\",\"notExists\",\"isViewer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]", new_value: "[\"exists\",\"notExists\",\"isPlayer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]" }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#recordUse.role", sort: "knownValues", old_value: "[\"perk\",\"character\",\"cosmetic\",\"bonus\",\"interoperability\",\"stats\",\"activity\",\"leaderboard\",\"save\",\"replay\",\"session\",\"profile\",\"inventory\",\"grant\",\"validation\",\"label\",\"other\"]", new_value: "[\"character\",\"perk\",\"cosmetic\",\"bonus\",\"interop\",\"stats\",\"activity\",\"leaderboard\",\"save\",\"replay\",\"session\",\"profile\",\"inventory\",\"grant\",\"validation\",\"label\",\"other\"]" }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#filter.op", sort: "knownValues", old_value: "[\"exists\",\"notExists\",\"isViewer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]", new_value: "[\"exists\",\"notExists\",\"isPlayer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]" }
Non-Breaking Changes (6)
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#field.value" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#filter.value" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#rule.value" }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.value", kind: "prop", name: Some("value") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.value", kind: "prop", name: Some("value") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.value", kind: "prop", name: Some("value") }

Migration Guidance

Removed Elements

  • RemovedVertex { vertex_id: "games.atmosphere.define#field.valueBoolean" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#field.valueInteger" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#field.valueString" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#filter.valueBoolean" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#filter.valueInteger" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#filter.valueString" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.acquire" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.nsid" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.purpose" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#lexiconRef.verify" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#recordUse.display" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#recordUse.display:items" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.acquire" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.authority" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.display" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.display:items" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.filters" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.filters:items" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.label" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.nsid" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.path" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.purpose" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.rkey" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.role" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#reference.verify" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.aggregate" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.divideBy" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.format" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.key" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.label" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.maximumFractionDigits" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.multiplyBy" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.path" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.priority" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#referenceDisplay.unit" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#rule.valueBoolean" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#rule.valueInteger" }
  • RemovedVertex { vertex_id: "games.atmosphere.define#rule.valueString" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.includes" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.includes:items" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.references" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.references:items" }

Added Elements

  • AddedVertex { vertex_id: "games.atmosphere.define#field.value" }
  • AddedVertex { vertex_id: "games.atmosphere.define#filter.value" }
  • AddedVertex { vertex_id: "games.atmosphere.define#rule.value" }

Constraint Changes

  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#field.op", sort: "knownValues", old_value: "[\"exists\",\"notExists\",\"isViewer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]", new_value: "[\"exists\",\"notExists\",\"isPlayer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]" }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#rule.op", sort: "knownValues", old_value: "[\"exists\",\"notExists\",\"isViewer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]", new_value: "[\"exists\",\"notExists\",\"isPlayer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]" }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#recordUse.role", sort: "knownValues", old_value: "[\"perk\",\"character\",\"cosmetic\",\"bonus\",\"interoperability\",\"stats\",\"activity\",\"leaderboard\",\"save\",\"replay\",\"session\",\"profile\",\"inventory\",\"grant\",\"validation\",\"label\",\"other\"]", new_value: "[\"character\",\"perk\",\"cosmetic\",\"bonus\",\"interop\",\"stats\",\"activity\",\"leaderboard\",\"save\",\"replay\",\"session\",\"profile\",\"inventory\",\"grant\",\"validation\",\"label\",\"other\"]" }
  • ConstraintTightened ConstraintTightened { vertex_id: "games.atmosphere.define#filter.op", sort: "knownValues", old_value: "[\"exists\",\"notExists\",\"isViewer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]", new_value: "[\"exists\",\"notExists\",\"isPlayer\",\"eq\",\"neq\",\"gt\",\"gte\",\"lt\",\"lte\"]" }

Additional Notes

  • Breaking: RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#reference", src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.role", kind: "prop", name: Some("role") }
  • Breaking: RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#reference", src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.nsid", kind: "prop", name: Some("nsid") }
  • Breaking: RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#referenceDisplay", src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.key", kind: "prop", name: Some("key") }
  • Breaking: RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#referenceDisplay", src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.path", kind: "prop", name: Some("path") }
  • Breaking: RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#referenceDisplay", src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.label", kind: "prop", name: Some("label") }
  • Breaking: RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#lexiconRef", src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.nsid", kind: "prop", name: Some("nsid") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.valueBoolean", kind: "prop", name: Some("valueBoolean") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.valueInteger", kind: "prop", name: Some("valueInteger") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.valueString", kind: "prop", name: Some("valueString") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.valueBoolean", kind: "prop", name: Some("valueBoolean") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.valueInteger", kind: "prop", name: Some("valueInteger") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.valueString", kind: "prop", name: Some("valueString") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.acquire", kind: "prop", name: Some("acquire") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.purpose", kind: "prop", name: Some("purpose") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.verify", kind: "prop", name: Some("verify") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#lexiconRef.verify", tgt: "games.atmosphere.define#rule", kind: "ref", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.display", kind: "prop", name: Some("display") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#recordUse.display", tgt: "games.atmosphere.define#recordUse.display:items", kind: "items", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#recordUse.display:items", tgt: "games.atmosphere.define#referenceDisplay", kind: "ref", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.acquire", kind: "prop", name: Some("acquire") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.authority", kind: "prop", name: Some("authority") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.display", kind: "prop", name: Some("display") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.filters", kind: "prop", name: Some("filters") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.label", kind: "prop", name: Some("label") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.path", kind: "prop", name: Some("path") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.purpose", kind: "prop", name: Some("purpose") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.rkey", kind: "prop", name: Some("rkey") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference", tgt: "games.atmosphere.define#reference.verify", kind: "prop", name: Some("verify") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference.display", tgt: "games.atmosphere.define#reference.display:items", kind: "items", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference.display:items", tgt: "games.atmosphere.define#referenceDisplay", kind: "ref", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference.filters", tgt: "games.atmosphere.define#reference.filters:items", kind: "items", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference.filters:items", tgt: "games.atmosphere.define#filter", kind: "ref", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#reference.verify", tgt: "games.atmosphere.define#rule", kind: "ref", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.aggregate", kind: "prop", name: Some("aggregate") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.divideBy", kind: "prop", name: Some("divideBy") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.format", kind: "prop", name: Some("format") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.maximumFractionDigits", kind: "prop", name: Some("maximumFractionDigits") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.multiplyBy", kind: "prop", name: Some("multiplyBy") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.priority", kind: "prop", name: Some("priority") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#referenceDisplay", tgt: "games.atmosphere.define#referenceDisplay.unit", kind: "prop", name: Some("unit") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.valueBoolean", kind: "prop", name: Some("valueBoolean") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.valueInteger", kind: "prop", name: Some("valueInteger") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.valueString", kind: "prop", name: Some("valueString") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body", tgt: "games.atmosphere.define:body.includes", kind: "prop", name: Some("includes") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body", tgt: "games.atmosphere.define:body.references", kind: "prop", name: Some("references") }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body.includes", tgt: "games.atmosphere.define:body.includes:items", kind: "items", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body.includes:items", tgt: "games.atmosphere.define#lexiconRef", kind: "ref", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body.references", tgt: "games.atmosphere.define:body.references:items", kind: "items", name: None }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body.references:items", tgt: "games.atmosphere.define#reference", kind: "ref", name: None }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#field", tgt: "games.atmosphere.define#field.value", kind: "prop", name: Some("value") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#filter", tgt: "games.atmosphere.define#filter.value", kind: "prop", name: Some("value") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.value", kind: "prop", name: Some("value") }
1 1
{
2 2
  "id": "games.atmosphere.define",
3 3
  "defs": {
4 4
    "all": {
5 5
      "type": "object",
6 6
      "required": [
7 7
        "check",
8 8
        "rules"
9 9
      ],
10 10
      "properties": {
11 11
        "check": {
12 12
          "type": "string",
13 13
          "const": "all"
14 14
        },
15 15
        "label": {
16 16
          "type": "string",
17 17
          "maxLength": 120
18 18
        },
19 19
        "rules": {
20 20
          "type": "array",
21 21
          "items": {
22 22
            "ref": "#rule",
23 23
            "type": "ref"
24 24
          },
25 25
          "maxLength": 16,
26 26
          "minLength": 1
27 27
        },
28 28
        "acquire": {
29 29
          "type": "string",
30 30
          "format": "uri"
31 31
        }
32 32
      },
33 33
      "description": "Logical AND. Passes only when every sub-rule passes."
34 34
    },
35 35
    "any": {
36 36
      "type": "object",
37 37
      "required": [
38 38
        "check",
39 39
        "rules"
40 40
      ],
41 41
      "properties": {
42 42
        "check": {
43 43
          "type": "string",
44 44
          "const": "any"
45 45
        },
46 46
        "label": {
47 47
          "type": "string",
48 48
          "maxLength": 120
49 49
        },
50 50
        "rules": {
51 51
          "type": "array",
52 52
          "items": {
53 53
            "ref": "#rule",
54 54
            "type": "ref"
55 55
          },
56 56
          "maxLength": 16,
57 57
          "minLength": 1
58 58
        },
59 59
        "acquire": {
60 60
          "type": "string",
61 61
          "format": "uri"
62 62
        }
63 63
      },
64 64
      "description": "Logical OR. Passes when at least one sub-rule passes, e.g. 'holds a sheet in any of these systems'."
65 65
    },
66 66
    "not": {
67 67
      "type": "object",
68 68
      "required": [
69 69
        "check",
70 70
        "rule"
71 71
      ],
72 72
      "properties": {
73 73
        "rule": {
74 74
          "ref": "#rule",
75 75
          "type": "ref"
76 76
        },
77 77
        "check": {
78 78
          "type": "string",
79 79
          "const": "not"
80 80
        },
81 81
        "label": {
82 82
          "type": "string",
83 83
          "maxLength": 120
84 84
        }
85 85
      },
86 86
      "description": "Logical NOT. Passes only when the sub-rule fails. Use for exclusion gates: 'has not already claimed this reward'."
87 87
    },
88 88
    "main": {
89 89
      "key": "any",
90 90
      "type": "record",
91 91
      "record": {
92 92
        "type": "object",
93 93
        "required": [
94 94
          "name",
95 95
          "url",
96 96
          "publisher",
97 97
          "category",
98 98
          "createdAt"
99 99
        ],
100 100
        "properties": {
101 101
          "url": {
102 102
            "type": "string",
103 103
            "format": "uri",
104 104
            "description": "URL at which the game is played, downloaded, or accessed. This is a launch location, not the record's identity."
105 105
          },
106 106
          "icon": {
107 107
            "type": "blob",
108 108
            "accept": [
109 109
              "image/png",
110 110
              "image/webp"
111 111
            ],
112 112
            "maxSize": 512000,
113 113
            "description": "Square icon for compact display contexts. Recommended 256x256 px."
114 114
          },
115 115
          "name": {
116 116
            "type": "string",
117 117
            "maxLength": 100,
118 118
            "description": "Display name of the experience as shown in portal listings."
119 119
          },
120 120
          "tags": {
121 121
            "type": "array",
122 122
            "items": {
123 123
              "type": "string",
124 124
              "maxLength": 32
125 125
            },
126 126
            "maxLength": 12,
127 127
            "description": "Freeform tags for search and discovery (e.g. 'arcade', 'pixel art', 'multiplayer')."
128 128
          },
129 129
          "uses": {
130 130
            "type": "array",
131 131
            "items": {
132 132
              "ref": "#recordUse",
133 133
              "type": "ref"
134 134
            },
135 135
            "maxLength": 32,
136 136
            "description": "Non-required records this game uses, understands, produces, validates, or wants portals to read. Use requires[] only for hard gates. Use uses[] for everything else: optional gameplay perks, character imports, cosmetics, bonuses, interoperability, stats, saves, activity, sessions, replays, leaderboards, labels, grants, validation, inventory, or profile context. The role and purpose fields explain whether the use is a player-facing benefit, a game-authored record, or a portal-readable display surface."
137 137
          },
138 138
          "cover": {
139 139
            "type": "blob",
140 140
            "accept": [
141 141
              "image/png",
142 142
              "image/jpeg",
143 143
              "image/webp"
144 144
            ],
145 145
            "maxSize": 4000000,
146 146
            "description": "Primary cover image. Portals display this as the card thumbnail. Recommended ratio 16:9."
147 147
          },
148 148
          "media": {
149 149
            "type": "array",
150 150
            "items": {
151 151
              "ref": "#mediaItem",
152 152
              "type": "ref"
153 153
            },
154 154
            "maxLength": 24,
155 155
            "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."
156 156
          },
157 157
          "status": {
158 158
            "type": "string",
159 159
            "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.",
160 160
            "knownValues": [
161 161
              "live",
162 162
              "beta",
163 163
              "coming",
164 164
              "archived"
165 165
            ]
166 166
          },
167 167
          "catalog": {
168 168
            "type": "array",
169 169
            "items": {
170 170
              "ref": "#catalogRef",
171 171
              "type": "ref"
172 172
            },
173 173
            "maxLength": 8,
174 174
            "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."
175 175
          },
176 176
          "tagline": {
177 177
            "type": "string",
178 178
            "maxLength": 200,
179 179
            "description": "One-line summary shown beneath the title in card views."
180 180
          },
181 181
          "category": {
182 182
            "type": "string",
183 183
            "maxLength": 30,
184 184
            "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.",
185 185
            "knownValues": [
186 186
              "browser",
187 187
              "download",
188 188
              "physical",
189 189
              "other"
190 190
            ]
191 191
          },
192 -
          "includes": {
193 -
            "type": "array",
194 -
            "items": {
195 -
              "ref": "#lexiconRef",
196 -
              "type": "ref"
197 -
            },
198 -
            "maxLength": 24,
199 -
            "description": "Deprecated compatibility field. Use uses[] instead. Older records used includes[] for optional player-facing records that change or enrich gameplay when present."
200 -
          },
201 192
          "requires": {
202 193
            "type": "array",
203 194
            "items": {
204 195
              "ref": "#rule",
205 196
              "type": "ref"
206 197
            },
207 198
            "maxLength": 16,
208 199
            "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."
209 200
          },
210 201
          "trailers": {
211 202
            "type": "array",
212 203
            "items": {
213 204
              "ref": "#video",
214 205
              "type": "ref"
215 206
            },
216 207
            "maxLength": 8,
217 208
            "description": "Video trailers and gameplay clips. Hosted externally (YouTube, Vimeo, Twitch) or linked directly so portals can embed or link them."
218 209
          },
219 210
          "createdAt": {
220 211
            "type": "string",
221 212
            "format": "datetime"
222 213
          },
223 214
          "developer": {
224 215
            "ref": "#party",
225 216
            "type": "ref",
226 217
            "description": "The studio or individual who built the experience. Prefer a DID when available so the developer is verifiable on the network."
227 218
          },
228 219
          "legacyIds": {
229 220
            "type": "array",
230 221
            "items": {
231 222
              "type": "string",
232 223
              "maxLength": 80
233 224
            },
234 225
            "maxLength": 12,
235 226
            "description": "Stable identifiers used by older catalogues, score readers, or inventory integrations for this same game. These are compatibility aliases, not canonical identity."
236 227
          },
237 228
          "publisher": {
238 229
            "type": "string",
239 230
            "format": "at-uri",
240 231
            "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."
241 232
          },
242 233
          "updatedAt": {
243 234
            "type": "string",
244 235
            "format": "datetime"
245 236
          },
246 -
          "references": {
247 -
            "type": "array",
248 -
            "items": {
249 -
              "ref": "#reference",
250 -
              "type": "ref"
251 -
            },
252 -
            "maxLength": 24,
253 -
            "description": "Deprecated compatibility field. Use uses[] instead. Older records used references[] for non-gating stat, save, activity, replay, leaderboard, validation, label, grant, profile, or portal-readable context."
254 -
          },
255 237
          "releasedAt": {
256 238
            "type": "string",
257 239
            "format": "datetime",
258 240
            "description": "When this experience became publicly available."
259 241
          },
260 242
          "description": {
261 243
            "type": "string",
262 244
            "maxLength": 2000,
263 245
            "description": "Full description of the experience. Plain text; portals may render line breaks."
264 246
          },
265 247
          "statNamespace": {
266 248
            "type": "string",
267 249
            "maxLength": 80,
268 -
            "description": "Deprecated compatibility hint. Use references[] with role 'activity' or 'stats' to describe player activity records and display metrics."
250 +
            "description": "Deprecated compatibility hint. Use uses[] with role 'activity' or 'stats' to describe player activity records and display metrics."
269 251
          }
270 252
        }
271 253
      },
272 254
      "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."
273 255
    },
274 256
    "rule": {
275 257
      "type": "object",
276 258
      "required": [
277 259
        "check"
278 260
      ],
279 261
      "properties": {
280 262
        "op": {
281 263
          "type": "string",
282 264
          "description": "For field: comparison operator.",
283 265
          "knownValues": [
284 266
            "exists",
285 267
            "notExists",
286 -
            "isViewer",
268 +
            "isPlayer",
287 269
            "eq",
288 270
            "neq",
289 271
            "gt",
290 272
            "gte",
291 273
            "lt",
292 274
            "lte"
293 275
          ]
294 276
        },
295 277
        "nsid": {
296 278
          "type": "string",
297 279
          "format": "nsid",
298 280
          "description": "Collection read by record, field, matches, or vouch."
299 281
        },
300 282
        "rkey": {
301 283
          "type": "string",
302 284
          "maxLength": 50,
303 285
          "description": "For field: record key, default 'self'; 'any' scans the collection."
304 286
        },
305 287
        "rule": {
306 288
          "ref": "#rule",
307 289
          "type": "ref",
308 290
          "description": "For not: nested rule to negate."
309 291
        },
310 292
        "check": {
311 293
          "type": "string",
312 294
          "description": "Rule discriminator. Known values are open for forward compatibility; an unknown value must not pass.",
313 295
          "knownValues": [
314 296
            "record",
315 297
            "field",
316 298
            "matches",
317 299
            "vouch",
318 300
            "all",
319 301
            "any",
320 302
            "not"
321 303
          ]
322 304
        },
323 305
        "field": {
324 306
          "type": "string",
325 307
          "maxLength": 200,
326 308
          "description": "For field: dot-path to test."
327 309
        },
328 310
        "label": {
329 311
          "type": "string",
330 312
          "maxLength": 120,
331 313
          "description": "Human-readable requirement."
332 314
        },
333 315
        "rules": {
334 316
          "type": "array",
335 317
          "items": {
336 318
            "ref": "#rule",
337 319
            "type": "ref"
338 320
          },
339 321
          "maxLength": 16,
340 322
          "minLength": 1,
341 323
          "description": "For all or any: nested rules."
342 324
        },
325 +
        "value": {
326 +
          "type": "unknown",
327 +
          "description": "Comparison value for value-taking operators."
328 +
        },
343 329
        "acquire": {
344 330
          "type": "string",
345 331
          "format": "uri",
346 332
          "description": "URL where a player can fulfil this requirement."
347 333
        },
348 334
        "filters": {
349 335
          "type": "array",
350 336
          "items": {
351 337
            "ref": "#filter",
352 338
            "type": "ref"
353 339
          },
354 340
          "maxLength": 8,
355 341
          "minLength": 1,
356 342
          "description": "For matches or vouch: conditions that must hold on one record."
357 343
        },
358 344
        "authority": {
359 345
          "type": "string",
360 346
          "format": "did",
361 347
          "description": "For vouch: stable DID of the record issuer."
362 -
        },
363 -
        "valueString": {
364 -
          "type": "string",
365 -
          "maxLength": 1000,
366 -
          "description": "String comparison value."
367 -
        },
368 -
        "valueBoolean": {
369 -
          "type": "boolean",
370 -
          "description": "Boolean comparison value."
371 -
        },
372 -
        "valueInteger": {
373 -
          "type": "integer",
374 -
          "description": "Integer comparison value."
375 348
        }
376 349
      },
377 350
      "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."
378 351
    },
379 352
    "field": {
380 353
      "type": "object",
381 354
      "required": [
382 355
        "check",
383 356
        "nsid",
384 357
        "field",
385 358
        "op"
386 359
      ],
387 360
      "properties": {
388 361
        "op": {
389 362
          "type": "string",
390 -
          "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.",
363 +
          "description": "How to test the field. exists/notExists check presence; eq/neq/gt/gte/lt/lte compare to value; isPlayer matches the signed-in player by their account ID (DID) and takes no value.",
391 364
          "knownValues": [
392 365
            "exists",
393 366
            "notExists",
394 -
            "isViewer",
367 +
            "isPlayer",
395 368
            "eq",
396 369
            "neq",
397 370
            "gt",
398 371
            "gte",
399 372
            "lt",
400 373
            "lte"
401 374
          ]
402 375
        },
403 376
        "nsid": {
404 377
          "type": "string",
405 378
          "format": "nsid"
406 379
        },
407 380
        "rkey": {
408 381
          "type": "string",
409 382
          "maxLength": 50,
410 383
          "description": "Record key. Defaults to 'self'. Use 'any' to pass if any record in the collection satisfies the condition."
411 384
        },
412 385
        "check": {
413 386
          "type": "string",
414 387
          "const": "field"
415 388
        },
416 389
        "field": {
417 390
          "type": "string",
418 391
          "maxLength": 200,
419 392
          "description": "Dot-path to the property to evaluate (e.g. 'score.total', 'level'). Array traversal is not supported."
420 393
        },
421 394
        "label": {
422 395
          "type": "string",
423 396
          "maxLength": 120
424 397
        },
398 +
        "value": {
399 +
          "type": "unknown",
400 +
          "description": "Comparison value for value-taking operators. Strings, numbers, and booleans are accepted; numeric operators coerce values to numbers."
401 +
        },
425 402
        "acquire": {
426 403
          "type": "string",
427 404
          "format": "uri"
428 -
        },
429 -
        "valueString": {
430 -
          "type": "string",
431 -
          "maxLength": 1000,
432 -
          "description": "String comparison value. For value-taking operators, set exactly one of valueString, valueInteger, or valueBoolean."
433 -
        },
434 -
        "valueBoolean": {
435 -
          "type": "boolean",
436 -
          "description": "Boolean comparison value."
437 -
        },
438 -
        "valueInteger": {
439 -
          "type": "integer",
440 -
          "description": "Integer comparison value. Use for numeric gt/gte/lt/lte checks."
441 405
        }
442 406
      },
443 407
      "description": "Fetches a record from the player's repository and tests one field. Covers required fields, score thresholds, flags, and enum matches."
444 408
    },
445 409
    "party": {
446 410
      "type": "object",
447 411
      "required": [
448 412
        "name"
449 413
      ],
450 414
      "properties": {
451 415
        "did": {
452 416
          "type": "string",
453 417
          "format": "did",
454 418
          "description": "AT Protocol DID of this entity's account, if they have one. On an atmosphere.games-managed provisional definition, this is also the DID expected to publish the canonical developer-owned definition."
455 419
        },
456 420
        "url": {
457 421
          "type": "string",
458 422
          "format": "uri",
459 423
          "description": "Website for this entity."
460 424
        },
461 425
        "name": {
462 426
          "type": "string",
463 427
          "maxLength": 100,
464 428
          "description": "Display name of the entity."
465 429
        }
466 430
      },
467 431
      "description": "A named entity (developer, publisher, studio) associated with the experience."
468 432
    },
469 433
    "video": {
470 434
      "type": "object",
471 435
      "required": [
472 436
        "title"
473 437
      ],
474 438
      "properties": {
475 439
        "url": {
476 440
          "type": "string",
477 441
          "format": "uri",
478 442
          "description": "Full URL to the video, used when no platform/videoId is given."
479 443
        },
480 444
        "title": {
481 445
          "type": "string",
482 446
          "maxLength": 120,
483 447
          "description": "Label for the clip (e.g. 'Launch Trailer')."
484 448
        },
485 449
        "videoId": {
486 450
          "type": "string",
487 451
          "maxLength": 120,
488 452
          "description": "Platform video id (e.g. a YouTube id). Combined with 'platform' to build an embed."
489 453
        },
490 454
        "platform": {
491 455
          "type": "string",
492 456
          "description": "Where the video lives. 'direct' means the url points straight at a video file or page.",
493 457
          "knownValues": [
494 458
            "youtube",
495 459
            "vimeo",
496 460
            "twitch",
497 461
            "direct"
498 462
          ]
499 463
        },
500 464
        "thumbnail": {
501 465
          "type": "blob",
502 466
          "accept": [
503 467
            "image/png",
504 468
            "image/jpeg",
505 469
            "image/webp"
506 470
          ],
507 471
          "maxSize": 2000000,
508 472
          "description": "Optional still frame shown before the video plays."
509 473
        }
510 474
      },
511 475
      "description": "A trailer or gameplay clip. Provide a platform + videoId (preferred, so portals embed natively) or a direct url."
512 476
    },
513 477
    "vouch": {
514 478
      "type": "object",
515 479
      "required": [
516 480
        "check",
517 481
        "authority",
518 482
        "nsid"
519 483
      ],
520 484
      "properties": {
521 485
        "nsid": {
522 486
          "type": "string",
523 487
          "format": "nsid",
524 488
          "description": "The kind of record to look for in that account's repo (e.g. equipment.rpg.give)."
525 489
        },
526 490
        "check": {
527 491
          "type": "string",
528 492
          "const": "vouch"
529 493
        },
530 494
        "label": {
531 495
          "type": "string",
532 496
          "maxLength": 120
533 497
        },
534 498
        "acquire": {
535 499
          "type": "string",
536 500
          "format": "uri"
537 501
        },
538 502
        "filters": {
539 503
          "type": "array",
540 504
          "items": {
541 505
            "ref": "#filter",
542 506
            "type": "ref"
543 507
          },
544 508
          "maxLength": 8,
545 -
          "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."
509 +
          "description": "Conditions the record must meet, written exactly like a matches rule. Put the 'isPlayer' 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."
546 510
        },
547 511
        "authority": {
548 512
          "type": "string",
549 513
          "format": "did",
550 514
          "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."
551 515
        }
552 516
      },
553 517
      "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.'"
554 518
    },
555 519
    "filter": {
556 520
      "type": "object",
557 521
      "required": [
558 522
        "field",
559 523
        "op"
560 524
      ],
561 525
      "properties": {
562 526
        "op": {
563 527
          "type": "string",
564 -
          "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.",
528 +
          "description": "How to test the field. exists/notExists check presence; eq/neq/gt/gte/lt/lte compare to value; isPlayer matches the signed-in player by their account ID (DID) and takes no value.",
565 529
          "knownValues": [
566 530
            "exists",
567 531
            "notExists",
568 -
            "isViewer",
532 +
            "isPlayer",
569 533
            "eq",
570 534
            "neq",
571 535
            "gt",
572 536
            "gte",
573 537
            "lt",
574 538
            "lte"
575 539
          ]
576 540
        },
577 541
        "field": {
578 542
          "type": "string",
579 543
          "maxLength": 200,
580 544
          "description": "Dot-path to the field."
581 545
        },
582 -
        "valueString": {
583 -
          "type": "string",
584 -
          "maxLength": 1000,
585 -
          "description": "String comparison value. For value-taking operators, set exactly one typed value property."
586 -
        },
587 -
        "valueBoolean": {
588 -
          "type": "boolean",
589 -
          "description": "Boolean comparison value."
590 -
        },
591 -
        "valueInteger": {
592 -
          "type": "integer",
593 -
          "description": "Integer comparison value. Use for numeric gt/gte/lt/lte checks."
546 +
        "value": {
547 +
          "type": "unknown",
548 +
          "description": "Comparison value for value-taking operators. Strings, numbers, and booleans are accepted; numeric operators coerce values to numbers."
594 549
        }
595 550
      },
596 -
      "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."
551 +
      "description": "A single condition on a record's contents, used by matches and vouch. Most operators compare the field to a value. The special 'isPlayer' 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."
597 552
    },
598 553
    "record": {
599 554
      "type": "object",
600 555
      "required": [
601 556
        "check",
602 557
        "nsid"
603 558
      ],
604 559
      "properties": {
605 560
        "nsid": {
606 561
          "type": "string",
607 562
          "format": "nsid",
608 563
          "description": "Collection to check on the player's PDS (e.g. 'actor.rpg.sprite')."
609 564
        },
610 565
        "check": {
611 566
          "type": "string",
612 567
          "const": "record"
613 568
        },
614 569
        "label": {
615 570
          "type": "string",
616 571
          "maxLength": 120,
617 572
          "description": "Human-readable requirement shown when gated (e.g. 'An rpg.actor sprite')."
618 573
        },
619 574
        "acquire": {
620 575
          "type": "string",
621 576
          "format": "uri",
622 577
          "description": "URL to send players who fail, so they can fulfil the requirement."
623 578
        }
624 579
      },
625 580
      "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?'"
626 581
    },
627 582
    "matches": {
628 583
      "type": "object",
629 584
      "required": [
630 585
        "check",
631 586
        "nsid",
632 587
        "filters"
633 588
      ],
634 589
      "properties": {
635 590
        "nsid": {
636 591
          "type": "string",
637 592
          "format": "nsid"
638 593
        },
639 594
        "check": {
640 595
          "type": "string",
641 596
          "const": "matches"
642 597
        },
643 598
        "label": {
644 599
          "type": "string",
645 600
          "maxLength": 120
646 601
        },
647 602
        "acquire": {
648 603
          "type": "string",
649 604
          "format": "uri"
650 605
        },
651 606
        "filters": {
652 607
          "type": "array",
653 608
          "items": {
654 609
            "ref": "#filter",
655 610
            "type": "ref"
656 611
          },
657 612
          "maxLength": 8,
658 613
          "minLength": 1,
659 614
          "description": "All filters must match on the same record (AND semantics within one record)."
660 615
        }
661 616
      },
662 617
      "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'."
663 618
    },
664 619
    "mediaItem": {
665 620
      "type": "object",
666 621
      "required": [
667 622
        "image"
668 623
      ],
669 624
      "properties": {
670 625
        "alt": {
671 626
          "type": "string",
672 627
          "maxLength": 300,
673 628
          "description": "Accessibility caption describing the image."
674 629
        },
675 630
        "type": {
676 631
          "type": "string",
677 632
          "description": "What kind of image this is, so portals can place it (e.g. 'banner' across the top, 'screenshot' in a gallery).",
678 633
          "knownValues": [
679 634
            "screenshot",
680 635
            "banner",
681 636
            "artwork",
682 637
            "poster",
683 638
            "background",
684 639
            "logo",
685 640
            "thumbnail"
686 641
          ]
687 642
        },
688 643
        "image": {
689 644
          "type": "blob",
690 645
          "accept": [
691 646
            "image/png",
692 647
            "image/jpeg",
693 648
            "image/webp",
694 649
            "image/gif"
695 650
          ],
696 651
          "maxSize": 8000000,
697 652
          "description": "The image blob, stored on the developer's PDS."
698 653
        },
699 654
        "width": {
700 655
          "type": "integer",
701 656
          "description": "Pixel width, if known, lets portals reserve layout space before the blob loads."
702 657
        },
703 658
        "height": {
704 659
          "type": "integer",
705 660
          "description": "Pixel height, if known."
706 661
        }
707 662
      },
708 663
      "description": "One image in the experience's media gallery."
709 664
    },
710 665
    "recordUse": {
711 666
      "type": "object",
712 667
      "required": [
713 668
        "role",
714 669
        "nsid"
715 670
      ],
716 671
      "properties": {
717 672
        "nsid": {
718 673
          "type": "string",
719 674
          "format": "nsid",
720 675
          "description": "Collection to read or use."
721 676
        },
722 677
        "path": {
723 678
          "type": "string",
724 679
          "maxLength": 200,
725 680
          "description": "Optional dot-path to the relevant payload within the record, e.g. 'data' inside actor.rpg.stats/clunscannon."
726 681
        },
727 682
        "rkey": {
728 683
          "type": "string",
729 684
          "maxLength": 50,
730 685
          "description": "Record key to read from a player's repo. Defaults to 'self'; use 'any' when a portal should scan the collection."
731 686
        },
732 687
        "role": {
733 688
          "type": "string",
734 -
          "description": "How this record is used. Player-benefit roles such as perk, character, cosmetic, bonus, and interoperability describe optional game behavior. Data roles such as stats, activity, leaderboard, save, replay, session, profile, inventory, grant, validation, and label describe records portals/tools may read or display.",
689 +
          "description": "How this record is used. Optional gameplay roles such as character, perk, cosmetic, bonus, and interop are shown as Optional Records in player-facing directories. Data roles such as stats, activity, leaderboard, save, replay, session, profile, inventory, grant, validation, and label describe records portals/tools may read, summarize, or verify without presenting them as optional perks.",
735 690
          "knownValues": [
736 -
            "perk",
737 691
            "character",
692 +
            "perk",
738 693
            "cosmetic",
739 694
            "bonus",
740 -
            "interoperability",
695 +
            "interop",
741 696
            "stats",
742 697
            "activity",
743 698
            "leaderboard",
744 699
            "save",
745 700
            "replay",
746 701
            "session",
747 702
            "profile",
748 703
            "inventory",
749 704
            "grant",
750 705
            "validation",
751 706
            "label",
752 707
            "other"
753 708
          ]
754 709
        },
755 710
        "label": {
756 711
          "type": "string",
757 712
          "maxLength": 120,
758 713
          "description": "Human label for this use."
759 714
        },
760 715
        "verify": {
761 716
          "ref": "#rule",
762 717
          "type": "ref",
763 -
          "description": "Optional rule that detects, authenticates, or validates this use. For player-benefit roles, it badges whether the benefit is available. For data roles, it badges whether the displayed record is trusted."
718 +
          "description": "Optional rule that detects, authenticates, or validates this use. For player-benefit roles, it badges whether the benefit is available. For data roles, it badges whether the referenced record is trusted."
764 719
        },
765 720
        "acquire": {
766 721
          "type": "string",
767 722
          "format": "uri",
768 723
          "description": "Optional URL where a player can create, obtain, or manage this record."
769 724
        },
770 -
        "display": {
771 -
          "type": "array",
772 -
          "items": {
773 -
            "ref": "#referenceDisplay",
774 -
            "type": "ref"
775 -
          },
776 -
          "maxLength": 8,
777 -
          "description": "Small metrics a portal may render on cards or profiles."
778 -
        },
779 725
        "filters": {
780 726
          "type": "array",
781 727
          "items": {
782 728
            "ref": "#filter",
783 729
            "type": "ref"
784 730
          },
785 731
          "maxLength": 8,
786 732
          "description": "Optional filters used when rkey is 'any' or authority is set. Conditions must match on one record."
787 733
        },
788 734
        "purpose": {
789 735
          "type": "string",
790 736
          "maxLength": 300,
791 737
          "description": "Plain-language reason this record matters. This should say whether it unlocks a benefit, imports player data, stores progress, validates a score, or powers portal display."
792 738
        },
793 739
        "authority": {
794 740
          "type": "string",
795 741
          "format": "did",
796 742
          "description": "When the referenced record lives in a trusted authority repo instead of the player's repo, this DID names that repo."
797 743
        }
798 744
      },
799 -
      "description": "One non-required AT Protocol record relationship for this game. This single shape covers optional gameplay benefits and portal-readable data. Examples: role 'perk' for a Jetpack item that changes play; role 'character' for a sprite the game can import; role 'stats' for a score record portals can display; role 'validation' for an authority record that confirms a stat. Hard gates still belong in requires[]."
800 -
    },
801 -
    "reference": {
802 -
      "type": "object",
803 -
      "required": [
804 -
        "role",
805 -
        "nsid"
806 -
      ],
807 -
      "properties": {
808 -
        "nsid": {
809 -
          "type": "string",
810 -
          "format": "nsid",
811 -
          "description": "Collection to read."
812 -
        },
813 -
        "path": {
814 -
          "type": "string",
815 -
          "maxLength": 200,
816 -
          "description": "Optional dot-path to the relevant payload within the record, e.g. 'clunscannon' inside actor.rpg.stats/self."
817 -
        },
818 -
        "rkey": {
819 -
          "type": "string",
820 -
          "maxLength": 50,
821 -
          "description": "Record key to read from a player's repo. Defaults to 'self'; use 'any' when a portal should scan the collection."
822 -
        },
823 -
        "role": {
824 -
          "type": "string",
825 -
          "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.",
826 -
          "knownValues": [
827 -
            "activity",
828 -
            "stats",
829 -
            "leaderboard",
830 -
            "save",
831 -
            "replay",
832 -
            "session",
833 -
            "profile",
834 -
            "inventory",
835 -
            "grant",
836 -
            "validation",
837 -
            "label",
838 -
            "other"
839 -
          ]
840 -
        },
841 -
        "label": {
842 -
          "type": "string",
843 -
          "maxLength": 120,
844 -
          "description": "Human label for this reference."
845 -
        },
846 -
        "verify": {
847 -
          "ref": "#rule",
848 -
          "type": "ref",
849 -
          "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."
850 -
        },
851 -
        "acquire": {
852 -
          "type": "string",
853 -
          "format": "uri",
854 -
          "description": "Optional URL where a player can create or manage this record."
855 -
        },
856 -
        "display": {
857 -
          "type": "array",
858 -
          "items": {
859 -
            "ref": "#referenceDisplay",
860 -
            "type": "ref"
861 -
          },
862 -
          "maxLength": 8,
863 -
          "description": "Small metrics a portal may render on cards or profiles."
864 -
        },
865 -
        "filters": {
866 -
          "type": "array",
867 -
          "items": {
868 -
            "ref": "#filter",
869 -
            "type": "ref"
870 -
          },
871 -
          "maxLength": 8,
872 -
          "description": "Optional filters used when rkey is 'any' or authority is set. Conditions must match on one record."
873 -
        },
874 -
        "purpose": {
875 -
          "type": "string",
876 -
          "maxLength": 300,
877 -
          "description": "Why a portal or game reads this data."
878 -
        },
879 -
        "authority": {
880 -
          "type": "string",
881 -
          "format": "did",
882 -
          "description": "When the referenced record lives in a trusted authority repo instead of the player's repo, this DID names that repo."
883 -
        }
884 -
      },
885 -
      "description": "Deprecated compatibility shape for references[]. Use recordUse in uses[]. A non-gating record surface relevant to stats, saves, leaderboards, activity, sessions, replays, validation, labels, grants, inventory, profile enrichment, or other portal-readable context."
745 +
      "description": "One non-required AT Protocol record relationship for this game. This single shape covers optional gameplay records and portal-readable data. Use role 'character' when a record identifies or renders the player in-game, role 'perk' when it grants an optional benefit, role 'stats' for progress/score records, role 'activity' for participation records, and role 'profile' for profile/context records. Hard gates still belong in requires[]."
886 746
    },
887 747
    "catalogRef": {
888 748
      "type": "object",
889 749
      "required": [
890 750
        "uri"
891 751
      ],
892 752
      "properties": {
893 753
        "uri": {
894 754
          "type": "string",
895 755
          "format": "at-uri",
896 756
          "description": "AT-URI of the external catalog record (e.g. at://did:web:gamesgamesgamesgames.games/games.gamesgamesgamesgames.game/3mgjih2bzdp2l)."
897 757
        },
898 758
        "name": {
899 759
          "type": "string",
900 760
          "maxLength": 100,
901 761
          "description": "Display name of the referenced entry, so portals can show it without resolving the record."
902 762
        },
903 763
        "borrow": {
904 764
          "type": "array",
905 765
          "items": {
906 766
            "type": "string",
907 767
            "knownValues": [
908 768
              "media",
909 769
              "trailers",
910 770
              "genres",
911 771
              "platforms",
912 772
              "releases",
913 773
              "ratings",
914 774
              "description",
915 775
              "summary"
916 776
            ]
917 777
          },
918 778
          "maxLength": 8,
919 779
          "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."
920 780
        },
921 781
        "source": {
922 782
          "type": "string",
923 783
          "maxLength": 60,
924 784
          "description": "Short label for the catalog this points at (e.g. 'pentaract')."
925 785
        }
926 786
      },
927 787
      "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."
928 -
    },
929 -
    "lexiconRef": {
930 -
      "type": "object",
931 -
      "required": [
932 -
        "nsid"
933 -
      ],
934 -
      "properties": {
935 -
        "nsid": {
936 -
          "type": "string",
937 -
          "format": "nsid"
938 -
        },
939 -
        "verify": {
940 -
          "ref": "#rule",
941 -
          "type": "ref",
942 -
          "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."
943 -
        },
944 -
        "acquire": {
945 -
          "type": "string",
946 -
          "format": "uri",
947 -
          "description": "Optional URL where a player can obtain this record."
948 -
        },
949 -
        "purpose": {
950 -
          "type": "string",
951 -
          "maxLength": 200,
952 -
          "description": "The player-visible benefit this record unlocks or enriches when present. Shown to players."
953 -
        }
954 -
      },
955 -
      "description": "Deprecated compatibility shape for includes[]. Use recordUse in uses[]. An optional player-facing record collection this game can use when present."
956 -
    },
957 -
    "referenceDisplay": {
958 -
      "type": "object",
959 -
      "required": [
960 -
        "key",
961 -
        "label",
962 -
        "path"
963 -
      ],
964 -
      "properties": {
965 -
        "key": {
966 -
          "type": "string",
967 -
          "maxLength": 80,
968 -
          "description": "Stable metric key within this definition, e.g. 'bestDistance'."
969 -
        },
970 -
        "path": {
971 -
          "type": "string",
972 -
          "maxLength": 200,
973 -
          "description": "Dot-path to the value, relative to the reference path when set."
974 -
        },
975 -
        "unit": {
976 -
          "type": "string",
977 -
          "maxLength": 20,
978 -
          "description": "Unit suffix such as 'm', 'XP', or 'pts'."
979 -
        },
980 -
        "label": {
981 -
          "type": "string",
982 -
          "maxLength": 80,
983 -
          "description": "Short label shown before or beside the value."
984 -
        },
985 -
        "format": {
986 -
          "type": "string",
987 -
          "description": "Presentation hint for the value.",
988 -
          "knownValues": [
989 -
            "string",
990 -
            "integer",
991 -
            "number",
992 -
            "distance",
993 -
            "percent",
994 -
            "duration",
995 -
            "datetime",
996 -
            "boolean"
997 -
          ]
998 -
        },
999 -
        "divideBy": {
1000 -
          "type": "integer",
1001 -
          "minimum": 1,
1002 -
          "description": "Integer divisor applied before display, e.g. divideBy 10 for decimeters to meters."
1003 -
        },
1004 -
        "priority": {
1005 -
          "type": "integer",
1006 -
          "description": "Lower numbers display first."
1007 -
        },
1008 -
        "aggregate": {
1009 -
          "type": "string",
1010 -
          "description": "How to reduce multiple records. Defaults to 'first' for fixed rkey records and 'count' for collection scans.",
1011 -
          "knownValues": [
1012 -
            "first",
1013 -
            "count",
1014 -
            "max",
1015 -
            "min",
1016 -
            "sum",
1017 -
            "latest",
1018 -
            "exists"
1019 -
          ]
1020 -
        },
1021 -
        "multiplyBy": {
1022 -
          "type": "integer",
1023 -
          "description": "Integer multiplier applied before display. Use with divideBy for rational scaling."
1024 -
        },
1025 -
        "maximumFractionDigits": {
1026 -
          "type": "integer",
1027 -
          "maximum": 6,
1028 -
          "minimum": 0,
1029 -
          "description": "Decimal precision for numeric display."
1030 -
        }
1031 -
      },
1032 -
      "description": "A declarative display metric derived from a referenced record or collection. Portals may ignore unsupported formats or aggregates."
1033 788
    }
1034 789
  },
1035 790
  "$type": "com.atproto.lexicon.schema",
1036 791
  "lexicon": 1,
1037 792
  "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."
1038 793
}

Compare Other Versions

Lexicon Garden

@