- Sashité for Developers
- Specifications
- GGN
- 1.0.0
- Examples
GGN Examples
Practical implementation guide for General Gameplay Notation v1.0.0.
Examples
Simple Movement
{
"C:R": {
"a1": {
"a4": [
{
"must": { "a2": "empty", "a3": "empty", "a4": "empty" },
"deny": {},
"diff": {
"board": {
"a1": null,
"a4": "C:R"
}
}
}
]
}
}
}
Capture
{
"C:R": {
"a1": {
"a4": [
{
"must": { "a2": "empty", "a3": "empty", "a4": "enemy" },
"deny": {},
"diff": {
"board": {
"a1": null,
"a4": "C:R"
},
"hands": {
"c:r": 1
}
}
}
]
}
}
}
Drop from Hand
{
"S:P": {
"*": {
"e4": [
{
"must": { "e4": "empty" },
"deny": {},
"diff": {
"board": {
"e4": "S:P"
},
"hands": {
"S:P": -1
}
}
}
]
}
}
}
Capture to Hand
{
"A:R": {
"a1": {
"*": [
{
"must": { "a1": "enemy" },
"deny": {},
"diff": {
"board": {
"a1": null
},
"hands": {
"A:R": 1
}
}
}
]
}
}
}
Multiple Promotion Choices
{
"C:P": {
"e7": {
"e8": [
{
"must": { "e8": "empty" },
"deny": {},
"diff": {
"board": {
"e7": null,
"e8": "C:Q"
}
}
}
]
}
}
}
Note: This example shows promotion to queen. Different promotion choices would be separate GGN entries with different diff
outcomes.
Complex Movement (Castling Possibility)
{
"C:+K": {
"e1": {
"g1": [
{
"must": { "f1": "empty", "g1": "empty", "h1": "C:+R" },
"deny": {},
"diff": {
"board": {
"e1": null,
"g1": "C:K",
"h1": null,
"f1": "C:R"
}
}
}
]
}
}
}
Capture Possibility (Shōgi-style)
{
"S:P": {
"c3": {
"c4": [
{
"must": { "c4": "enemy" },
"deny": {},
"diff": {
"board": {
"c3": null,
"c4": "S:P"
},
"hands": {
"S:P": 1
}
}
}
]
}
}
}
Cross-Style Game Example
{
"C:R": {
"a1": {
"a4": [
{
"must": { "a2": "empty", "a3": "empty", "a4": "enemy" },
"deny": {},
"diff": {
"board": {
"a1": null,
"a4": "C:R"
},
"hands": {
"x:c": 1
}
}
}
]
}
},
"x:c": {
"b2": {
"b8": [
{
"must": { "b3": "empty", "b4": "empty", "b5": "empty", "b6": "empty", "b8": "enemy" },
"deny": { "b7": "empty" },
"diff": {
"board": {
"b2": null,
"b8": "x:c"
},
"hands": {
"C:R": 1
}
}
}
]
}
}
}
This example shows a GGN data set usable for a game where Chess pieces face Xiangqi pieces.
Conditional Movement (En Passant)
{
"C:P": {
"e5": {
"f6": [
{
"must": { "f6": "empty", "f5": "c:-p" },
"deny": {},
"diff": {
"board": {
"e5": null,
"f6": "C:P",
"f5": null
},
"hands": {
"c:p": 1
}
}
}
]
}
}
}
This represents an en passant possibility: pawn can move to f6 if f6 is empty AND f5 contains an enemy pawn vulnerable to en passant (noted with the -
modifier).
Multi-Dimensional Movement
{
"R:B": {
"a1A": {
"d4D": [
{
"must": { "b2B": "empty", "c3C": "empty", "d4D": "empty" },
"deny": {},
"diff": {
"board": {
"a1A": null,
"d4D": "R:B"
}
}
}
]
}
}
}
Example from Raumschach showing bishop movement across dimensions using CELL coordinates.
Pawn Drop with File Restriction (Shogi-Style)
Dropping a pawn from hand onto e4, with the restriction that there must not be another unpromoted pawn on the same file.
{
"S:P": {
"*": {
"e4": [
{
"must": { "e4": "empty" },
"deny": {
"e1": "S:P", "e2": "S:P", "e3": "S:P",
"e5": "S:P", "e6": "S:P", "e7": "S:P",
"e8": "S:P", "e9": "S:P"
},
"diff": {
"board": {
"e4": "S:P"
},
"hands": {
"S:P": -1
}
}
}
]
}
}
}
Piece State Transitions
Pre-Move vs Post-Move States
GGN represents pieces in their pre-move state (before the action is executed) in the query structure, while the diff
field represents the post-move state (after the action is completed). This distinction is crucial for pieces whose states change as a result of movement.
State Evolution Examples
Castling Eligibility Loss:
When a rook moves for the first time, it loses its castling eligibility. This state change is reflected in the different QPI identifiers used in the query versus the diff
field:
{
"C:+R": {
"a1": {
"a4": [
{
"must": { "a2": "empty", "a3": "empty", "a4": "empty" },
"deny": {},
"diff": {
"board": {
"a1": null,
"a4": "C:R"
}
}
}
]
}
}
}
The query uses C:+R
(rook with castling eligibility) but the diff
shows C:R
(rook without castling eligibility).
En Passant Vulnerability:
A pawn vulnerable to en passant capture loses this vulnerability after any move:
{
"c:-p": {
"f5": {
"f4": [
{
"must": { "f4": "empty" },
"deny": {},
"diff": {
"board": {
"f5": null,
"f4": "c:p"
}
}
}
]
}
}
}
The query uses c:-p
(vulnerable pawn) but the diff
shows c:p
(normal pawn).
Design Rationale
This temporal distinction allows GGN to:
- Query current possibilities based on the actual present state of pieces
- Maintain state consistency with the current position
- Describe state transitions explicitly through the
diff
field
Integration with PMN
GGN defines movement possibilities with complete state transitions, while PMN handles mechanical execution. When a GGN move is selected, the diff
field provides the expected outcome that can be validated against PMN execution results.
Simple Movement to PMN
GGN possibility:
{
"C:+R": {
"a1": {
"a4": [
{
"must": { "a2": "empty", "a3": "empty", "a4": "empty" },
"deny": {},
"diff": {
"board": {
"a1": null,
"a4": "C:R"
}
}
}
]
}
}
}
PMN execution:
["a1", "a4", "C:R"]
Complex Movement to PMN
GGN possibility (castling):
{
"C:+K": {
"e1": {
"g1": [
{
"must": { "f1": "empty", "g1": "empty", "h1": "C:+R" },
"deny": {},
"diff": {
"board": {
"e1": null,
"g1": "C:K",
"h1": null,
"f1": "C:R"
}
}
}
]
}
}
}
PMN execution:
["e1", "g1", "C:K", "h1", "f1", "C:R"]
Capture to PMN
GGN possibility (en passant):
{
"C:P": {
"e5": {
"f6": [
{
"must": { "f6": "empty", "f5": "c:-p" },
"deny": {},
"diff": {
"board": {
"e5": null,
"f6": "C:P",
"f5": null
},
"hands": {
"c:p": 1
}
}
}
]
}
}
}
PMN execution:
["e5", "f6", "C:P", "f5", "*", "c:p"]