games.atmosphere.define

rpg.actor

Schema Diff

+44 -203

From

CID
bafyreia6xhfyhiq...
Indexed At
2026-07-18 02:22 UTC
View this version

To

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

Compatibility Analysis

Breaking Changes Detected

100 breaking changes, 34 non-breaking changes.

Breaking Changes (100)
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "games.atmosphere.define#recordUse", src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.role", kind: "prop", name: Some("role") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "games.atmosphere.define#recordUse", src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.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") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "games.atmosphere.define#lexiconRef", src: "games.atmosphere.define#lexiconRef", tgt: "games.atmosphere.define#lexiconRef.nsid", kind: "prop", name: Some("nsid") }
  • 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#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.migratedFromAtUri" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.references" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.references:items" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.replaces" }
  • RemovedVertex RemovedVertex { vertex_id: "games.atmosphere.define:body.replaces: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#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.migratedFromAtUri", kind: "prop", name: Some("migratedFromAtUri") }
  • 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", tgt: "games.atmosphere.define:body.replaces", kind: "prop", name: Some("replaces") }
  • 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 }
  • RemovedEdge RemovedEdge { src: "games.atmosphere.define:body.replaces", tgt: "games.atmosphere.define:body.replaces:items", kind: "items", name: None }
  • 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#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 (34)
  • 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#recordUse" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.acquire" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.authority" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.filters" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.filters:items" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.label" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.nsid" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.path" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.purpose" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.rkey" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.role" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#recordUse.verify" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define#rule.value" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define:body.uses" }
  • AddedVertex AddedVertex { vertex_id: "games.atmosphere.define:body.uses:items" }
  • 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#recordUse", tgt: "games.atmosphere.define#recordUse.acquire", kind: "prop", name: Some("acquire") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.authority", kind: "prop", name: Some("authority") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.filters", kind: "prop", name: Some("filters") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.label", kind: "prop", name: Some("label") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.path", kind: "prop", name: Some("path") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.purpose", kind: "prop", name: Some("purpose") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.rkey", kind: "prop", name: Some("rkey") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.verify", kind: "prop", name: Some("verify") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse.filters", tgt: "games.atmosphere.define#recordUse.filters:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse.filters:items", tgt: "games.atmosphere.define#filter", kind: "ref", name: None }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#recordUse.verify", tgt: "games.atmosphere.define#rule", kind: "ref", name: None }
  • AddedEdge AddedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.value", kind: "prop", name: Some("value") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define:body", tgt: "games.atmosphere.define:body.uses", kind: "prop", name: Some("uses") }
  • AddedEdge AddedEdge { src: "games.atmosphere.define:body.uses", tgt: "games.atmosphere.define:body.uses:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "games.atmosphere.define:body.uses:items", tgt: "games.atmosphere.define#recordUse", kind: "ref", name: None }

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#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.migratedFromAtUri" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.references" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.references:items" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.replaces" }
  • RemovedVertex { vertex_id: "games.atmosphere.define:body.replaces: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#recordUse" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.acquire" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.authority" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.filters" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.filters:items" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.label" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.nsid" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.path" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.purpose" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.rkey" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.role" }
  • AddedVertex { vertex_id: "games.atmosphere.define#recordUse.verify" }
  • AddedVertex { vertex_id: "games.atmosphere.define#rule.value" }
  • AddedVertex { vertex_id: "games.atmosphere.define:body.uses" }
  • AddedVertex { vertex_id: "games.atmosphere.define:body.uses:items" }

Constraint Changes

  • 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\"]" }
  • 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\"]" }

