Sashité for Developers

Forsyth–Edwards Enhanced Notation (FEEN) Specification

Version: 1.0.0 Author: Sashité Published: May 1, 2025 License: MIT License


Overview

FEEN is a compact, canonical, and rule-agnostic textual format for representing static board positions in two-player piece-placement games. It is designed to support multiple game types and hybrid configurations, while remaining neutral with regard to the rules of any specific game.

FEEN extends the traditional FEN notation to support cross-game scenarios, arbitrary board dimensions, and captured pieces management, making it suitable for a wide range of abstract strategy games including Chess, Shōgi, Xiangqi, and their variants.


Properties


Constraints


Format

A FEEN record consists of the following three space-separated fields:

  1. <PIECE-PLACEMENT> — Specifies the configuration of pieces on the board, possibly in multiple dimensions.
  2. <PIECES-IN-HAND> — Lists any off-board pieces available to each player, separated by player and sorted within each player group.
  3. <GAMES-TURN> — Indicates which player is to move, and associates piece casing with game identities.

These fields are combined into a single FEEN string like:

<PIECE-PLACEMENT> <PIECES-IN-HAND> <GAMES-TURN>

Fundamental Concepts

Piece Representation

FEEN relies on the Piece Name Notation (PNN) specification for representing individual pieces. PNN provides a consistent way to identify pieces and their states across various board games.

Key PNN Elements in FEEN Context

Important: Pieces in hand (captured pieces) are stored in their base form only, without any modifiers, as they represent the raw piece type available for future use.

Game Identification and GAN Inference

FEEN positions can be converted to General Actor Notation (GAN) identifiers using the <GAMES-TURN> field. Each piece’s complete GAN identifier is inferred by combining:

  1. The appropriate game identifier from <GAMES-TURN> based on the piece’s current ownership (case)
  2. The piece’s PNN representation

GAN Inference Rules

Example

Given FEEN position:

lnsiksnl/1b4r1/pppppppp/8/4P3/PPPP1PPP/8/RNSKMSNR / ogi/MAKRUK

Piece Ownership and Capture Logic

FEEN supports dynamic piece ownership where pieces can change hands through capture and redeployment (as in Shōgi-style games). A piece’s current owner is always determined by its case in the FEEN position, regardless of its original game system.

Ownership Rules

  1. Dynamic Ownership: A piece’s current owner is determined by its case in the FEEN position
  2. Capture Support: Pieces can be captured and moved to the opponent’s hand
  3. Redeployment: Captured pieces can be placed back on the board under new ownership
  4. Case Correspondence: Current ownership is always determined by piece case, not original game

Examples of Ownership Changes

Same-Game Captures (Chess, Shōgi, etc.)

# Initial position in Shōgi:
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL / SHOGI/shogi

# After some moves:
l4+R2+R/3G+Ns2k/p1pppgspp/5p3/2P6/3S1S3/P2P+nPP2/2G2G2L/LN2K2N1 5P2BL/p shogi/SHOGI
# Uppercase player (Sente) has captured 5 pawns, 2 bishops and 1 lance
# Lowercase player (Gote) has captured 1 pawn

Cross-Game Captures

# Initial position in Chess vs Makruk:
rnsmksnr/8/pppppppp/8/8/8/PPPPPPPP/RNBQKBNR / CHESS/makruk

# After some moves:
2s5/6k1/2PQ2p1/4Pp1p/3P3P/5N2/5PP1/2m4K / CHESS/makruk
# Captured pieces are removed from play

Potential Ambiguity Consideration

Important Note: When games use overlapping PNN identifiers (e.g., both games have pieces that use the same letters), piece identification after ownership changes may become ambiguous in certain contexts.

Example of Potential Ambiguity

# Consider two games:
# CHESSGAME uses pieces: {K, Q, R, B, N, P}
# chessgame uses pieces: {k, q, r, b, n, p}

Position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR prq/PBR CHESSGAME/chessgame"

