Field Expression Encoding Notation (FEEN) Specification
- Version: 1.0.0
- Author: Cyril Kato
- Published: May 1, 2025
- License: Open Web Foundation Agreement 1.0
1. Status of this document
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as normative requirements.
Capitalized terms (Game, Match, Position, Board, Square, Hand, Piece, Piece Side, Piece State, Piece Style, Terminal Status, Active Player, Player Side) are defined in the Glossary.
FEEN does not redefine these concepts; it specifies how to encode a protocol-level Position.
2. Overview
Field Expression Encoding Notation (FEEN) is a rule-agnostic Position encoding for two-Player, turn-based board games built on the Sashité Game Protocol.
A FEEN string encodes exactly:
- Board structure and occupancy (which Squares exist and which Pieces occupy them),
- Hands (multisets of off-board Pieces located in each Player’s Hand),
- Side Styles and the Active Player.
FEEN is designed to be:
- Protocol-aligned (structurally compatible with the Game Protocol’s Position model),
- Compact (run-length encoding for empty Squares; multiplicities for Hands),
- Canonical (a valid FEEN string is always in canonical form).
3. Scope and non-goals
3.1 What FEEN defines
FEEN defines:
- a concrete wire-format for serializing a Position into three textual fields,
- the lexical and syntactic rules needed to parse those fields,
- canonicalization rules for the structure and ordering of those fields,
- dimensional coherence rules for multi-dimensional Boards,
- cardinality constraints inherited from the Game Protocol.
3.2 What FEEN does not define
FEEN does not define:
- movement rules, legality, outcomes, or any Rule System semantics,
- clocks, counters, repetition policy, Move numbers, or History,
- the geometric meaning of ranks/layers/dimensions (beyond preserving separators),
- the mapping from Style letters to concrete rule families (that is external configuration),
- the mapping from the Piece Placement stream to a Board’s geometry, except via an externally-defined Board serialization scheme,
- which EPIN tokens should be used to represent a given Piece (that is the responsibility of the producer’s Game context).
4. Dependencies
FEEN depends on:
- EPIN for encoding Pieces as tokens (Piece Placement and Hands),
- SIN for encoding Side Styles in the Style–Turn field.
Token validity for EPIN and SIN is defined by their respective specifications.
5. Conformance
A valid FEEN string MUST satisfy:
- the syntactic rules defined in this specification,
- the canonicalization rules defined in this specification,
- the dimensional coherence rules defined in this specification,
- the cardinality constraints defined in this specification.
Requirements:
- Producers (encoders) MUST output valid FEEN.
- Consumers (decoders) MUST accept valid FEEN.
- Consumers MUST reject FEEN strings that violate dimensional coherence or cardinality constraints.
- Consumers SHOULD reject non-canonical FEEN strings.
6. Overall format
A FEEN string consists of three fields separated by single ASCII space characters:
<PIECE-PLACEMENT> <HANDS> <STYLE-TURN>
6.1 Whitespace and line discipline
- A FEEN string MUST NOT contain leading or trailing whitespace.
- Fields MUST be separated by exactly two ASCII spaces total (one between field 1 and 2, one between field 2 and 3).
- Tabs and other whitespace characters MUST NOT appear anywhere in the string.
- Line breaks (
\ror\n) MUST NOT appear anywhere in the string.
6.2 Character set
FEEN is an ASCII-only format.
Implementations MUST reject any non-ASCII input.
7. Field 1 — Piece Placement
The Piece Placement field encodes Board structure and occupancy as a stream of tokens organized into a hierarchical structure of segments separated by separator groups of one or more slash characters (/).