Additional Notes

  • Breaking: RequiredEdgeAdded { vertex_id: "games.atmosphere.define#recordUse", src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.role", kind: "prop", name: Some("role") }
  • Breaking: RequiredEdgeAdded { vertex_id: "games.atmosphere.define#recordUse", src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.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: 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: 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#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.migratedFromAtUri", kind: "prop", name: Some("migratedFromAtUri") }
  • 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", tgt: "games.atmosphere.define:body.replaces", kind: "prop", name: Some("replaces") }
  • 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 }
  • Breaking: RemovedEdge { src: "games.atmosphere.define:body.replaces", tgt: "games.atmosphere.define:body.replaces:items", kind: "items", 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#recordUse", tgt: "games.atmosphere.define#recordUse.acquire", kind: "prop", name: Some("acquire") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.authority", kind: "prop", name: Some("authority") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.filters", kind: "prop", name: Some("filters") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.label", kind: "prop", name: Some("label") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.path", kind: "prop", name: Some("path") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.purpose", kind: "prop", name: Some("purpose") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.rkey", kind: "prop", name: Some("rkey") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse", tgt: "games.atmosphere.define#recordUse.verify", kind: "prop", name: Some("verify") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse.filters", tgt: "games.atmosphere.define#recordUse.filters:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse.filters:items", tgt: "games.atmosphere.define#filter", kind: "ref", name: None }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#recordUse.verify", tgt: "games.atmosphere.define#rule", kind: "ref", name: None }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define#rule", tgt: "games.atmosphere.define#rule.value", kind: "prop", name: Some("value") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define:body", tgt: "games.atmosphere.define:body.uses", kind: "prop", name: Some("uses") }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define:body.uses", tgt: "games.atmosphere.define:body.uses:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "games.atmosphere.define:body.uses:items", tgt: "games.atmosphere.define#recordUse", kind: "ref", name: None }
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 +
          "uses": {
130 +
            "type": "array",
131 +
            "items": {
132 +
              "ref": "#recordUse",
133 +
              "type": "ref"
134 +
            },
135 +
            "maxLength": 32,
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 +
          },
129 138
          "cover": {
130 139
            "type": "blob",
131 140
            "accept": [
132 141
              "image/png",
133 142
              "image/jpeg",
134 143
              "image/webp"
135 144
            ],
136 145
            "maxSize": 4000000,
137 146
            "description": "Primary cover image. Portals display this as the card thumbnail. Recommended ratio 16:9."
138 147
          },
139 148
          "media": {
140 149
            "type": "array",
141 150
            "items": {
142 151
              "ref": "#mediaItem",
143 152
              "type": "ref"
144 153
            },
145 154
            "maxLength": 24,
146 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."
147 156
          },
148 157
          "status": {
149 158
            "type": "string",
150 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.",
151 160
            "knownValues": [
152 161
              "live",
153 162
              "beta",
154 163
              "coming",
155 164
              "archived"
156 165
            ]
157 166
          },
158 167
          "catalog": {
159 168
            "type": "array",
160 169
            "items": {
161 170
              "ref": "#catalogRef",
162 171
              "type": "ref"
163 172
            },
164 173
            "maxLength": 8,
165 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."
166 175
          },
167 176
          "tagline": {
168 177
            "type": "string",
169 178
            "maxLength": 200,
170 179
            "description": "One-line summary shown beneath the title in card views."
171 180
          },
172 181
          "category": {
173 182
            "type": "string",
174 183
            "maxLength": 30,
175 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.",
176 185
            "knownValues": [
177 186
              "browser",
178 187
              "download",
179 188
              "physical",
180 189
              "other"
181 190
            ]
182 191
          },
183 -
          "includes": {
184 -
            "type": "array",
185 -
            "items": {
186 -
              "ref": "#lexiconRef",
187 -
              "type": "ref"
188 -
            },
189 -
            "maxLength": 24,
190 -
            "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."
191 -
          },
192 -
          "replaces": {
193 -
            "type": "array",
194 -
            "items": {
195 -
              "type": "string",
196 -
              "format": "at-uri"
197 -
            },
198 -
            "maxLength": 12,
199 -
            "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."
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 -
          },
246 -
          "references": {
247 -
            "type": "array",
248 -
            "items": {
249 -
              "ref": "#reference",
250 -
              "type": "ref"
251 -
            },
252 -
            "maxLength": 24,
253 -
            "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[]."
254 236
          },
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."
269 -
          },
270 -
          "migratedFromAtUri": {
271 -
            "type": "string",
272 -
            "format": "at-uri",
273 -
            "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."
250 +
            "description": "Deprecated compatibility hint. Use uses[] with role 'activity' or 'stats' to describe player activity records and display metrics."
274 251
          }
275 252
        }
276 253
      },
