Piece Name Notation (PNN) Specification
- Version: 1.0.0
- Author: Cyril Kato
- Published: September 4, 2026
- 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, Rule System, Piece, Piece Name, Piece Side, Side) are defined in the Glossary. This document does not redefine those terms.
2. Overview
Piece Name Notation (PNN) is the smallest piece notation of the Sashité ecosystem: a single ASCII letter that names a Piece.
A PNN token encodes exactly two attributes:
- Piece Name → the letter, read case-insensitively (
Kandkname the same Piece), - Piece Side → the case of the letter (uppercase for Side
first, lowercase for Sidesecond).
PNN is a primitive. It is the <name> component of PIN, and therefore, transitively, of EPIN, QPI and every notation built on them. Anything a Piece may carry beyond its Name and its Side — a state modifier, a terminal marker, a derivation marker, a Style — is added by those notations, never by PNN.
2.1 Scope
PNN defines only:
- the syntax of a token (one letter),
- how the letter maps to the Piece Name and the Piece Side.
2.2 Non-goals
PNN does not define:
- which letter names which Piece (the mapping is chosen by the Game or Rule System),
- Piece State, Terminal Status, Piece Style, or native/derived status,
- how Pieces move, capture, promote, or are dropped,
- how Players are named (white/black, sente/gote, …).
Those belong to the notations that build on PNN, or to the Rule System.
3. Dependencies
PNN is self-contained and has no dependencies on other Sashité specifications.
4. Token format
4.1 Structure
A PNN token is exactly one ASCII letter:
<letter>
4.2 Grammar (EBNF)
pnn ::= letter ;
letter ::= "A"…"Z" | "a"…"z" ;
4.3 Regular expression
A PNN token MUST match the following regular expression, anchored to the whole string:
^[A-Za-z]$
Anchoring requirement (normative):
- Implementations MUST ensure the anchors apply to the entire input string, not to individual lines.
- If the target regex engine interprets
^and$as line anchors under a multiline mode, implementations MUST disable that mode or use the engine’s “string anchors” equivalents to preserve whole-string matching.
Notes for implementers:
- Tokens are case-sensitive as strings (
K≠k), even though the Piece Name they carry is the same (§5.1). - Any surrounding whitespace is invalid for a token; whitespace handling, if any, belongs to the surrounding container format.
5. Attribute mapping
A conforming implementation MUST interpret a valid token as follows.
5.1 Piece Name
The letter is a single-letter abbreviation of the Piece Name, assigned by convention within a Game or Rule System — K for a king, R for a rook, I for the ōgi princess, E for the xiongqi empress.
The identity of the abbreviation is case-insensitive: R and r are the same Piece Name, held by different Sides. A Rule System therefore disposes of 26 Piece Names.
PNN reserves no letter. The mapping from letter to Piece Name is entirely Rule System-defined, and a Rule System SHOULD keep it stable, unambiguous, and documented within a given Game context.
5.2 Piece Side
The case of the letter encodes the Piece Side:
- uppercase (
A–Z) → Piece Sidefirst, - lowercase (
a–z) → Piece Sidesecond.
This is the two-Side model of the Glossary. PNN encodes the Side of the Piece, not of the Player who controls it: per the Glossary, a Piece Side may differ from the Player Side of its holder (a captured Piece kept in the opponent’s case, for instance) and may change during a Match if the Rule System permits. The two notions coincide in most positions, but PNN only ever states the former.
6. Parsing and conformance requirements
6.1 Validity
A string is a valid PNN token if and only if it matches the grammar in §4.2 (or the regex in §4.3) and contains no other character.
Implementations:
- MUST reject invalid tokens,
- SHOULD provide a non-raising validity predicate (e.g.
valid?), - MAY provide a raising/bang parser variant.
6.2 Canonical form
A PNN token is canonical by construction. Implementations MUST NOT normalize a token — in particular, they MUST NOT change its case, since the case is an attribute of the Piece, not a presentation choice.
6.3 Component extraction
Implementations SHOULD provide accessors for each attribute:
| Accessor | Description |
|---|---|
name |
The abbreviation, case-insensitive (conventionally returned uppercase) |
side |
first or second |
Two tokens have the same Piece Name if and only if their name accessors are equal.
7. Design considerations
7.1 Character space
PNN provides 26 Piece Names × 2 Sides = 52 distinct tokens. Every notation built on PNN multiplies this space by its own attributes (PIN: 3 states × 2 terminal statuses = 312 tokens).
7.2 Two-Side assumption
PNN encodes exactly two Piece Sides using case. Games with more than two Sides MUST use a convention outside the scope of PNN, or a different notation.
7.3 One letter per Piece Name
A Piece whose identity differs from another’s in the Rule System — a promoted form with a different movement, a piece of another tradition sharing a name — needs its own letter, or an attribute added by a higher notation (a PIN state modifier, a QPI Style). PNN does not arbitrate: it only guarantees that two tokens with the same letter, whatever their case, name the same Piece.
8. Relationship to other specifications
| Specification | Uses PNN as |
|---|---|
| PIN | the <name> component, framed by an optional state modifier and an optional terminal marker |
| EPIN | inherited through PIN, with an optional derivation marker |
| QPI | inherited through PIN, qualified by a SIN Style letter |
PNN and SIN are the two single-letter primitives of the ecosystem: PNN names a Piece (and its Side), SIN names a Style (and a Side). They are independent; QPI combines them.
9. Examples
See PNN Examples for letter mappings in various Game contexts.
10. Reference implementations
The following reference libraries are maintained by Sashité and are intended to be idiomatic, fully tested, and spec-accurate implementations of PNN v1.0.0.
They generally provide:
- strict parsing and validation (
valid?,parse, and a raising/bang variant), - component extraction (
name,side), - clear error reporting for invalid inputs.
If a library behavior appears to conflict with this document, this specification is normative. Please report issues (or propose clarifications) on the relevant repository.
- Ruby — pnn.rb
11. 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)”.