7.1 Board serialization scheme (required external context)
To interpret a Piece Placement stream as Squares on a Board, the surrounding Game context MUST define a deterministic Board serialization scheme, including:
- the exact Square traversal order, and
- the dimensional interpretation of separator groups.
FEEN preserves segment separators and their multiplicity, encoding dimensional structure without assigning geometric meaning.
7.2 Dimensional model
FEEN encodes multi-dimensional Boards using a hierarchical separator system:
- A separator group of N slashes (
/repeated N times) separates structures of dimension N. - A separator group of 1 slash separates rank-level segments (dimension 1).
- A separator group of 2 slashes separates layer-level structures (dimension 2).
- A separator group of 3 slashes separates cube-level structures (dimension 3).
- And so on for higher dimensions.
Examples:
| Dimensions | Structure | Separator pattern |
|---|---|---|
| 1D | Single sequence of Squares | No separators |
| 2D | Ranks separated by / |
rank/rank/rank |
| 3D | Layers (each containing ranks) separated by // |
rank/rank//rank/rank |
| 4D | Cubes (each containing layers) separated by /// |
layer//layer///layer//layer |
7.3 Segments and separators
- The Piece Placement field consists of one or more segments.
- Segments are separated by one or more
/characters (a separator group). - The field MUST NOT start with
/and MUST NOT end with/.
7.4 Dimensional coherence
If a separator group of length N (N ≥ 2) appears in the Piece Placement field, then each segment it separates MUST contain at least one separator group of length N-1.
This rule applies recursively: a structure separated by // must contain / separators, a structure separated by /// must contain // separators (which in turn must contain / separators), and so on.
Rationale: This constraint ensures that dimensional structure is consistent and that no intermediate dimension is omitted. A Board cannot “skip” from dimension 1 directly to dimension 3.
Valid examples:
| Piece Placement | Structure | Why valid |
|---|---|---|
rkr |
1D (3 squares) | No separators needed |
rkr/PPPP |
2D (2 ranks) | / separates segments |
a/b//c/d |
3D (2 layers × 2 ranks) | // separates structures containing / |
a/b/c//d/e/f |
3D (2 layers, 3 ranks each) | // separates structures containing / |
a/b//c/d//e/f |
3D (3 layers × 2 ranks) | // separates structures containing / |
a/b//c/d///e/f//g/h |
4D (2 cubes × 2 layers × 2 ranks) | /// separates structures containing // |
Invalid examples:
| Piece Placement | Why invalid |
|---|---|
rkr//PPPP |
// used but segments lack / |
a//b//c |
// used but segments lack / |
a/b///c/d |
/// used but segments lack // |
a///b |
/// used but segments lack // and / |
7.5 Placement tokens
Within each segment, the content is a concatenation of placement tokens:
-
Empty-count token
- A base-10 integer representing a run of empty Squares.
- The integer MUST be ≥ 1.
- The integer MUST NOT contain leading zeros.
-
Piece token
- A syntactically valid EPIN token.
7.6 Parsing rule (unambiguous scanning)
Within a segment, parsing is performed left-to-right:
- If the next character is a digit, read the maximal consecutive digit sequence and interpret it as an Empty-count token.
- Otherwise, read the maximal substring that forms a valid EPIN token (per EPIN), and interpret it as a Piece token.
Because EPIN tokens do not begin with digits, Empty-count tokens and Piece tokens are unambiguous under this scanning rule.
7.7 Canonical Piece Placement
Within a segment:
- Empty-count tokens MUST be encoded as minimal base-10 integers with no leading zeros.
- Consecutive empty Squares MUST be merged into a single Empty-count token.
The segment/separator structure is dictated by the Game context’s Board serialization scheme.
8. Field 2 — Hands
The Hands field encodes the two protocol Hands:
<FIRST-HAND>/<SECOND-HAND>
- The
/delimiter in the Hands field is always present. - Either Hand may be empty (encoded as the empty string).