277 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."
278 255
    },
279 256
    "rule": {
280 257
      "type": "object",
281 258
      "required": [
282 259
        "check"
283 260
      ],
284 261
      "properties": {
285 262
        "op": {
286 263
          "type": "string",
287 264
          "description": "For field: comparison operator.",
288 265
          "knownValues": [
289 266
            "exists",
290 267
            "notExists",
291 -
            "isViewer",
268 +
            "isPlayer",
292 269
            "eq",
293 270
            "neq",
294 271
            "gt",
295 272
            "gte",
296 273
            "lt",
297 274
            "lte"
298 275
          ]
299 276
        },
300 277
        "nsid": {
301 278
          "type": "string",
302 279
          "format": "nsid",
303 280
          "description": "Collection read by record, field, matches, or vouch."
304 281
        },
305 282
        "rkey": {
306 283
          "type": "string",
307 284
          "maxLength": 50,
308 285
          "description": "For field: record key, default 'self'; 'any' scans the collection."
309 286
        },
310 287
        "rule": {
311 288
          "ref": "#rule",
312 289
          "type": "ref",
313 290
          "description": "For not: nested rule to negate."
314 291
        },
315 292
        "check": {
316 293
          "type": "string",
317 294
          "description": "Rule discriminator. Known values are open for forward compatibility; an unknown value must not pass.",
318 295
          "knownValues": [
319 296
            "record",
320 297
            "field",
321 298
            "matches",
322 299
            "vouch",
323 300
            "all",
324 301
            "any",
325 302
            "not"
326 303
          ]
327 304
        },
328 305
        "field": {
329 306
          "type": "string",
330 307
          "maxLength": 200,
331 308
          "description": "For field: dot-path to test."
332 309
        },
333 310
        "label": {
334 311
          "type": "string",
335 312
          "maxLength": 120,
336 313
          "description": "Human-readable requirement."
337 314
        },
338 315
        "rules": {
339 316
          "type": "array",
340 317
          "items": {
341 318
            "ref": "#rule",
342 319
            "type": "ref"
343 320
          },
344 321
          "maxLength": 16,
345 322
          "minLength": 1,
346 323
          "description": "For all or any: nested rules."
347 324
        },
325 +
        "value": {
326 +
          "type": "unknown",
327 +
          "description": "Comparison value for value-taking operators."
328 +
        },
348 329
        "acquire": {
349 330
          "type": "string",
350 331
          "format": "uri",
351 332
          "description": "URL where a player can fulfil this requirement."
352 333
        },
353 334
        "filters": {
354 335
          "type": "array",
355 336
          "items": {
356 337
            "ref": "#filter",
357 338
            "type": "ref"
358 339
          },
359 340
          "maxLength": 8,
360 341
          "minLength": 1,
361 342
          "description": "For matches or vouch: conditions that must hold on one record."
362 343
        },
363 344
        "authority": {
364 345
          "type": "string",
365 346
          "format": "did",
366 347
          "description": "For vouch: stable DID of the record issuer."
367 -
        },
368 -
        "valueString": {
369 -
          "type": "string",
370 -
          "maxLength": 1000,
371 -
          "description": "String comparison value."
372 -
        },
373 -
        "valueBoolean": {
374 -
          "type": "boolean",
375 -
          "description": "Boolean comparison value."
376 -
        },
377 -
        "valueInteger": {
378 -
          "type": "integer",
379 -
          "description": "Integer comparison value."
380 348
        }
381 349
      },
382 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."
383 351
    },
