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
- FEEN is rule-agnostic and does not encode legality, move counters, or game-specific conditions.
- FEEN enforces a canonical representation, ensuring that equivalent positions yield identical strings.
- FEEN supports hybrid or cross-game positions involving different piece sets.
- FEEN supports arbitrary-dimensional board configurations for games like 3D chess variants.
- FEEN is suitable for static storage, comparison, and visual reconstruction of positions.
- FEEN provides piece identification through case-based ownership determination.
Constraints
- FEEN supports exactly two players.
- A maximum of 26 unique pieces per player is allowed, as identifiers must be mapped to
a-z
orA-Z
. - Players must be assigned distinct casing (uppercase/lowercase) for their associated game identifiers to ensure proper disambiguation.
Format
A FEEN record consists of the following three space-separated fields:
<PIECE-PLACEMENT>
— Specifies the configuration of pieces on the board, possibly in multiple dimensions.<PIECES-IN-HAND>
— Lists any off-board pieces available to each player, separated by player and sorted within each player group.<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
- Pieces are denoted using single ASCII characters
a-z
orA-Z
. - Case distinguishes between players (uppercase for first player, lowercase for second).
- Optional modifiers may be applied to pieces on the board only:
- Prefix: “
-
” (diminished state) or “+
” (enhanced state) - Suffix: “
'
” (intermediate state)
- Prefix: “
- The specific meaning of modifiers depends on the game context, but FEEN remains agnostic about their interpretation.
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:
- The appropriate game identifier from
<GAMES-TURN>
based on the piece’s current ownership (case) - The piece’s PNN representation
GAN Inference Rules
- Uppercase pieces → Use the uppercase game identifier from
<GAMES-TURN>
- Lowercase pieces → Use the lowercase game identifier from
<GAMES-TURN>
Example
Given FEEN position:
lnsiksnl/1b4r1/pppppppp/8/4P3/PPPP1PPP/8/RNSKMSNR / ogi/MAKRUK
- Lowercase “
n
” pieces → GAN: “ogi:n
” - Lowercase “
k
” pieces → GAN: “ogi:k
” - Uppercase “
K
” pieces → GAN: “MAKRUK:K
”
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
- Dynamic Ownership: A piece’s current owner is determined by its case in the FEEN position
- Capture Support: Pieces can be captured and moved to the opponent’s hand
- Redeployment: Captured pieces can be placed back on the board under new ownership
- 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:
- Cross-game scenarios where different games use overlapping PNN identifiers
- Piece behavior differs between games (e.g., “
CHESSGAME:R
” moves differently than chessgame:r) - Game engines need to apply different rules based on original piece identity
When This Doesn’t Matter
This ambiguity is not a concern when:
- Same-game scenarios (e.g., “
SHOGI/shogi
”) - all pieces belong to the same system - Capture-removal games (like traditional Chess) where captured pieces are removed from play
- Intentional design where captured pieces are meant to assimilate into the capturing player’s game system
- 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.
Encoding Rules
- The board is traversed starting from the outermost dimension and proceeding inward, dimension by dimension.
- Pieces are denoted using PNN notation (including modifiers for pieces on the board).
- Empty spaces are compressed using digits
1
-n
, representing consecutive empty cells. - Dimension separators:
/
separates consecutive elements of the first inner dimension.- Each higher-level dimension adds an additional
/
, resulting in//
,///
, etc.
- Pieces are not separated by delimiters; their identity and grouping are inferred from their individual characters.
Multi-Dimensional Support
This generalization allows FEEN to describe n-dimensional boards with arbitrary shapes:
- 2D boards: Standard format with
/
separators between ranks - 3D boards: Use
//
to separate planes,/
to separate ranks within planes - Higher dimensions: Continue pattern with additional
/
characters
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.
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:
<UPPERCASE-PIECES>
represents pieces currently owned by the first player (uppercase game identifier)<LOWERCASE-PIECES>
represents pieces currently owned by the second player (lowercase game identifier)- The separator
/
is always present, even when one or both sides have no pieces
Encoding Rules
Player Separation
- Left side (before
/
): Contains only pieces currently owned by the uppercase player - Right side (after
/
): Contains only pieces currently owned by the lowercase player - If a player has no pieces in hand, their side remains empty (but the
/
separator is still present)
Piece Representation
- Pieces are represented using their base PNN identifiers only (no prefixes or suffixes)
- Quantity notation:
- Single occurrence: no numeric prefix (e.g., “
P
”, “K
”, “R
”) - Multiple occurrences: numeric prefix required (e.g., “
2P
”, “3K
”, “5R
”) - The numeric prefix cannot be “
0
” or “1
”
- Single occurrence: no numeric prefix (e.g., “
Sorting Rules
Within each player’s section (uppercase or lowercase), pieces are sorted by:
- Quantity (descending): Pieces with higher quantities appear first
- Alphabetical order (ascending): Within the same quantity, pieces are sorted alphabetically by their base PNN representation
Complete Sorting Examples
Valid formats:
/
(no pieces for either player)5P3B2R/
(first player has pieces, second player has none)/3p2qr
(first player has none, second player has pieces)10P5K3B/2pr
(both players have pieces)
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.
Format Structure
- The format is
<FIRST-GAME>/<SECOND-GAME>
, where:- The first name refers to the player to move.
- The second name refers to the opponent.
- Each name consists of alphabetic characters and must be valid identifiers.
- Casing is semantically significant: one name must be uppercase, the other lowercase.
- The uppercase name identifies the game system associated with uppercase-cased pieces.
- The lowercase name identifies the game system associated with lowercase-cased pieces.
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
CHESS/chess
- Chess white player (uppercase pieces) to moveshogi/SHOGI
- Shōgi gote player (lowercase pieces) to movechess/XIONGQI
- Chess black player (lowercase pieces) to move in a hybrid game
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
- Chess initial position:
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR / CHESS/chess
- Chess position after 1.e4:
rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR / chess/CHESS
- Shōgi initial position:
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL / SHOGI/shogi
- Shōgi mid-game with captures:
lnsgkg1nl/1r7/ppp1ppppp/3p5/9/2P6/PP1PPPPPP/1B5R1/LNSGKGSNL 2PB/pr SHOGI/shogi
Cross-Game Examples
- Chess vs Ōgi:
lnsiksnl/1b4r1/pppppppp/8/8/8/PPPPPPPP/RNBQKBNR / CHESS/ogi
- Custom hybrid games:
abcdef/6/6/6/6/GHIJKL / ALPHA/beta
3D Game Position
- Raumschach (3D Chess) initial position:
rnknr/ppppp/5/5/5//buqbu/ppppp/5/5/5//5/5/5/5/5//5/5/5/PPPPP/BUQBU//5/5/5/PPPPP/RNKNR / RAUMSCHACH/raumschach
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:
- 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
- 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
- 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:
- Rule-Agnostic Applications: FEEN provides sufficient information for position storage and display
- Game Engines: May need additional metadata to track original piece identities in cross-game scenarios
- Database Systems: FEEN canonical format excellent for position indexing and comparison
For Cross-Game Scenarios
Consider these approaches based on your needs:
- 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
- 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
- Game position storage and transmission - Compact representation of game states
- Cross-game analysis - Comparing positions across different game variants
- Database indexing - Canonical format for position-based searches
- Capture-and-drop games - Natural support for Shōgi-style mechanics
- Hybrid game support - Representing positions combining multiple game systems
- 3D and multi-dimensional games - Extending beyond traditional 2D boards
Known Limitations
- Two-player restriction - Cannot represent games with more than two players
- 26-piece limit - Maximum of 26 unique piece types per player due to ASCII constraints
- No rule encoding - Cannot represent game-specific legality constraints
- Static positions only - Cannot encode move history or dynamic game state
- 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 |
Related Specifications
FEEN is part of a family of specifications designed to provide a comprehensive and rule-agnostic representation system for abstract strategy board games:
- Piece Name Notation (PNN) - Defines the format for representing individual pieces and their states. Critical for FEEN’s piece identification.
- General Actor Notation (GAN) - Provides a game-qualified piece identifier format that can be inferred from FEEN positions based on current ownership.
- General Gameplay Notation (GGN) - Describes pseudo-legal moves and board transformations (complementary to FEEN’s static representation).
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
- Feen.rb - Full implementation of the FEEN specification for Ruby, including conversion from/to various formats, as well as support for hybrid games and arbitrary dimensions.