{
"id": "me.byjp.pesos.sts2.run",
"defs": {
"main": {
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"outcome",
"character",
"ascension",
"seed",
"startedAt",
"updatedAt"
],
"properties": {
"act": {
"type": "integer",
"maximum": 4,
"minimum": 1
},
"deck": {
"type": "array",
"items": {
"type": "string"
},
"description": "Card ids in the final deck."
},
"game": {
"type": "string",
"format": "at-uri",
"description": "Optional at-uri of the canonical games.gamesgamesgamesgames.actor.game record for StS2."
},
"seed": {
"type": "string",
"description": "Run seed as displayed in-game."
},
"floor": {
"type": "integer",
"minimum": 0
},
"maxHp": {
"type": "integer",
"minimum": 0,
"description": "Local player's maximum HP at the time of emission (reflects run-long HP gains/losses)."
},
"score": {
"type": "integer",
"minimum": 0
},
"stats": {
"ref": "lex:me.byjp.pesos.sts2.run#stats",
"type": "ref",
"description": "Aggregated combat stats across the run. All fields optional; counters reflect the local player's own activity."
},
"allies": {
"type": "array",
"items": {
"type": "object",
"required": [
"steam"
],
"properties": {
"steam": {
"type": "string",
"description": "SteamID64 as a decimal string."
},
"atproto": {
"type": "string",
"format": "did",
"description": "Atproto DID, when known."
}
}
},
"description": "Other players in a multiplayer run."
},
"relics": {
"type": "array",
"items": {
"type": "string"
},
"description": "Relic ids held at run end."
},
"endedAt": {
"type": "string",
"format": "datetime"
},
"outcome": {
"type": "string",
"description": "How the run ended.",
"knownValues": [
"in_progress",
"victory",
"death",
"abandoned"
]
},
"potions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Potion ids currently held."
},
"killedBy": {
"type": "string",
"description": "Enemy / event that ended the run, if applicable."
},
"statsRef": {
"type": "string",
"format": "at-uri",
"description": "at-uri of the user's games.gamesgamesgamesgames.actor.stats record for StS2, updated alongside this run."
},
"ascension": {
"type": "integer",
"maximum": 20,
"minimum": 0
},
"character": {
"type": "string",
"description": "Character class id (e.g. 'ironclad', 'silent')."
},
"currentHp": {
"type": "integer",
"minimum": 0,
"description": "Local player's current HP at the time of emission (0 if dead)."
},
"startedAt": {
"type": "string",
"format": "datetime"
},
"steamID64": {
"type": "string",
"description": "SteamID64 of the run's owner, when playing on Steam."
},
"updatedAt": {
"type": "string",
"format": "datetime"
},
"modVersion": {
"type": "string"
},
"gameVersion": {
"type": "string"
},
"durationSeconds": {
"type": "integer",
"minimum": 0
}
}
},
"description": "A single Slay the Spire 2 run."
},
"stats": {
"type": "object",
"properties": {
"turns": {
"type": "integer",
"minimum": 0,
"description": "Total player turns taken across all combats."
},
"deaths": {
"type": "integer",
"minimum": 0,
"description": "Number of times the player went to 0 HP. 0 in solo victory; can exceed 1 in multiplayer where allies revive."
},
"combats": {
"type": "integer",
"minimum": 0,
"description": "Total combats entered."
},
"lowestHp": {
"type": "integer",
"minimum": 0,
"description": "Lowest HP the player reached at any tracked moment in the run."
},
"bossesWon": {
"type": "integer",
"minimum": 0,
"description": "Boss combats won."
},
"elitesWon": {
"type": "integer",
"minimum": 0,
"description": "Elite combats won."
},
"goldSpent": {
"type": "integer",
"minimum": 0,
"description": "Total gold spent over the run."
},
"killCount": {
"type": "integer",
"minimum": 0,
"description": "Number of monsters this player dealt the killing blow to."
},
"cardsDrawn": {
"type": "integer",
"minimum": 0
},
"combatsWon": {
"type": "integer",
"minimum": 0,
"description": "Combats the player's side won."
},
"goldEarned": {
"type": "integer",
"minimum": 0,
"description": "Total gold gained over the run."
},
"cardsPlayed": {
"type": "integer",
"minimum": 0
},
"damageDealt": {
"type": "integer",
"minimum": 0,
"description": "Total HP damage dealt by the player to enemies (after block)."
},
"damageTaken": {
"type": "integer",
"minimum": 0,
"description": "Total HP damage taken by the player (after block)."
},
"goldCurrent": {
"type": "integer",
"minimum": 0,
"description": "Gold the player is currently holding at the time of emission."
},
"potionsUsed": {
"type": "integer",
"minimum": 0
},
"longestCombat": {
"type": "integer",
"minimum": 0,
"description": "Most player turns in a single combat."
},
"noDamageTurns": {
"type": "integer",
"minimum": 0,
"description": "Enemy turns during which the player took zero unblocked damage."
},
"cardsExhausted": {
"type": "integer",
"minimum": 0
},
"healingReceived": {
"type": "integer",
"minimum": 0,
"description": "Total HP healed by the player across the run (sum of positive HP changes)."
},
"biggestDamageDealt": {
"type": "integer",
"minimum": 0,
"description": "Largest HP damage dealt by the player in one attack (after block)."
},
"biggestDamageTaken": {
"type": "integer",
"minimum": 0,
"description": "Largest HP damage taken by the player in one attack (after block)."
},
"highestBlockInTurn": {
"type": "integer",
"minimum": 0,
"description": "Most block gained by the player in a single player turn."
},
"cardUseDistribution": {
"ref": "#distribution",
"type": "ref",
"description": "Cards played, keyed by card name (id) mapped to the number of times that card was played. Example: { \"strike\": 42, \"bash\": 6 }."
},
"hitsDealtDistribution": {
"ref": "#distribution",
"type": "ref",
"description": "Hits dealt by the player grouped by the attack's full value (before block). Example: { \"1\": 23, \"2\": 8, \"10\": 1 }."
},
"hitsTakenDistribution": {
"ref": "#distribution",
"type": "ref",
"description": "Hits the player received grouped by the attack's full value (before block). Example: { \"1\": 23, \"2\": 8, \"10\": 1 }."
},
"biggestTurnDamageDealt": {
"type": "integer",
"minimum": 0,
"description": "Most HP damage the player dealt in one player turn (after block)."
},
"biggestTurnDamageTaken": {
"type": "integer",
"minimum": 0,
"description": "Most HP damage the player took in one enemy turn (after block)."
}
}
},
"attestation": {
"type": "object",
"required": [
"cid",
"key",
"signature"
],
"properties": {
"cid": {
"type": "string",
"description": "CIDv1 (DAG-CBOR + SHA-256) of the record body that was signed."
},
"key": {
"type": "string",
"format": "did",
"description": "did:key identifying the signing key."
},
"signature": {
"type": "bytes",
"description": "P-256 ECDSA signature (low-S, IEEE P1363 r‖s) over the content CID bytes."
}
},
"description": "Inline ECDSA signature appended to the record's `signatures` array after the content CID is computed (per badge.blue). The `signatures` array is stripped before re-validation; entries identify the signing key so verifiers can look it up against a trusted-keys list to confirm a genuine mod build. The canonical list lives at https://sts2.byjp.me/.well-known/sts2-mod-keys/keys.json — other verifiers may publish their own at the same well-known path on a different host."
},
"distribution": {
"type": "object",
"properties": {},
"description": "Generic histogram keyed by arbitrary string values mapped to their integer counts. Keys are intentionally undeclared because the set of values is open-ended."
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1
}