384 352
    "field": {
385 353
      "type": "object",
386 354
      "required": [
387 355
        "check",
388 356
        "nsid",
389 357
        "field",
390 358
        "op"
391 359
      ],
392 360
      "properties": {
393 361
        "op": {
394 362
          "type": "string",
395 -
          "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.",
396 364
          "knownValues": [
397 365
            "exists",
398 366
            "notExists",
399 -
            "isViewer",
367 +
            "isPlayer",
400 368
            "eq",
401 369
            "neq",
402 370
            "gt",
403 371
            "gte",
404 372
            "lt",
405 373
            "lte"
406 374
          ]
407 375
        },
408 376
        "nsid": {
409 377
          "type": "string",
410 378
          "format": "nsid"
411 379
        },
412 380
        "rkey": {
413 381
          "type": "string",
414 382
          "maxLength": 50,
415 383
          "description": "Record key. Defaults to 'self'. Use 'any' to pass if any record in the collection satisfies the condition."
416 384
        },
417 385
        "check": {
418 386
          "type": "string",
419 387
          "const": "field"
420 388
        },
421 389
        "field": {
422 390
          "type": "string",
423 391
          "maxLength": 200,
424 392
          "description": "Dot-path to the property to evaluate (e.g. 'score.total', 'level'). Array traversal is not supported."
425 393
        },
426 394
        "label": {
427 395
          "type": "string",
428 396
          "maxLength": 120
429 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 +
        },
430 402
        "acquire": {
431 403
          "type": "string",
432 404
          "format": "uri"
433 -
        },
434 -
        "valueString": {
435 -
          "type": "string",
436 -
          "maxLength": 1000,
437 -
          "description": "String comparison value. For value-taking operators, set exactly one of valueString, valueInteger, or valueBoolean."
438 -
        },
439 -
        "valueBoolean": {
440 -
          "type": "boolean",
441 -
          "description": "Boolean comparison value."
442 -
        },
443 -
        "valueInteger": {
444 -
          "type": "integer",
445 -
          "description": "Integer comparison value. Use for numeric gt/gte/lt/lte checks."
446 405
        }
447 406
      },
448 407
      "description": "Fetches a record from the player's repository and tests one field. Covers required fields, score thresholds, flags, and enum matches."
449 408
    },
450 409
    "party": {
451 410
      "type": "object",
452 411
      "required": [
453 412
        "name"
454 413
      ],
455 414
      "properties": {
456 415
        "did": {
457 416
          "type": "string",
458 417
          "format": "did",
459 -
          "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."
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."
460 419
        },
461 420
        "url": {
462 421
          "type": "string",
463 422
          "format": "uri",
464 423
          "description": "Website for this entity."
465 424
        },
466 425
        "name": {
467 426
          "type": "string",
468 427
          "maxLength": 100,
469 428
          "description": "Display name of the entity."
470 429
        }
471 430
      },
472 431
      "description": "A named entity (developer, publisher, studio) associated with the experience."
473 432
    },
474 433
    "video": {
475 434
      "type": "object",
476 435
      "required": [
477 436
        "title"
478 437
      ],
479 438
      "properties": {
480 439
        "url": {
481 440
          "type": "string",
482 441
          "format": "uri",
483 442
          "description": "Full URL to the video, used when no platform/videoId is given."
484 443
        },
485 444
        "title": {
486 445
          "type": "string",
487 446
          "maxLength": 120,
488 447
          "description": "Label for the clip (e.g. 'Launch Trailer')."
489 448
        },
490 449
        "videoId": {
491 450
          "type": "string",
492 451
          "maxLength": 120,
493 452
          "description": "Platform video id (e.g. a YouTube id). Combined with 'platform' to build an embed."
494 453
        },
495 454
        "platform": {
496 455
          "type": "string",
497 456
          "description": "Where the video lives. 'direct' means the url points straight at a video file or page.",
498 457
          "knownValues": [
499 458
            "youtube",
500 459
            "vimeo",
501 460
            "twitch",
502 461
            "direct"
503 462
          ]
504 463
        },
505 464
        "thumbnail": {
506 465
          "type": "blob",
507 466
          "accept": [
508 467
            "image/png",
509 468
            "image/jpeg",
510 469
            "image/webp"
511 470
          ],
512 471
          "maxSize": 2000000,
513 472
          "description": "Optional still frame shown before the video plays."
514 473
        }
515 474
      },
516 475
      "description": "A trailer or gameplay clip. Provide a platform + videoId (preferred, so portals embed natively) or a direct url."
517 476
    },
