Portable Chess Notation (PCN) Specification
- Version: 1.0.0
- Author: Cyril Kato
- Published: June 17, 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 (Match, Position, Ply, Move, Action, Game, Rule System, Period, Piece, Piece Style, Player Side, Active Player) are defined in the Glossary and the Game Protocol.
2. Overview
Portable Chess Notation (PCN) is a format for recording complete Matches in abstract strategy board games built on the Sashité Game Protocol.
A PCN document encodes:
- metadata about the Match (rule system, site, start time, platform),
- links to external resources (canonical URL, related games),
- player information (variant, name, rating),
- time control configuration (periods with duration, increment, or ply quota),
- the initial Position (via FEEN or alternative notations),
- the sequence of Plies (single-player actions) with timing, assessment, and variations,
- the competitive outcome (result).
PCN is:
- format-agnostic — supports both TOML and JSON serialization,
- rule-agnostic — independent of any particular Rule System,
- notation-agnostic — supports PMN, SAN, UCI, or custom Ply representations,
- extensible — custom properties allowed without restricting semantic properties,
- composable — designed for storage, analysis, and replay.
3. Dependencies
PCN depends on:
- TOML v1.0.0 or JSON (RFC 8259) — the serialization formats.
PCN optionally depends on:
- FEEN — default Position encoding format.
- PMN — default Ply notation format.
- SNN — Style Name Notation for variant identification.
PCN permits alternative notations (FEN, SAN, UCI, etc.) via custom properties, delegating format validation to context-specific implementations.
4. Serialization formats
PCN documents MAY be serialized in either TOML or JSON.
4.1 Format detection
Implementations SHOULD detect the format by:
- File extension:
.tomlfor TOML,.jsonfor JSON. - Content inspection: presence of
[table headers indicates TOML;{as first non-whitespace character indicates JSON.
4.2 Structural equivalence
Both formats encode the same logical structure. The mapping is direct:
- TOML tables (
[name]) correspond to JSON objects. - TOML arrays of tables (
[[name]]) correspond to JSON arrays of objects. - TOML key-value pairs correspond to JSON properties.
4.3 Encoding
- TOML documents MUST be valid TOML v1.0.0 and encoded in UTF-8.
- JSON documents MUST be valid JSON per RFC 8259 and encoded in UTF-8.
5. Overall structure
A PCN document has the following top-level structure:
| Section | Type | Required | Description |
|---|---|---|---|
meta |
object | No | Match metadata |
links |
array | No | External resource links |
periods |
array | No | Time control periods |
sides |
object | No | Player information |
setup |
object | Yes | Initial Position |
plies |
array | No | Sequence of moves |
outcome |
object | No | Match result |
Only the setup section is required. All other sections are optional.
6. Meta object
The meta object encodes Match metadata (all properties optional):
| Property | Type | Description |
|---|---|---|
name |
string | Match/game name |
event |
string | Tournament or event label |
round |
string | Round identifier within an event |
site |
string | Venue (physical location or virtual platform) |
started_at |
datetime | Match start time in ISO 8601 format |
rule_system |
string | Rule system identifier (e.g., "standard", "antichess") |
platform_name |
string | Platform or application name (e.g., "lichess", "chess.com") |
comment |
string | Free-text narrative about the overall Match |
6.1 Datetime format
The started_at property MUST use ISO 8601 format:
- TOML: Native datetime type (
1620-01-01T00:00:00Z) - JSON: String in ISO 8601 format (
"1620-01-01T00:00:00Z")
7. Links array
The links array contains references to external resources:
| Property | Type | Required | Description |
|---|---|---|---|
rel |
string | Yes | Relationship type |
url |
string | Yes | URL of the linked resource |
7.1 Relationship types
Common rel values include:
| Value | Description |
|---|---|
"canonical" |
Authoritative URL for this Match |
"source" |
Original source of the game record |
"analysis" |
Link to analysis or commentary |
"video" |
Link to video coverage |
"next" |
Next game in a series |
"prev" |
Previous game in a series |
Custom relationship types are permitted.
8. Periods array
Time control is specified as an array of Period objects. Each entry describes one Period:
| Property | Type | Required | Description |
|---|---|---|---|
duration_ms |
integer >= 0 | Yes | Time budget in milliseconds |
increment_ms |
integer >= 0 | No | Fischer increment per Ply in milliseconds |
plies |
integer >= 1 | No | Move-count quota — time covers N plies, then repeats |
8.1 Time control semantics
- If both
increment_msandpliesare absent, the Period models a fixed time bank (duration depletes linearly). - If
increment_msis present withoutplies, the Period models Fischer time control. - If
pliesis present (with or withoutincrement_ms), it models quota-based time control (e.g., byōyomi, Canadian). - All Players share the same Periods (time control is Match-wide, not per-player).
8.2 Multi-period time control
When multiple Periods are specified, they are applied in sequence. A typical pattern is a main time bank followed by overtime periods.
9. Sides object
The sides object contains first and second player objects (both optional):
| Property | Type | Description |
|---|---|---|
variant |
string | Movement tradition in SNN format (e.g., "Chess", "Shogi") |
name |
string | Player name, handle, or identifier |
elo |
integer >= 0 | Rating (if applicable) |
All properties within each side are optional.
9.1 Variant property
The variant property, if present, MUST be a valid SNN token. It identifies the movement tradition or game family associated with that player’s pieces.
In standard games, both players typically have the same variant. In hybrid or cross-variant games, players MAY have different variants.
10. Setup object
The setup object describes the initial Position of the Match:
| Property | Type | Required | Description |
|---|---|---|---|
feen |
string | Conditional | Position in FEEN format |
10.1 Position notation requirement
At least one Position notation MUST be present. If feen is present, it is canonical. Alternative notations (e.g., fen, sfen) MAY be supplied as additional properties.
10.2 Custom notations
Implementations MAY recognize additional position notations:
| Property | Description |
|---|---|
fen |
Standard chess FEN |
sfen |
Shogi FEN variant |
If multiple notations exist, feen is preferred as canonical; others are informational.
11. Plies array
Plies are encoded as an array of objects. Each Ply records a single Player’s action in one turn.
11.1 Ply properties
| Property | Type | Required | Description |
|---|---|---|---|
pmn |
string | No | Move in PMN format |
feen |
string | No | Resulting Position in FEEN format |
elapsed_ms |
integer >= 0 | No | Time spent on this Ply in milliseconds |
assessment |
string (enum) | No | Move quality assessment |
comment |
string | No | Free-text narrative |
check |
boolean | No | Whether this move delivers check |
mate |
boolean | No | Whether this move delivers checkmate |
draw_offer |
boolean | No | Whether the Active Player offered/accepted a draw |
variations |
array | No | Alternative lines from this position |
At least one property SHOULD be present (otherwise the Ply record is semantically vacuous).
11.2 Assessment values
The assessment property accepts values corresponding to standard PGN Numeric Annotation Glyphs:
| Value | PGN | NAG | Description |
|---|---|---|---|
"good" |
! |
1 | Good move |
"mistake" |
? |
2 | Mistake |
"brilliant" |
!! |
3 | Brilliant move |
"blunder" |
?? |
4 | Blunder |
"interesting" |
!? |
5 | Interesting/speculative move |
"dubious" |
?! |
6 | Dubious/questionable move |
11.3 Check and mate
The check and mate properties are boolean flags:
check: true— the move delivers check to the opponent’s terminal piece.mate: true— the move delivers checkmate (impliescheck: true).
These properties are informational; the actual game state is determined by the Rule System.
11.4 Draw offer semantics
The draw_offer property indicates whether the Active Player has offered or accepted a draw on this Ply:
true— the Active Player offers or accepts a draw.falseor absent — no draw offer on this Ply (default).
Negotiation protocol:
- When Player A sets
draw_offer: true, they offer a draw. - When Player B sets
draw_offer: trueon their subsequent Ply, they accept. - Once both Players have set
draw_offer: true, the Match MAY be concluded by draw agreement.
11.5 Variations
The variations array contains alternative lines that could be played from the current position. Each variation is an object with:
| Property | Type | Description |
|---|---|---|
comment |
string | Commentary on this variation |
plies |
array | Sequence of Ply objects in this variation |
Variations MAY be nested (variations within variations) to represent complex analysis trees.
11.6 Custom properties
Any additional properties are allowed and carry no normative semantics. Common custom properties include:
| Property | Description |
|---|---|
san |
Standard Algebraic Notation |
uci |
Universal Chess Interface notation |
eval |
Engine evaluation score |
depth |
Engine search depth |
engine |
Engine name |
12. Ply sequencing and turn alternation
Invariant:
- Plies alternate between Players.
- The first Ply is played by the Active Player in the initial Position (as encoded in the setup).
- Each subsequent Ply toggles the Active Player (per Game Protocol).
Indexing:
- Ply index 0, 2, 4, … → same Side as initial Position’s Active Player.
- Ply index 1, 3, 5, … → opposite Side.
13. Outcome object
The outcome object encodes the competitive result:
| Property | Type | Required | Description |
|---|---|---|---|
result |
string | Yes | Match result code |
13.1 Result values
| Value | Description |
|---|---|
"1-0" |
First Player wins |
"0-1" |
Second Player wins |
"1/2-1/2" |
Draw |
"1/2-0" |
First Player draws, Second Player forfeits |
"0-1/2" |
First Player forfeits, Second Player draws |
"1-1/2" |
First Player wins, Second Player takes half-point |
"1/2-1" |
First Player takes half-point, Second Player wins |
13.2 Outcome omission
If outcome is absent, the Match is either in progress or outcome not yet determined.
14. Extensibility
14.1 Custom properties
Implementations and users MAY add custom properties at any level:
- Match level: custom metadata, opening codes, analysis engine info.
- Ply level: san, uci, eval, depth, engine name, etc.
Custom properties MUST NOT use names already assigned to semantic properties.
14.2 Position notations
While FEEN is the default, alternative notations MAY be supplied in both setup and individual plies.
14.3 Ply notations
Ply actions MAY be recorded in multiple notations. If multiple exist, pmn is canonical; others are informational.
15. Validation rules
15.1 Structural validation (MUST)
- Document is valid TOML or valid JSON.
- Top level is an object/table.
meta,sides,sides.first,sides.second,setup,outcomeare optional objects.links,periods,pliesare optional arrays.- The
setupobject MUST be present with at least one Position notation.
15.2 Semantic validation (MUST, where applicable)
assessment(if present): MUST be one of the six valid enum values.result(if present): MUST be one of the seven valid result strings.duration_ms(if present): MUST be an integer >= 0.increment_ms(if present): MUST be an integer >= 0.plies(Period property, if present): MUST be an integer >= 1.elapsed_ms(if present): MUST be an integer >= 0.elo(if present): MUST be an integer >= 0.variant(if present): MUST be a valid SNN token.check,mate,draw_offer(if present): MUST be booleans.- Position notation (if present): syntax validation delegated to respective spec (FEEN, FEN, etc.).
pmn(if present): syntax validation delegated to PMN spec.
15.3 Semantic validation (SHOULD, context-dependent)
When Rule System context is available, implementations SHOULD additionally validate:
- Plies form a legal game sequence.
- Initial Position is valid under the Rule System.
checkandmateflags are accurate.- Time control periods are reasonable.
- Assessments are consistent with the game state.
16. Semantics NOT defined by PCN
PCN is deliberately agnostic to:
- Movement rules (belongs to Rule System),
- Legality and pseudo-legality (belongs to Rule System),
- Terminal evaluation (belongs to Rule System),
- Geometric interpretation of Coordinates (belongs to Rule System),
- Piece movement traditions (belongs to Rule System),
- Outcome classification beyond the result property (belongs to Rule System).
17. Robustness considerations
Implementations SHOULD defend against resource abuse:
- Impose reasonable maximum file size limits.
- Impose reasonable limits on string lengths.
- Impose reasonable limits on nesting depth (especially for variations).
- Avoid integer overflow via bounded arithmetic or big integers.
- Reject inputs that cannot be parsed in linear time with bounded memory.
18. Examples
See PCN Examples for comprehensive usage patterns including:
- Traditional chess games with explicit results,
- Matches with Fischer, byōyomi, and Canadian time controls,
- Cross-variant games using different variants per Side,
- Games with variations and analysis,
- Matches ending by resignation, time limit, or agreement,
- In-progress matches without final result.
19. JSON Schema
A JSON Schema for PCN is published for programmatic validation:
Implementations MAY rely on this schema as a baseline validator and add further semantic checks as needed.
20. Reference implementations
The following reference libraries are maintained by Sashité and are intended to be idiomatic, fully tested, and spec-accurate implementations of PCN v1.0.0.
They generally provide:
- Strict parsing and validation of PCN documents (TOML and JSON),
- Round-trip serialization (PCN ⇄ structured Match representation),
- Clear error reporting for invalid inputs,
- Semantic 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.
21. 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)”.
