Sashité for Developers

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:

  1. Which piece (via GAN identifier)
  2. From where (source square label)
  3. To where (destination square label)
  4. Which pre‑conditions must hold (require)
  5. Which pre‑conditions must not hold (prevent)
  6. 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:

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:


Logical Semantics of Require and Prevent

Logical Operations

Constraint Resolution

  1. Consistency Rule: A square cannot have the same state specified in both require and prevent 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.
  2. Precedence: When both require and prevent fields are present, they are evaluated independently, and both sets of constraints must be satisfied for the move to be valid.
  3. Empty Fields: Omitting either the require or prevent 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

  1. A valid GGN document must conform to the JSON Schema above.
  2. For each move entry:
    • The perform field is required and must not be empty.
    • The require and prevent fields are optional, but if present must not be empty.
    • No square may have the same state in both the require and prevent fields within the same variant.
    • All squares referenced in require, prevent, and perform must be valid board squares.
    • All GAN identifiers must be valid according to the GAN specification.
  3. 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.
  4. 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, or perform conditions.
  5. 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