518 477
    "vouch": {
519 478
      "type": "object",
520 479
      "required": [
521 480
        "check",
522 481
        "authority",
523 482
        "nsid"
524 483
      ],
525 484
      "properties": {
526 485
        "nsid": {
527 486
          "type": "string",
528 487
          "format": "nsid",
529 488
          "description": "The kind of record to look for in that account's repo (e.g. equipment.rpg.give)."
530 489
        },
531 490
        "check": {
532 491
          "type": "string",
533 492
          "const": "vouch"
534 493
        },
535 494
        "label": {
536 495
          "type": "string",
537 496
          "maxLength": 120
538 497
        },
539 498
        "acquire": {
540 499
          "type": "string",
541 500
          "format": "uri"
542 501
        },
543 502
        "filters": {
544 503
          "type": "array",
545 504
          "items": {
546 505
            "ref": "#filter",
547 506
            "type": "ref"
548 507
          },
549 508
          "maxLength": 8,
550 -
          "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."
551 510
        },
552 511
        "authority": {
553 512
          "type": "string",
554 513
          "format": "did",
555 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."
556 515
        }
557 516
      },
558 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.'"
559 518
    },
560 519
    "filter": {
561 520
      "type": "object",
562 521
      "required": [
563 522
        "field",
564 523
        "op"
565 524
      ],
566 525
      "properties": {
567 526
        "op": {
568 527
          "type": "string",
569 -
          "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.",
570 529
          "knownValues": [
571 530
            "exists",
572 531
            "notExists",
573 -
            "isViewer",
532 +
            "isPlayer",
574 533
            "eq",
575 534
            "neq",
576 535
            "gt",
577 536
            "gte",
578 537
            "lt",
579 538
            "lte"
580 539
          ]
581 540
        },
582 541
        "field": {
583 542
          "type": "string",
584 543
          "maxLength": 200,
585 544
          "description": "Dot-path to the field."
586 545
        },
587 -
        "valueString": {
588 -
          "type": "string",
589 -
          "maxLength": 1000,
590 -
          "description": "String comparison value. For value-taking operators, set exactly one typed value property."
591 -
        },
592 -
        "valueBoolean": {
593 -
          "type": "boolean",
594 -
          "description": "Boolean comparison value."
595 -
        },
596 -
        "valueInteger": {
597 -
          "type": "integer",
598 -
          "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."
599 549
        }
600 550
      },
601 -
      "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."
602 552
    },
603 553
    "record": {
604 554
      "type": "object",
605 555
      "required": [
606 556
        "check",
607 557
        "nsid"
608 558
      ],
609 559
      "properties": {
610 560
        "nsid": {
611 561
          "type": "string",
612 562
          "format": "nsid",
613 563
          "description": "Collection to check on the player's PDS (e.g. 'actor.rpg.sprite')."
614 564
        },
615 565
        "check": {
616 566
          "type": "string",
617 567
          "const": "record"
618 568
        },
619 569
        "label": {
620 570
          "type": "string",
621 571
          "maxLength": 120,
622 572
          "description": "Human-readable requirement shown when gated (e.g. 'An rpg.actor sprite')."
623 573
        },
624 574
        "acquire": {
625 575
          "type": "string",
626 576
          "format": "uri",
627 577
          "description": "URL to send players who fail, so they can fulfil the requirement."
628 578
        }
629 579
      },
630 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?'"
631 581
    },
632 582
    "matches": {
633 583
      "type": "object",
634 584
      "required": [
635 585
        "check",
636 586
        "nsid",
637 587
        "filters"
638 588
      ],
639 589
      "properties": {
640 590
        "nsid": {
641 591
          "type": "string",
642 592
          "format": "nsid"
643 593
        },
644 594
        "check": {
645 595
          "type": "string",
646 596
          "const": "matches"
647 597
        },
648 598
        "label": {
649 599
          "type": "string",
650 600
          "maxLength": 120
651 601
        },
652 602
        "acquire": {
653 603
          "type": "string",
654 604
          "format": "uri"
655 605
        },
656 606
        "filters": {
657 607
          "type": "array",
658 608
          "items": {
659 609
            "ref": "#filter",
660 610
            "type": "ref"
661 611
          },
662 612
          "maxLength": 8,
663 613
          "minLength": 1,
664 614
          "description": "All filters must match on the same record (AND semantics within one record)."
665 615
        }
666 616
      },
667 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'."
668 618
    },
