dev.tsunagite.score

tsunagite.dev

Schema Diff

+20 -4

From

CID
bafyreifl3pzitvt...
Indexed At
2026-02-18 19:15 UTC
View this version

To

CID
bafyreicscnfo45a...
Indexed At
2026-08-07 18:08 UTC
View this version

Compatibility Analysis

Backward Compatible

Backward compatible. 6 non-breaking changes.

Non-Breaking Changes (6)
  • AddedVertex AddedVertex { vertex_id: "dev.tsunagite.score:body.scoredAt" }
  • AddedVertex AddedVertex { vertex_id: "dev.tsunagite.score:body.totalEarly" }
  • AddedVertex AddedVertex { vertex_id: "dev.tsunagite.score:body.totalLate" }
  • AddedEdge AddedEdge { src: "dev.tsunagite.score:body", tgt: "dev.tsunagite.score:body.scoredAt", kind: "prop", name: Some("scoredAt") }
  • AddedEdge AddedEdge { src: "dev.tsunagite.score:body", tgt: "dev.tsunagite.score:body.totalEarly", kind: "prop", name: Some("totalEarly") }
  • AddedEdge AddedEdge { src: "dev.tsunagite.score:body", tgt: "dev.tsunagite.score:body.totalLate", kind: "prop", name: Some("totalLate") }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "dev.tsunagite.score:body.scoredAt" }
  • AddedVertex { vertex_id: "dev.tsunagite.score:body.totalEarly" }
  • AddedVertex { vertex_id: "dev.tsunagite.score:body.totalLate" }

Additional Notes

  • Non-breaking: AddedEdge { src: "dev.tsunagite.score:body", tgt: "dev.tsunagite.score:body.scoredAt", kind: "prop", name: Some("scoredAt") }
  • Non-breaking: AddedEdge { src: "dev.tsunagite.score:body", tgt: "dev.tsunagite.score:body.totalEarly", kind: "prop", name: Some("totalEarly") }
  • Non-breaking: AddedEdge { src: "dev.tsunagite.score:body", tgt: "dev.tsunagite.score:body.totalLate", kind: "prop", name: Some("totalLate") }
