app.golfthesky.round
Schema Diff
+49 -1
Compatibility Analysis
Breaking Changes Detected
4 breaking changes, 14 non-breaking changes.
Breaking Changes (4)
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "app.golfthesky.round#player", src: "app.golfthesky.round#player", tgt: "app.golfthesky.round#player.did", kind: "prop", name: Some("did") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "app.golfthesky.round#player", src: "app.golfthesky.round#player", tgt: "app.golfthesky.round#player.handle", kind: "prop", name: Some("handle") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "app.golfthesky.round#player", src: "app.golfthesky.round#player", tgt: "app.golfthesky.round#player.holes", kind: "prop", name: Some("holes") }
- ConstraintTightened ConstraintTightened { vertex_id: "app.golfthesky.round#hole.holeId", sort: "knownValues", old_value: "[\"opening-drive\",\"dogleg\",\"sky-ramp\",\"slick-slope\",\"bunker-alley\",\"island-hop\",\"first-light\",\"sticky-situation\",\"ice-cave\",\"archipelago\"]", new_value: "[\"opening-drive\",\"dogleg\",\"sky-ramp\",\"slick-slope\",\"bunker-alley\",\"island-hop\",\"first-light\",\"sticky-situation\",\"ice-cave\",\"archipelago\",\"clockwork\",\"mill-race\",\"skyhook\",\"paddle-alley\",\"crater\"]" }
Non-Breaking Changes (14)
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round#player" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round#player.did" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round#player.handle" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round#player.holes" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round#player.holes:items" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round:body.players" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round:body.players:items" }
- AddedVertex AddedVertex { vertex_id: "app.golfthesky.round:body.target" }
- AddedEdge AddedEdge { src: "app.golfthesky.round#player.holes", tgt: "app.golfthesky.round#player.holes:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "app.golfthesky.round#player.holes:items", tgt: "app.golfthesky.round#hole", kind: "ref", name: None }
- AddedEdge AddedEdge { src: "app.golfthesky.round:body", tgt: "app.golfthesky.round:body.players", kind: "prop", name: Some("players") }
- AddedEdge AddedEdge { src: "app.golfthesky.round:body", tgt: "app.golfthesky.round:body.target", kind: "prop", name: Some("target") }
- AddedEdge AddedEdge { src: "app.golfthesky.round:body.players", tgt: "app.golfthesky.round:body.players:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "app.golfthesky.round:body.players:items", tgt: "app.golfthesky.round#player", kind: "ref", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "app.golfthesky.round#player" }AddedVertex { vertex_id: "app.golfthesky.round#player.did" }AddedVertex { vertex_id: "app.golfthesky.round#player.handle" }AddedVertex { vertex_id: "app.golfthesky.round#player.holes" }AddedVertex { vertex_id: "app.golfthesky.round#player.holes:items" }AddedVertex { vertex_id: "app.golfthesky.round:body.players" }AddedVertex { vertex_id: "app.golfthesky.round:body.players:items" }AddedVertex { vertex_id: "app.golfthesky.round:body.target" }
Constraint Changes
- ConstraintTightened ConstraintTightened { vertex_id: "app.golfthesky.round#hole.holeId", sort: "knownValues", old_value: "[\"opening-drive\",\"dogleg\",\"sky-ramp\",\"slick-slope\",\"bunker-alley\",\"island-hop\",\"first-light\",\"sticky-situation\",\"ice-cave\",\"archipelago\"]", new_value: "[\"opening-drive\",\"dogleg\",\"sky-ramp\",\"slick-slope\",\"bunker-alley\",\"island-hop\",\"first-light\",\"sticky-situation\",\"ice-cave\",\"archipelago\",\"clockwork\",\"mill-race\",\"skyhook\",\"paddle-alley\",\"crater\"]" }
Additional Notes
- Breaking: RequiredEdgeAdded { vertex_id: "app.golfthesky.round#player", src: "app.golfthesky.round#player", tgt: "app.golfthesky.round#player.did", kind: "prop", name: Some("did") }
- Breaking: RequiredEdgeAdded { vertex_id: "app.golfthesky.round#player", src: "app.golfthesky.round#player", tgt: "app.golfthesky.round#player.handle", kind: "prop", name: Some("handle") }
- Breaking: RequiredEdgeAdded { vertex_id: "app.golfthesky.round#player", src: "app.golfthesky.round#player", tgt: "app.golfthesky.round#player.holes", kind: "prop", name: Some("holes") }
- Non-breaking: AddedEdge { src: "app.golfthesky.round#player.holes", tgt: "app.golfthesky.round#player.holes:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "app.golfthesky.round#player.holes:items", tgt: "app.golfthesky.round#hole", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "app.golfthesky.round:body", tgt: "app.golfthesky.round:body.players", kind: "prop", name: Some("players") }
- Non-breaking: AddedEdge { src: "app.golfthesky.round:body", tgt: "app.golfthesky.round:body.target", kind: "prop", name: Some("target") }
- Non-breaking: AddedEdge { src: "app.golfthesky.round:body.players", tgt: "app.golfthesky.round:body.players:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "app.golfthesky.round:body.players:items", tgt: "app.golfthesky.round#player", kind: "ref", name: None }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"hole": {
5
5
"properties": {
6
6
"holeId": {
7
7
"description": "Permanent identity of the hole within the course.",
8
8
"knownValues": [
9
9
"opening-drive",
10
10
"dogleg",
11
11
"sky-ramp",
12
12
"slick-slope",
13
13
"bunker-alley",
14
14
"island-hop",
15
15
"first-light",
16
16
"sticky-situation",
17
17
"ice-cave",
18
-
"archipelago"
18
+
"archipelago",
19
+
"clockwork",
20
+
"mill-race",
21
+
"skyhook",
22
+
"paddle-alley",
23
+
"crater"
19
24
],
20
25
"maxLength": 64,
21
26
"type": "string"
22
27
},
23
28
"shots": {
24
29
"description": "The whole hole as the only input the game takes. Comma-separated `<dtick>.<angle>.<mod>.<power>` entries: dtick is 120 Hz ticks since the previous entry, angle is milliradians counter-clockwise from +x (0–6283), mod is the ball type applied to that swing (0 none, 1 sticky, 2 super, 3 nitro, 4 air brakes, 5 sniper), power 1–100. An entry with power 0 is an event, not a swing: mod 4 is an Air Brakes tap, mod 5 a Mulligan. Power-ups cost energy; a verifier recomputes energy from the clock (starts at 4, +1 every 360 ticks, max 10; costs sticky 4, super 3, nitro 4, brakes 5, mulligan 6, sniper 6) and refuses a log that overspends. Example: `360.785.0.80,540.0.4.0`.",
25
30
"maxLength": 8000,
26
31
"type": "string"
27
32
},
28
33
"strokes": {
29
34
"description": "Advisory stroke count, including out-of-bounds penalties.",
30
35
"minimum": 0,
31
36
"type": "integer"
32
37
},
33
38
"ticks": {
34
39
"description": "Advisory: the tick the ball dropped. Absent if the hole was never finished.",
35
40
"minimum": 1,
36
41
"type": "integer"
37
42
}
38
43
},
39
44
"required": [
40
45
"holeId",
41
46
"shots",
42
47
"strokes"
43
48
],
44
49
"type": "object"
45
50
},
46
51
"main": {
47
52
"description": "One Golf the Sky round, published by the player into their own repo. The record stores every shot rather than a score: the game's ball physics are deterministic, so re-simulating the shots reproduces the round exactly. Owning the record is the identity proof, and replaying it is the score proof — strokes and ticks in this record are advisory and never trusted by a leaderboard.",
48
53
"key": "tid",
49
54
"record": {
50
55
"properties": {
51
56
"courseId": {
52
57
"description": "Permanent identity of the course played. Append-only: ids are never reordered, renamed, or reused.",
53
58
"knownValues": [
54
59
"skyline-links"
55
60
],
56
61
"maxLength": 64,
57
62
"type": "string"
58
63
},
59
64
"createdAt": {
60
65
"format": "datetime",
61
66
"type": "string"
62
67
},
63
68
"field": {
64
69
"description": "How many players were in that live round.",
65
70
"minimum": 1,
66
71
"type": "integer"
67
72
},
68
73
"holes": {
69
74
"items": {
70
75
"ref": "#hole",
71
76
"type": "ref"
72
77
},
73
78
"maxLength": 18,
74
79
"type": "array"
75
80
},
76
81
"mode": {
77
82
"description": "solo: against local bots. live: against other players on a synced clock — the only mode in which placing means anything.",
78
83
"knownValues": [
79
84
"solo",
80
85
"live"
81
86
],
82
87
"type": "string"
83
88
},
84
89
"placing": {
85
90
"description": "Advisory finishing position in a live round, 1 = won.",
86
91
"minimum": 1,
87
92
"type": "integer"
88
93
},
94
+
"players": {
95
+
"description": "Everyone else who played this round, each with their own shot logs, so a replay of this one record shows the whole field. Bots carry a did of the form bot:N. Advisory, like placing: only the owner's own holes are theirs to prove.",
96
+
"items": {
97
+
"ref": "#player",
98
+
"type": "ref"
99
+
},
100
+
"maxLength": 7,
101
+
"type": "array"
102
+
},
89
103
"simVersion": {
90
104
"description": "Which physics produced these shots. A verifier must replay under the matching version or refuse the round.",
91
105
"minimum": 1,
92
106
"type": "integer"
107
+
},
108
+
"target": {
109
+
"description": "The pills (hole wins) the round was played to.",
110
+
"maximum": 9,
111
+
"minimum": 1,
112
+
"type": "integer"
93
113
}
94
114
},
95
115
"required": [
96
116
"courseId",
97
117
"simVersion",
98
118
"holes",
99
119
"createdAt"
100
120
],
101
121
"type": "object"
102
122
},
103
123
"type": "record"
124
+
},
125
+
"player": {
126
+
"properties": {
127
+
"did": {
128
+
"description": "Their DID, or bot:N for a local bot.",
129
+
"maxLength": 300,
130
+
"type": "string"
131
+
},
132
+
"handle": {
133
+
"description": "Their handle when the round was played (advisory).",
134
+
"maxLength": 100,
135
+
"type": "string"
136
+
},
137
+
"holes": {
138
+
"items": {
139
+
"ref": "#hole",
140
+
"type": "ref"
141
+
},
142
+
"maxLength": 18,
143
+
"type": "array"
144
+
}
145
+
},
146
+
"required": [
147
+
"did",
148
+
"handle",
149
+
"holes"
150
+
],
151
+
"type": "object"
104
152
}
105
153
},
106
154
"id": "app.golfthesky.round",
107
155
"lexicon": 1
108
156
}