669 619
    "mediaItem": {
670 620
      "type": "object",
671 621
      "required": [
672 622
        "image"
673 623
      ],
674 624
      "properties": {
675 625
        "alt": {
676 626
          "type": "string",
677 627
          "maxLength": 300,
678 628
          "description": "Accessibility caption describing the image."
679 629
        },
680 630
        "type": {
681 631
          "type": "string",
682 632
          "description": "What kind of image this is, so portals can place it (e.g. 'banner' across the top, 'screenshot' in a gallery).",
683 633
          "knownValues": [
684 634
            "screenshot",
685 635
            "banner",
686 636
            "artwork",
687 637
            "poster",
688 638
            "background",
689 639
            "logo",
690 640
            "thumbnail"
691 641
          ]
692 642
        },
693 643
        "image": {
694 644
          "type": "blob",
695 645
          "accept": [
696 646
            "image/png",
697 647
            "image/jpeg",
698 648
            "image/webp",
699 649
            "image/gif"
700 650
          ],
701 651
          "maxSize": 8000000,
702 652
          "description": "The image blob, stored on the developer's PDS."
703 653
        },
704 654
        "width": {
705 655
          "type": "integer",
706 656
          "description": "Pixel width, if known, lets portals reserve layout space before the blob loads."
707 657
        },
708 658
        "height": {
709 659
          "type": "integer",
710 660
          "description": "Pixel height, if known."
711 661
        }
712 662
      },
713 663
      "description": "One image in the experience's media gallery."
714 664
    },