1 1
{
2 2
  "id": "dev.tsunagite.score",
3 3
  "defs": {
4 4
    "enum": {
5 5
      "type": "object",
6 6
      "required": [
7 7
        "value"
8 8
      ],
9 9
      "properties": {
10 10
        "value": {
11 11
          "type": "string",
12 12
          "format": "record-key",
13 13
          "description": "The internal ID of the value, matching with an allowed enum value defined by the game record."
14 14
        }
15 15
      },
16 16
      "description": "An indexable named score component."
17 17
    },
18 18
    "main": {
19 19
      "key": "tid",
20 20
      "type": "record",
21 21
      "record": {
22 22
        "type": "object",
23 23
        "required": [
24 24
          "game",
25 25
          "song",
26 26
          "chart",
27 27
          "judgments",
28 28
          "scoreComponents"
29 29
        ],
30 30
        "properties": {
31 31
          "game": {
32 32
            "type": "string",
33 33
            "format": "at-uri",
34 34
            "description": "The game this score was earned in. URI must point to a record of type `dev.tsunagite.game`."
35 35
          },
36 36
          "mode": {
37 37
            "type": "string",
38 38
            "description": "The game mode this score was earned on. Must be a mode defined by the game record if present."
39 39
          },
40 40
          "song": {
41 41
            "type": "string",
42 42
            "format": "at-uri",
43 43
            "description": "The song this score was earned on. URI must point to a record of type `dev.tsunagite.song`."
44 44
          },
45 45
          "chart": {
46 46
            "type": "string",
47 47
            "format": "at-uri",
48 48
            "description": "The chart this score was earned on. URI must point to a record of type `dev.tsunagite.chart`."
49 49
          },
50 50
          "version": {
51 51
            "type": "bytes",
52 52
            "maxLength": 16,
53 53
            "minLength": 16,
54 54
            "description": "The md5 hash of the chart version this score was earned on. Optional if you will not perform leaderboard resets upon any chart changes."
55 55
          },
56 +
          "scoredAt": {
57 +
            "type": "string",
58 +
            "format": "datetime",
59 +
            "description": "The time this score was originally earned."
60 +
          },
56 61
          "judgments": {
57 62
            "type": "object",
58 63
            "properties": {
59 64
              "$keyFormat": {
60 65
                "type": "string",
61 66
                "format": "record-key",
62 67
                "maxLength": 32,
63 68
                "minLength": 1,
64 69
                "description": "Must match a judgment defined by the game record."
65 70
              },
66 71
              "$valueType": {
67 72
                "type": "object",
68 73
                "required": [
69 74
                  "total"
70 75
                ],
71 76
                "properties": {
72 77
                  "late": {
73 78
                    "type": "integer",
74 -
                    "description": "The number of total judgments of this type earned when hitting late."
79 +
                    "description": "The number of judgments of this type earned when hitting late."
75 80
                  },
76 81
                  "early": {
77 82
                    "type": "integer",
78 -
                    "description": "The number of total judgments of this type earned when hitting early."
83 +
                    "description": "The number of judgments of this type earned when hitting early."
79 84
                  },
80 85
                  "total": {
81 86
                    "type": "integer",
82 -
                    "description": "The number of total judgments of this type earned."
87 +
                    "description": "The total number of judgments of this type earned."
83 88
                  }
84 89
                }
85 90
              }
86 91
            },
87 92
            "description": "A map of judgment names to the integer judgment amounts earned during play."
88 93
          },
94 +
          "totalLate": {
95 +
            "type": "integer",
96 +
            "description": "The total number of judgments earned when hitting late."
97 +
          },
98 +
          "totalEarly": {
99 +
            "type": "integer",
100 +
            "description": "The total number of judgments earned when hitting early."
101 +
          },
89 102
          "inputMethod": {
90 103
            "type": "string",
91 104
            "description": "The input method this score was earned using. Must be an input method defined by the game record if present."
92 105
          },
93 106
          "scoreComponents": {
94 107
            "type": "object",
95 108
            "properties": {
96 109
              "$keyFormat": {
97 110
                "type": "string",
98 111
                "format": "record-key",
99 112
                "maxLength": 32,
100 113
                "minLength": 1,
101 114
                "description": "Must match an ID defined by the game record, as well as using the same type."
102 115
              },
103 116
              "$valueType": {
104 117
                "refs": [
105 118
                  "#enum",
106 119
                  "#points",
107 120
                  "#percentage",
108 121
                  "#text"
109 122
                ],
110 123
                "type": "union",
111 124
                "description": "If you need a component type that doesn't exist yet, contact @lemmaeof.gay"
112 125
              }
113 126
            },
114 127
            "description": "The components that make up this score, as defined by the game record."
115 128
          }
116 129
        }
117 130
      },
118 131
      "description": "A score in a game hosting leaderboards via Tsunagite."
119 132
    },
120 133
    "text": {
121 134
      "type": "object",
122 135
      "required": [
123 136
        "id",
124 137
        "value"
125 138
      ],
126 139
      "properties": {
127 140
        "id": {
128 141
          "type": "string",
129 142
          "format": "record-key",
130 143
          "maxLength": 32,
131 144
          "minLength": 1,
132 145
          "description": "The internal ID of this component, matching with a text score defined by the game record."
133 146
        },
134 147
        "value": {
135 148
          "type": "string",
136 149
          "description": "The text value of this score."
137 150
        }
138 151
      },
139 152
      "description": "A fallback score component."
140 153
    },
141 154
    "points": {
142 155
      "type": "object",
143 156
      "required": [
144 157
        "value"
145 158
      ],
146 159
      "properties": {
147 160
        "value": {
148 161
          "type": "integer",
149 162
          "description": "The number of points earned, capped by the limit defined by the game record if present."
150 163
        }
151 164
      },
152 165
      "description": "An integer point score component."
153 166
    },
154 167
    "percentage": {
155 168
      "type": "object",
156 169
      "required": [
157 170
        "value"
158 171
      ],
159 172
      "properties": {
160 173
        "value": {
161 174
          "type": "string",
162 175
          "description": "The percentage score earned, capped and formatted by the limits defined by the game record. Stored as a decimal number without a percent sign."
163 176
        }
164 177
      },
165 178
      "description": "A percentage score component."
166 179
    }
167 180
  },
168 181
  "$type": "com.atproto.lexicon.schema",
169 182
  "lexicon": 1,
170 -
  "description": "Definitions related to scores in games hosting leaderboards via Tsunagite."
183 +
  "description": "Definitions related to scores in games hosting leaderboards via Tsunagite.",
184 +
  "featureFlags": [
185 +
    "dev.tsunagite.dictionaryObject"
186 +
  ]
171 187
}

Compare Other Versions

Lexicon Garden

@