# In the chessgame player's hand: "P", "B", "R"
# These could be:
# 1. Originally CHESSGAME pieces that were captured (CHESSGAME:P, CHESSGAME:B, CHESSGAME:R)
# 2. Originally chessgame pieces that changed case due to game rules (chessgame:p, chessgame:b, chessgame:r)
#
# Without additional context, the original game system of these pieces cannot be determined
# from the FEEN position alone.

When This Matters

This ambiguity is only relevant when:

  1. Cross-game scenarios where different games use overlapping PNN identifiers
  2. Piece behavior differs between games (e.g., “CHESSGAME:R” moves differently than chessgame:r)
  3. Game engines need to apply different rules based on original piece identity

When This Doesn’t Matter

This ambiguity is not a concern when:

  1. Same-game scenarios (e.g., “SHOGI/shogi”) - all pieces belong to the same system
  2. Capture-removal games (like traditional Chess) where captured pieces are removed from play
  3. Intentional design where captured pieces are meant to assimilate into the capturing player’s game system
  4. Rule-agnostic applications that only care about current piece positions and ownership

Field 1: <PIECE-PLACEMENT>

This field encodes the spatial distribution of pieces across the board. The position is always expressed from the point of view of the player who plays first in the initial position.

Pencil sketch of chess pieces with smiley faces standing on an isometric checkered board, illustrating the piece placement field in FEEN notation for board game positions

Encoding Rules

Multi-Dimensional Support

This generalization allows FEEN to describe n-dimensional boards with arbitrary shapes:

Irregular Board Shapes

FEEN can represent boards with irregular shapes by varying the number of cells per rank:

8/7/8/8/8/8/8/8  # 8x8 board with one rank having only 7 cells

Field 2: <PIECES-IN-HAND>

This field lists pieces available for future placement on the board, representing captured pieces or reserves depending on the game. The format uses a forward slash (/) as a separator between the two players’ pieces.

Pencil sketch of fallen chess pieces with sad expressions lying on their sides, illustrating the pieces-in-hand field in FEEN notation for captured or reserve pieces in board games

Important: Pieces in hand are represented in their base form only (no modifiers), as captured pieces lose their board-specific states and revert to their fundamental type.

Format Structure

The <PIECES-IN-HAND> field follows the pattern:

<UPPERCASE-PIECES>/<LOWERCASE-PIECES>

Where:

Encoding Rules

Player Separation

Piece Representation

Sorting Rules

Within each player’s section (uppercase or lowercase), pieces are sorted by:

  1. Quantity (descending): Pieces with higher quantities appear first
  2. Alphabetical order (ascending): Within the same quantity, pieces are sorted alphabetically by their base PNN representation

Complete Sorting Examples

Valid formats:

Note: Unlike the board representation, pieces in hand cannot have modifiers like +, -, or ' because captured pieces revert to their base form.


Field 3: <GAMES-TURN>

This field identifies the game type associated with each player and specifies whose turn it is.

Pencil sketch of two flags labeled 'CHESS' and 'Shogi', illustrating the games-turn field in FEEN notation that identifies game types and active player

Format Structure

This dual function enables attribution of pieces to game systems and identification of the player to move, even in hybrid configurations.

Game Identifier Recommendations

While FEEN allows any alphabetic game identifiers, the following conventions are recommended for common games:

Game Uppercase Lowercase
Chess CHESS chess
Janggi JANGGI janggi
Makruk MAKRUK makruk
Shōgi SHOGI shogi
Xiangqi XIANGQI xiangqi

Turn Determination Examples


Complete Examples

Standard 2D Game Positions

The following are examples of valid FEEN strings representing positions from various games. These are for illustration only — FEEN does not define or assume any game-specific rules.

Same-Game Examples

Cross-Game Examples

3D Game Position


GAN Conversion Examples

These examples demonstrate how FEEN positions can be converted to GAN identifiers:

Example 1: Pure Chess Game

FEEN: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR / CHESS/chess"

GAN Conversions:

- "R" (a1) → "CHESS:R"
- "r" (a8) → "chess:r"
- "P" (a2) → "CHESS:P"
- "p" (a7) → "chess:p"

Example 2: Shōgi with Captures (Identical Games)

FEEN: "lnsgkg1nl/1r7/ppp1ppppp/3p5/9/2P6/PP1PPPPPP/1B5R1/LNSGKGSNL 2PB/pr SHOGI/shogi"

