General Gameplay Notation (GGN) Specification
Version: 1.0.0 Author: Sashité Published: 8 March 2014 License: MIT License
Overview
General Gameplay Notation (GGN) is a rule‑agnostic, JSON‑based format for describing pseudo‑legal moves in abstract strategy board games. Whereas PMN expresses what a move does, GGN expresses whether that move is possible under basic movement constraints. GGN is deliberately silent about higher‑level, game‑specific legality questions (e.g., check, ko, repetition, castling paths). This neutrality makes the format universal: any engine can pre‑compute and share a library of pseudo‑legal moves for any mix of games.
GGN focuses exclusively on board-to-board transformations: pieces moving, capturing, or transforming on the game board. Hand management, drops, and captures-to-hand are outside the scope of this specification.
Core Concepts
A single GGN entry answers the question:
Can this piece, currently on this square, reach that square?
It therefore encodes:
- Which piece (via GAN identifier)
- From where (source square label)
- To where (destination square label)
- Which pre‑conditions must hold (
require
) - Which pre‑conditions must not hold (
prevent
) - Which post‑conditions result (
perform
)
Multiple entries in the destination array represent different variants of the same basic move (e.g., different promotion choices).
No other information (turn order, player rights, game outcome, hand management, etc.) belongs in GGN.
JSON Structure
{
"<Source piece GAN>": {
"<Source square>": {
"<Destination square>": [
{
"require": { "<square>": "<required state>", … },
"prevent": { "<square>": "<forbidden state>", … },
"perform": { "<square>": "<new state | null>", … }
},
{
// Additional variants for the same move...
}
]
}
}
}
Fields
Field | Type | Required | Meaning |
---|---|---|---|
Source piece GAN | string | yes | Identifier of the current piece state (GAN) |
Source square | string | yes | Origin square on the board |
Destination square | string | yes | Target square on the board |
require | object | no | Square → Occupation State map that must be satisfied before the move |
prevent | object | no | Square → Occupation State map that must not be satisfied before the move |
perform | object | yes | Square → piece GAN or null (indicating an empty square) after the move |
Implicit Requirements
The query structure itself defines implicit requirements that must not be duplicated in the require
field:
- Source piece availability: The specified source piece must be present at the source square
- Move consistency: All implicit requirements derived from the query structure are automatically validated
Explicitly specifying these implicit requirements in the require
field should result in a validation error, as it creates redundancy and potential inconsistency.
Move Variants
When a move can result in multiple outcomes (such as promotion choices), each variant is represented as a separate object in the destination array. All variants share the same source and destination squares but may have different require
, prevent
, or perform
conditions.
Common use cases for variants include:
- Promotion choices: Different pieces the moving piece can transform into
- Optional promotions: Choice between promoting or not promoting
- Conditional transformations: Different outcomes based on game state
Logical Semantics of Require and Prevent
Logical Operations
- require: All conditions specified in this field must be satisfied (logical AND). If even one condition is not met, the move is invalid (under GGN constraints).
- prevent: The move is forbidden if any of the listed conditions is true (logical OR). This corresponds to rejecting the move as soon as one or more of the listed states are satisfied.
Constraint Resolution
- Consistency Rule: A square cannot have the same state specified in both
require
andprevent
fields, as this would create a logical contradiction. A state is considered the same if the exact same string (e.g.,"enemy"
or a GAN identifier like"GAME:P"
) appears in both fields for the same square. - Precedence: When both
require
andprevent
fields are present, they are evaluated independently, and both sets of constraints must be satisfied for the move to be valid. - Empty Fields: Omitting either the
require
orprevent
field is equivalent to having no constraints of that type.
Occupation States
GGN recognizes three explicit occupation states and allows exact piece matching:
State | Meaning |
---|---|
"empty" |
Square must be empty |
"enemy" |
Square must contain a standard opposing piece (as opposed to empty or ally) |
GAN identifier | Square must contain exactly the specified piece |
Implicit Occupation States
Through the use of the prevent
field, it’s possible to express two additional implicit states:
Implicit State | Expression | Meaning |
---|---|---|
"occupied" |
"prevent": { "a1": "empty" } |
Square must be occupied by any piece (enemy or ally) |
"ally" |
"prevent": { "a1": "enemy" } |
Square must contain a friendly piece (not an enemy piece) |
Combinatorial Expressions
By combining the require
and prevent
predicates with the occupation states, GGN can express a rich set of conditions. The following table illustrates common patterns:
Desired Condition | GGN Expression |
---|---|
Square must be empty | "require": { "a1": "empty" } |
Square must contain an enemy piece | "require": { "a1": "enemy" } |
Square must contain an ally piece | "prevent": { "a1": "enemy" } |
Square must be occupied (by any piece) | "prevent": { "a1": "empty" } |
Square must contain exactly piece “X:Y” | "require": { "a1": "X:Y" } |
Square must not contain piece “X:Y” | "prevent": { "a1": "X:Y" } |
Square must not be attacked by any enemy piece | (Outside the scope of GGN; belongs to full game rules) |
These patterns can be combined to express complex conditions while maintaining the canonicity of the format. The minimalist approach of GGN’s occupation states, coupled with the expressive power of require
and prevent
predicates, allows for precise description of move constraints without semantic redundancy.
Examples (Game‑Neutral)
Coordinates are illustrative; any labeling convention is acceptable.
Simple Move with No Requirements
A piece that can move directly to a destination without any requirements.
{
"GAME:X": {
"c3": {
"c5": [
{
"perform": { "c3": null, "c5": "GAME:X" }
}
]
}
}
}
Simple Move (Sliding)
A piece slides from c3 to c5 along an empty file.
{
"GAME:X": {
"c3": {
"c5": [
{
"require": { "c4": "empty", "c5": "empty" },
"perform": { "c3": null, "c5": "GAME:X" }
}
]
}
}
}
Simple Capture
A piece captures an enemy on d4.
{
"GAME:X": {
"c3": {
"d4": [
{
"require": { "d4": "enemy" },
"perform": { "c3": null, "d4": "GAME:X" }
}
]
}
}
}
Multiple Promotion Choices (Chess)
A white pawn on the seventh rank moves to the eighth rank and can be promoted to any of four pieces.
{
"CHESS:P": {
"e7": {
"e8": [
{
"require": { "e8": "empty" },
"perform": { "e7": null, "e8": "CHESS:Q" }
},
{
"require": { "e8": "empty" },
"perform": { "e7": null, "e8": "CHESS:R" }
},
{
"require": { "e8": "empty" },
"perform": { "e7": null, "e8": "CHESS:N" }
},
{
"require": { "e8": "empty" },
"perform": { "e7": null, "e8": "CHESS:B" }
}
]
}
}
}
Optional Promotion (Shōgi-Style)
A piece entering a promotion zone can choose whether or not to promote.
{
"SHOGI:P": {
"1g": {
"1f": [
{
"require": { "1f": "empty" },
"perform": { "1g": null, "1f": "SHOGI:P" }
},
{
"require": { "1f": "empty" },
"perform": { "1g": null, "1f": "SHOGI:+P" }
}
]
}
}
}
Multi-Square Move (Castling)
A complex move involving multiple pieces, such as castling in Chess.
{
"CHESS:K": {
"e1": {
"g1": [
{
"require": { "f1": "empty", "g1": "empty", "h1": "CHESS:R" },
"perform": { "e1": null, "f1": "CHESS:R", "g1": "CHESS:K", "h1": null }
}
]
}
}
}
Conditional Move with Prevention
A move that requires certain squares to be empty and prevents the move if specific pieces are present.
{
"GAME:B": {
"c1": {
"f4": [
{
"require": { "d2": "empty", "e3": "empty", "f4": "empty" },
"prevent": { "g5": "GAME:K", "h6": "GAME:Q" },
"perform": { "c1": null, "f4": "GAME:B" }
}
]
}
}
}
En Passant Capture
A pawn captures en passant, removing the captured pawn from a different square.
{
"CHESS:P": {
"d5": {
"e6": [
{
"require": { "e5": "CHESS:p", "e6": "empty" },
"perform": { "d5": null, "e5": null, "e6": "CHESS:P" }
}
]
}
}
}
Validation Rules
- A valid GGN document must conform to the JSON Schema above.
- For each move entry:
- The
perform
field is required and must not be empty. - The
require
andprevent
fields are optional, but if present must not be empty. - No square may have the same state in both the
require
andprevent
fields within the same variant. - All squares referenced in
require
,prevent
, andperform
must be valid board squares. - All GAN identifiers must be valid according to the GAN specification.
- The
- Implicit requirement consistency:
- The
require
field must not duplicate implicit requirements from the query structure. - Specifically,
require
must not specify that the source square contains the source piece. - Violating this rule should result in a validation error.
- The
- For move variants:
- Multiple variants in the same destination array represent different possible outcomes of the same basic move.
- Each variant must have a valid
perform
field. - Variants may have different
require
,prevent
, orperform
conditions.
- Board-only scope:
- All squares must refer to valid board positions.
- Hand management, drops, and captures-to-hand are outside the scope of GGN.
Relationship to Other Notations
Notation | Purpose |
---|---|
GAN | Game-qualified piece identifiers |
FEEN | Complete board state (static positions) |
PMN | Sequential, deterministic state changes |
GGN complements this ecosystem by defining movement possibilities: it specifies which board-to-board transformations are theoretically achievable under basic constraints, without validating their legality under complete game rules.
For games involving hand management (like Shōgi drops or captures-to-hand), these mechanics should be handled at a higher level, with GGN focusing solely on the board transformation aspects of such moves.
JSON Schema
This specification is accompanied by a formal JSON Schema, which defines the structure and constraints of a valid GGN document. It can be used for automatic validation, editor integration, or documentation generation.
Schema URL:
https://sashite.dev/schemas/ggn/1.0.0/schema.json
This schema is versioned and stable. It corresponds exactly to the current version of this specification (v1.0.0). For best compatibility, consumers of GGN data are encouraged to validate against this schema before processing.
Example
{
"$schema": "https://sashite.dev/schemas/ggn/1.0.0/schema.json",
"CHESS:P": {
"e7": {
"e8": [
{
"require": { "e8": "empty" },
"perform": { "e7": null, "e8": "CHESS:Q" }
},
{
"require": { "e8": "empty" },
"perform": { "e7": null, "e8": "CHESS:N" }
}
]
}
}
}
Implementations
Ruby
- Ggn.rb - A Ruby implementation of the General Gameplay Notation (GGN) specification. This library provides parsing, validation, and evaluation capabilities for GGN documents, enabling game engines to work with movement rules across different board games including Chess, Shōgi, Xiangqi, and custom variants.