715 -
    "reference": {
665 +
    "recordUse": {
716 666
      "type": "object",
717 667
      "required": [
718 668
        "role",
719 669
        "nsid"
720 670
      ],
721 671
      "properties": {
722 672
        "nsid": {
723 673
          "type": "string",
724 674
          "format": "nsid",
725 -
          "description": "Collection to read."
675 +
          "description": "Collection to read or use."
726 676
        },
727 677
        "path": {
728 678
          "type": "string",
729 679
          "maxLength": 200,
730 -
          "description": "Optional dot-path to the relevant payload within the record, e.g. 'clunscannon' inside actor.rpg.stats/self."
680 +
          "description": "Optional dot-path to the relevant payload within the record, e.g. 'data' inside actor.rpg.stats/clunscannon."
731 681
        },
732 682
        "rkey": {
733 683
          "type": "string",
734 684
          "maxLength": 50,
735 685
          "description": "Record key to read from a player's repo. Defaults to 'self'; use 'any' when a portal should scan the collection."
736 686
        },
737 687
        "role": {
738 688
          "type": "string",
739 -
          "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.",
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.",
740 690
          "knownValues": [
741 -
            "activity",
691 +
            "character",
692 +
            "perk",
693 +
            "cosmetic",
694 +
            "bonus",
695 +
            "interop",
742 696
            "stats",
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 -
          "description": "Human label for this reference."
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 validates this reference before displaying it as trusted. Example: an actor.rpg.master vouch for a player's actor.rpg.stats system."
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 -
          "description": "Optional URL where a player can create or manage this record."
769 -
        },
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."
723 +
          "description": "Optional URL where a player can create, obtain, or manage this record."
778 724
        },
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 -
          "description": "Why a portal or game reads this data."
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": "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[]."
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[]."
800 746
    },
801 747
    "catalogRef": {
802 748
      "type": "object",
803 749
      "required": [
804 750
        "uri"
805 751
      ],
806 752
      "properties": {
807 753
        "uri": {
808 754
          "type": "string",
809 755
          "format": "at-uri",
810 756
          "description": "AT-URI of the external catalog record (e.g. at://did:web:gamesgamesgamesgames.games/games.gamesgamesgamesgames.game/3mgjih2bzdp2l)."
811 757
        },
812 758
        "name": {
813 759
          "type": "string",
814 760
          "maxLength": 100,
815 761
          "description": "Display name of the referenced entry, so portals can show it without resolving the record."
816 762
        },
817 763
        "borrow": {
818 764
          "type": "array",
819 765
          "items": {
820 766
            "type": "string",
821 767
            "knownValues": [
822 768
              "media",
823 769
              "trailers",
824 770
              "genres",
825 771
              "platforms",
826 772
              "releases",
827 773
              "ratings",
828 774
              "description",
829 775
              "summary"
830 776
            ]
831 777
          },
832 778
          "maxLength": 8,
833 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."
834 780
        },
835 781
        "source": {
836 782
          "type": "string",
837 783
          "maxLength": 60,
838 784
          "description": "Short label for the catalog this points at (e.g. 'pentaract')."
839 785
        }
840 786
      },
841 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."
842 -
    },
843 -
    "lexiconRef": {
844 -
      "type": "object",
845 -
      "required": [
846 -
        "nsid"
847 -
      ],
848 -
      "properties": {
849 -
        "nsid": {
850 -
          "type": "string",
851 -
          "format": "nsid"
852 -
        },
853 -
        "verify": {
854 -
          "ref": "#rule",
855 -
          "type": "ref",
856 -
          "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."
857 -
        },
858 -
        "acquire": {
859 -
          "type": "string",
860 -
          "format": "uri",
861 -
          "description": "Optional URL where a player can obtain this record."
862 -
        },
863 -
        "purpose": {
864 -
          "type": "string",
865 -
          "maxLength": 200,
866 -
          "description": "The player-visible benefit this record unlocks or enriches when present. Shown to players."
867 -
        }
868 -
      },
869 -
      "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."
870 -
    },
871 -
    "referenceDisplay": {
872 -
      "type": "object",
873 -
      "required": [
874 -
        "key",
875 -
        "label",
876 -
        "path"
877 -
      ],
878 -
      "properties": {
879 -
        "key": {
880 -
          "type": "string",
881 -
          "maxLength": 80,
882 -
          "description": "Stable metric key within this definition, e.g. 'bestDistance'."
883 -
        },
884 -
        "path": {
885 -
          "type": "string",
886 -
          "maxLength": 200,
887 -
          "description": "Dot-path to the value, relative to the reference path when set."
888 -
        },
889 -
        "unit": {
890 -
          "type": "string",
891 -
          "maxLength": 20,
892 -
          "description": "Unit suffix such as 'm', 'XP', or 'pts'."
893 -
        },
894 -
        "label": {
895 -
          "type": "string",
896 -
          "maxLength": 80,
897 -
          "description": "Short label shown before or beside the value."
898 -
        },
899 -
        "format": {
900 -
          "type": "string",
901 -
          "description": "Presentation hint for the value.",
902 -
          "knownValues": [
903 -
            "string",
904 -
            "integer",
905 -
            "number",
906 -
            "distance",
907 -
            "percent",
908 -
            "duration",
909 -
            "datetime",
910 -
            "boolean"
911 -
          ]
912 -
        },
913 -
        "divideBy": {
914 -
          "type": "integer",
915 -
          "minimum": 1,
916 -
          "description": "Integer divisor applied before display, e.g. divideBy 10 for decimeters to meters."
917 -
        },
918 -
        "priority": {
919 -
          "type": "integer",
920 -
          "description": "Lower numbers display first."
921 -
        },
922 -
        "aggregate": {
923 -
          "type": "string",
924 -
          "description": "How to reduce multiple records. Defaults to 'first' for fixed rkey records and 'count' for collection scans.",
925 -
          "knownValues": [
926 -
            "first",
927 -
            "count",
928 -
            "max",
929 -
            "min",
930 -
            "sum",
931 -
            "latest",
932 -
            "exists"
933 -
          ]
934 -
        },
935 -
        "multiplyBy": {
936 -
          "type": "integer",
937 -
          "description": "Integer multiplier applied before display. Use with divideBy for rational scaling."
938 -
        },
939 -
        "maximumFractionDigits": {
940 -
          "type": "integer",
941 -
          "maximum": 6,
942 -
          "minimum": 0,
943 -
          "description": "Decimal precision for numeric display."
944 -
        }
945 -
      },
946 -
      "description": "A declarative display metric derived from a referenced record or collection. Portals may ignore unsupported formats or aggregates."
947 788
    }
948 789
  },
949 790
  "$type": "com.atproto.lexicon.schema",
950 791
  "lexicon": 1,
951 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."
952 793
}

Compare Other Versions

Lexicon Garden

@