8.1 Hand items
Each Hand is a concatenation of hand items with no separators:
[<count>]<piece>
Where:
<piece>is a valid EPIN token.<count>is an optional base-10 integer indicating multiplicity of that exact<piece>token.
Count rules:
- If
<count>is absent, the multiplicity is exactly 1. - If
<count>is present, it MUST be ≥ 2. <count>MUST NOT contain leading zeros.
8.2 Parsing rule (unambiguous scanning)
Within a Hand, parsing is performed left-to-right:
- If the next character is a digit, read the maximal digit sequence as
<count>, then read the following EPIN token as<piece>. - Otherwise, read the next EPIN token as
<piece>with an implicit multiplicity of 1.
8.3 Hand attribution
The position relative to the Hands delimiter determines which Hand is being described:
- left of
/→ First Player Hand, - right of
/→ Second Player Hand.
The Piece Side encoded inside the EPIN token remains a property of the Piece itself and is independent of the Hand’s associated Side. A Piece with Piece Side first may be located in the Second Player Hand, and vice versa.
8.4 Canonical Hands
-
Identical EPIN tokens MUST be aggregated into a single hand item with the appropriate count (omitting the count only when the total is 1).
-
Hand items MUST be ordered using the following comparator (stable total order):
- By multiplicity — descending (larger counts first)
- By base letter — case-insensitive alphabetical order
- By letter case — uppercase before lowercase
- By state modifier —
-before+before none - By terminal marker — absent before present
- By derivation marker — absent before present
Ties after all keys are impossible if EPIN tokens are identical, which would have been aggregated.
9. Field 3 — Style–Turn
The Style–Turn field encodes:
- the native Piece Style associated with each Player Side, and
- the identity of the Active Player.
Format:
<ACTIVE-STYLE>/<INACTIVE-STYLE>
Where each STYLE is a valid SIN token (exactly one ASCII letter).