GAN Conversions (pieces in hand):

- "2P" (uppercase hand) → "SHOGI:P" (2 pieces now owned by Shōgi sente player)
- "B" (uppercase hand) → "SHOGI:B" (1 piece now owned by Shōgi sente player)
- "p" (lowercase hand) → "shogi:p" (1 piece now owned by Shōgi gote player)
- "r" (lowercase hand) → "shogi:r" (1 piece now owned by Shōgi gote player)

Note: Since both players use the same game system, piece behavior remains consistent

Example 3: Cross-Game Scenario

FEEN: "acegast/7/ppppppp/7/7/PPPPPPP/7/KQRBNPJ PN/2ac FOO/bar"

GAN Conversions:

- Board pieces: "K" → "FOO:K", "a" → "bar:a"
- FOO hand: "P" → "FOO:P", "N" → "FOO:N" (current ownership by FOO player)
- bar hand: "2a" → "bar:a", "c" → "bar:c" (current ownership by bar player)

Note: GAN inference reflects current ownership; original piece identity is not preserved in FEEN

Example 4: With Promoted Pieces

FEEN: "lnsgkg1nl/1r5+P1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL / SHOGI/shogi"

GAN Conversions:
- "l" (a9) → "shogi:l"
- "L" (a1) → "SHOGI:L"
- "+P" (h8) → "SHOGI:+P" (promoted pawn on board - modifiers allowed on board)

Design Considerations

For Game Designers

When designing games that will use FEEN representation:

  1. Same-Game Approach (Simplest):
    • Use identical game systems for both players
    • Natural support for capture and redeployment mechanics
    • No ambiguity concerns
    • Example: SHOGI/shogi, CHESS/chess
  2. Cross-Game Approach (More Complex):
    • Consider whether piece identity after capture matters for your game rules
    • If pieces assimilate into the capturing player’s system, overlapping PNN is acceptable
    • If original piece behavior must be preserved, consider disjoint PNN sets or external tracking
  3. Capture Mechanics:
    • Removal games (like traditional Chess): No capture ambiguity concerns
    • Redeployment games (like Shōgi): Consider piece identity requirements

For Application Developers

When implementing FEEN support:

  1. Rule-Agnostic Applications: FEEN provides sufficient information for position storage and display
  2. Game Engines: May need additional metadata to track original piece identities in cross-game scenarios
  3. Database Systems: FEEN canonical format excellent for position indexing and comparison

For Cross-Game Scenarios

Consider these approaches based on your needs:

  1. Assimilation Model: Captured pieces adopt the behavior of the capturing player’s game system
    • Simpler implementation
    • FEEN representation is sufficient
    • Example: Captured xiangqi:a becomes functionally equivalent to CHESS:a
  2. Preservation Model: Captured pieces retain their original game behavior
    • More complex but potentially more interesting gameplay
    • May require additional metadata beyond FEEN
    • Example: Captured xiangqi:a retains xiangqi movement rules even when owned by CHESS player

Formal Grammar (BNF)

The following Backus-Naur Form (BNF) grammar defines the FEEN format. It supports arbitrarily nested board dimensions through a recursive structure of dimension groups, and describes all three main fields.

<feen> ::= <piece-placement> <whitespace> <pieces-in-hand> <whitespace> <games-turn>
<whitespace> ::= " "

Piece Placement (Recursive n-Dimensional Support)

<piece-placement> ::= <dim-group>

<dim-group> ::= <dim-element>
             | <dim-element> <dim-separator> <dim-group>

<dim-element> ::= <dim-group>        ; nested dimension (recursive case)
               | <rank>              ; base case: 1D sequence of cells

<rank> ::= <cell>
        | <cell> <rank>

<cell> ::= <piece> | <number>

<piece> ::= <pnn-piece>              ; As defined in the PNN specification

<number> ::= <non-zero-digit>
          | <non-zero-digit> <digits>

<non-zero-digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<digit> ::= "0" | <non-zero-digit>
<digits> ::= <digit>
          | <digit> <digits>