9.1 Side attribution (by case)
- The uppercase SIN token (A–Z) specifies the Style associated with Player Side
first. - The lowercase SIN token (a–z) specifies the Style associated with Player Side
second.
This attribution is by token case and is independent of Turn order.
9.2 Turn attribution (by position)
<ACTIVE-STYLE>identifies the Active Player (to move next).<INACTIVE-STYLE>identifies the Inactive Player.
Therefore:
- If
<ACTIVE-STYLE>is uppercase, the Active Player’s Player Side isfirst. - If
<ACTIVE-STYLE>is lowercase, the Active Player’s Player Side issecond.
9.3 Structural constraints
The two STYLE tokens:
- MUST be of opposite case (one uppercase and one lowercase),
- MUST each be a valid SIN token.
10. Formal grammar (syntactic)
This grammar describes FEEN’s structure at the container level and delegates EPIN/SIN token validity to their respective specifications.
10.1 Core terminals
SPis the ASCII space character0x20.SLASHis/.DIGITis0–9.NONZEROis1–9.
10.2 Grammar (EBNF)
feen ::= piece_placement SP hands SP style_turn ;
piece_placement ::= segment ( slash_group segment )* ;
slash_group ::= SLASH+ ;
segment ::= placement_token+ ;
placement_token ::= empty_count | epin_token ;
empty_count ::= NONZERO DIGIT* ;
hands ::= hand SLASH hand ;
hand ::= hand_item* ;
hand_item ::= (hand_count epin_token) | epin_token ;
hand_count ::= NONZERO DIGIT* ; (* semantic constraint: value >= 2 when present *)
style_turn ::= sin_token SLASH sin_token ;
Where:
epin_tokenis any token accepted as valid by the EPIN specification.sin_tokenis any token accepted as valid by the SIN specification.
Note: The grammar permits any slash_group length. The dimensional coherence constraint (§7.4) is a semantic rule applied after syntactic parsing.
11. Validation requirements
11.1 Syntactic validation (required)
An implementation MUST:
- Enforce the whitespace rules and reject any line breaks.
- Split the input into exactly three fields on ASCII spaces (two separators).
-
Validate Field 1:
- does not start or end with
/, - consists of segments separated by one or more
/, - each segment parses into a non-empty sequence of placement tokens,
- each Piece token is a valid EPIN token,
- each empty-count is an integer ≥ 1 with no leading zeros.
- does not start or end with
-
Validate Field 2:
- contains exactly one
/delimiter, - each Hand parses into zero or more hand items,
- each Piece token is a valid EPIN token,
- each explicit count is an integer ≥ 2 with no leading zeros.
- contains exactly one
-
Validate Field 3:
- contains exactly one
/delimiter, - each Style token is a valid SIN token,
- the two Style tokens are of opposite case.
- contains exactly one
11.2 Canonicality validation (required)
An implementation MUST reject FEEN strings that violate the canonicalization rules:
- Empty-count tokens must be minimal (no leading zeros, consecutive empties merged).
- Hand items must be aggregated and ordered according to the canonical ordering.
11.3 Dimensional coherence validation (required)
An implementation MUST reject FEEN strings that violate dimensional coherence:
If a separator group of length N (where N ≥ 2) appears in the Piece Placement field, then each segment it separates MUST contain at least one separator group of length N-1.
Algorithm sketch:
- Find the maximum separator group length M in the Piece Placement field.
- If M = 1, the Board is 2D; no further checks needed.
- If M ≥ 2, recursively verify:
- Split by separator groups of length M.
- Each resulting part must contain at least one separator group of length M-1.
- Repeat for M-1, M-2, …, down to 2.
11.4 Cardinality validation (required)
An implementation MUST reject FEEN strings that violate the cardinality constraints inherited from the Game Protocol.
Let:
- n = the total number of Squares on the Board, computed as the sum of all empty-count values plus the number of Piece tokens in Field 1.
- p = the total number of Pieces, computed as the number of Piece tokens in Field 1 plus the sum of all multiplicities in Field 2.
The following constraints MUST be satisfied:
| Constraint | Requirement | Rationale |
|---|---|---|
| Board non-empty | n ≥ 1 | A Board must contain at least one Square |
| Piece cardinality | p ≤ n | The number of Pieces cannot exceed the number of Squares |
Note: A Position with zero Pieces (p = 0) is valid, provided the Board contains at least one Square.
Examples:
| FEEN string | n | p | Valid? | Reason |
|---|---|---|---|---|
k^ / S/s |
1 | 1 | ✓ | 0 ≤ 1 ≤ 1 |
8/8/8/8/8/8/8/8 / S/s |
64 | 0 | ✓ | 0 ≤ 0 ≤ 64 |
1 / G/g |
1 | 0 | ✓ | 0 ≤ 0 ≤ 1 |
K^k^ 2K^/2k^ S/s |
2 | 6 | ✗ | p > n (6 > 2) |
11.5 Extended validation (optional, context-dependent)
If the Game context is known, implementations MAY additionally validate:
- that the total number of Squares implied by Piece Placement matches the Board serialization scheme,
- that the material represented across Board and Hands is consistent with Game-defined constraints,
- that Style configuration is consistent with any Rule System expectations.
12. Robustness considerations
Implementations SHOULD defend against resource abuse:
- impose reasonable maximum lengths on the overall FEEN string,
- impose reasonable limits on numeric token length and/or numeric value,
- impose reasonable limits on the maximum dimensionality (separator group length),
- avoid integer overflow by using bounded arithmetic or big integers with caps,
- reject inputs that cannot be parsed in linear time with bounded memory.
13. Design properties
FEEN is designed to be:
- Rule-agnostic (no assumptions about game rules or piece semantics),
- Protocol-aligned (structurally compatible with the Game Protocol’s Position model),
- Compact (run-length encoding for empty Squares; multiplicities for Hands),
- Multi-dimensional friendly (separator groups encode dimensional hierarchy with coherence guarantees),
- Canonical (valid FEEN strings are always in canonical form),
- Engine-friendly (suitable for hashing, caching, and repetition detection as a Position identity key).
14. Examples
See FEEN Examples for comprehensive usage patterns.
15. Reference Implementations
The following reference libraries are maintained by Sashité and are intended to be idiomatic, fully tested, and spec-accurate implementations of FEEN v1.0.0.
They generally provide:
- strict parsing and validation (
valid?,parse, and a raising/bang variant), - round-trip serialization (FEEN string ⇄ structured Position representation),
- field extraction (
piece_placement,hands,style_turn), - canonical form enforcement,
- dimensional coherence validation,
- cardinality constraint validation,
- clear error reporting for invalid inputs,
- extended validation when Game context is available.
If a library behavior appears to conflict with this document, this specification is normative. Please report issues (or propose clarifications) on the relevant repository.
16. License
This specification is made available under the terms of the Open Web Foundation Agreement 1.0 (OWFa 1.0).
The authoritative legal text is the OWF “Final Specification Agreement (OWFa 1.0)”.