<dim-separator> ::= <slash> <separator-tail>
<separator-tail> ::= ""                  ; base level: one slash
                  | <slash> <separator-tail> ; additional nesting: //, ///, etc.

<slash> ::= "/"

Pieces in Hand (Base Form Only)

<pieces-in-hand> ::= <uppercase-pieces> <slash> <lowercase-pieces>

<uppercase-pieces> ::= ""
                    | <uppercase-sequence>

<lowercase-pieces> ::= ""
                    | <lowercase-sequence>

<uppercase-sequence> ::= <uppercase-entry>
                      | <uppercase-entry> <uppercase-sequence>

<lowercase-sequence> ::= <lowercase-entry>
                      | <lowercase-entry> <lowercase-sequence>

<uppercase-entry> ::= <base-piece-uppercase>
                   | <count> <base-piece-uppercase>

<lowercase-entry> ::= <base-piece-lowercase>
                   | <count> <base-piece-lowercase>

<base-piece-uppercase> ::= <letter-uppercase>  ; Base form only, no modifiers
<base-piece-lowercase> ::= <letter-lowercase>  ; Base form only, no modifiers

<count> ::= <digit-2-9>
         | <digit-1-9> <digits>

<digit-2-9> ::= "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<digit-1-9> ::= "1" | <digit-2-9>
<digit> ::= "0" | <digit-1-9>
<digits> ::= <digit>
          | <digit> <digits>

<slash> ::= "/"

<letter-lowercase> ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j"
                    | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t"
                    | "u" | "v" | "w" | "x" | "y" | "z"

<letter-uppercase> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J"
                    | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T"
                    | "U" | "V" | "W" | "X" | "Y" | "Z"

Game Turn

<games-turn> ::= <game-id-uppercase> <slash> <game-id-lowercase>
              | <game-id-lowercase> <slash> <game-id-uppercase>

<slash> ::= "/"

<game-id-uppercase> ::= <identifier-uppercase>
<game-id-lowercase> ::= <identifier-lowercase>

<identifier-uppercase> ::= <letter-uppercase>
                        | <letter-uppercase> <identifier-uppercase>

<identifier-lowercase> ::= <letter-lowercase>
                        | <letter-lowercase> <identifier-lowercase>

Invalid FEEN Examples

The following examples illustrate common mistakes and constraint violations:

# Invalid: pieces in hand cannot have modifiers
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL +P/ SHOGI/shogi

# Invalid: numeric prefix "1" is forbidden
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL 1P/ SHOGI/shogi

# Invalid: pieces not sorted by quantity then alphabetically
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL P3K/ SHOGI/shogi

# Invalid: both game names have same casing
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR / CHESS/MAKRUK

# Invalid: numeric prefix starting with "0"
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL 02P/ SHOGI/shogi

# Invalid: missing separator slash in pieces-in-hand field
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL 2P SHOGI/shogi

# Invalid: uppercase piece in lowercase section
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPP/1B5R1/LNSGKGSNL /2pP SHOGI/shogi

# Invalid: lowercase piece in uppercase section
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL 2Pp/ SHOGI/shogi

Use Cases and Limitations

Ideal Use Cases

Known Limitations

  1. Two-player restriction - Cannot represent games with more than two players
  2. 26-piece limit - Maximum of 26 unique piece types per player due to ASCII constraints
  3. No rule encoding - Cannot represent game-specific legality constraints
  4. Static positions only - Cannot encode move history or dynamic game state
  5. Original piece identity - In cross-game scenarios with overlapping PNN, original game system of captured pieces is not preserved

FEEN vs GGN Comparison

Aspect FEEN GGN
Purpose Static position representation Pseudo-legal move description
Piece Ownership Dynamic ownership support Case correspondence only
Scope Complete game state snapshot Board transformations only
Hand Management Explicit captured pieces support Not supported
Multi-dimensional Full support Board squares only
Cross-game Support Flexible with considerations Flexible case-based

FEEN is part of a family of specifications designed to provide a comprehensive and rule-agnostic representation system for abstract strategy board games:


FEEN Implementations

This section lists available libraries and tools that implement the FEEN specification, allowing developers to easily integrate this format into their applications.

Ruby