Portable Chess Notation (PCN) Specification
Version: 1.0.0 Author: Sashité Published: August 5, 2012 License: MIT License
Overview
Portable Chess Notation (PCN) is a simple, JSON-based format for representing complete chess game records across variants. PCN is designed to be standalone and rule-agnostic, requiring no external dependencies while remaining compatible with other Sashité specifications when needed.
PCN focuses on practical game representation with minimal complexity, supporting both traditional single-variant games and modern cross-variant scenarios where different players use different game systems.
Design Principles
- Simplicity First: Minimal structure with intuitive field names
- Standalone: No dependencies on other specifications
- Compatible: Can leverage concepts from GAN, FEEN, PMN when beneficial
- Rule-Agnostic: No embedded game logic or validation
- Cross-Game Ready: Native support for hybrid game scenarios
JSON Structure
{
"meta": {
"name": "<string>",
"event": "<string>",
"location": "<string>",
"round": "<integer>",
"started_on": "<date>",
"finished_at": "<datetime>",
"href": "<url>"
},
"games": {
"northside": "<game_id>",
"southside": "<game_id>"
},
"players": {
"northside": {
"name": "<string>",
"elo": "<integer>",
"pieces_in_hand": ["<piece>", ...]
},
"southside": {
"name": "<string>",
"elo": "<integer>",
"pieces_in_hand": ["<piece>", ...]
}
},
"setup": {
"dimensions": [<integer>, ...],
"squares": [<piece_or_null>, ...],
"first_to_move": "<northside|southside>"
},
"moves": [
[<action>, ...],
...
],
"state": {
"current_player": "<northside|southside>",
"game_status": "<status>",
"is_in_check": "<boolean>",
"result": "<result>"
}
}
Field Specifications
Meta Section (Optional)
Game metadata and administrative information:
Field | Type | Description |
---|---|---|
name |
string | Descriptive name for the game |
event |
string | Tournament or event name |
location |
string | Location where game was played |
round |
integer | Round number (≥ 1) |
started_on |
date | Start date (YYYY-MM-DD) |
finished_at |
datetime | End date/time (ISO 8601) |
href |
url | Reference URL |
Games Section (Required)
Identifies the game system for each side:
Field | Type | Description |
---|---|---|
northside |
string | Game identifier for north player |
southside |
string | Game identifier for south player |
Game Identifiers: Use lowercase for northside, uppercase for southside (compatible with GAN/FEEN conventions):
- Same game:
"chess"
vs"CHESS"
- Cross game:
"shogi"
vs"XIONGQI"
- Custom:
"variant1"
vs"VARIANT2"
Players Section (Optional)
Player information:
Field | Type | Description |
---|---|---|
name |
string | Player name or identifier |
elo |
integer | Elo rating (≥ 0) |
pieces_in_hand |
array | Available pieces for placement |
Setup Section (Required)
Initial game configuration:
Field | Type | Description |
---|---|---|
dimensions |
array | Board size as [rows, columns, …] |
squares |
array | Starting position as flat array |
first_to_move |
string | Who moves first: “northside” or “southside” |
Board Representation:
- Flat array indexed row-major (left-to-right, top-to-bottom)
null
for empty squares- String identifiers for pieces
- Length must equal product of dimensions
Moves Section (Required)
Sequence of game moves:
Each move is an array of actions representing one player’s complete turn:
[source_square, destination_square, piece_name, captured_piece]
Position | Type | Description |
---|---|---|
0 | integer/null | Source square index (null = from hand) |
1 | integer | Destination square index |
2 | string | Piece name after move |
3 | string/null | Captured piece (null = no capture) |
Examples:
[12, 28, "p"] // Simple move
[28, 37, "p", "P"] // Capture
[null, 45, "N"] // Drop from hand
[60, 62, "K", null, 63, 61, "R", null] // Castling (2 actions)
State Section (Required)
Current game state:
Field | Type | Description |
---|---|---|
current_player |
string | Whose turn: “northside” or “southside” |
game_status |
string | Current status (see status values) |
is_in_check |
boolean | Whether current player is in check |
result |
string | Final result when game finished |
Game Status Values:
"in_progress"
- Game ongoing"checkmate"
- King in checkmate"stalemate"
- No legal moves"bare_king"
- King stands alone"mare_king"
- King captured"resignation"
- Player resigned"time_limit"
- Time exceeded"repetition"
- Position repeated"illegal_move"
- Illegal move
Result Values:
"northside_wins"
- North player wins"southside_wins"
- South player wins"draw"
- Game is drawn
Examples
Standard Chess Game
{
"meta": {
"name": "King's Gambit",
"event": "Club Tournament"
},
"games": {
"northside": "chess",
"southside": "CHESS"
},
"players": {
"northside": {"name": "Alice"},
"southside": {"name": "Bob"}
},
"setup": {
"dimensions": [8, 8],
"squares": [
"r", "n", "b", "q", "k", "b", "n", "r",
"p", "p", "p", "p", "p", "p", "p", "p",
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
"P", "P", "P", "P", "P", "P", "P", "P",
"R", "N", "B", "Q", "K", "B", "N", "R"
],
"first_to_move": "southside"
},
"moves": [
[[52, 36, "P"]], // 1. e4
[[12, 28, "p"]], // 1... e5
[[53, 37, "P"]], // 2. f4
[[28, 37, "p", "P"]] // 2... exf4
],
"state": {
"current_player": "southside",
"game_status": "in_progress"
}
}
Shogi Game with Captures
{
"meta": {
"name": "Shortest Shogi Game"
},
"games": {
"northside": "shogi",
"southside": "SHOGI"
},
"setup": {
"dimensions": [9, 9],
"squares": [
"l", "n", "s", "g", "k", "g", "s", "n", "l",
null, "r", null, null, null, null, null, "b", null,
"p", "p", "p", "p", "p", "p", "p", "p", "p",
null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null,
"P", "P", "P", "P", "P", "P", "P", "P", "P",
null, "B", null, null, null, null, null, "R", null,
"L", "N", "S", "G", "K", "G", "S", "N", "L"
],
"first_to_move": "southside"
},
"moves": [
[[56, 47, "P"]], // 1. P-7f
[[3, 11, "g"]], // 1... G-2b
[[64, 24, "+B", "p"]], // 2. Bx3c+ (capture and promote)
[[5, 14, "g"]], // 2... G-1d
[[24, 14, "+B", "g"]], // 3. +Bx1d (capture)
[[4, 3, "k"]], // 3... K-2a
[[null, 13, "G"]] // 4. G*2b# (drop checkmate)
],
"state": {
"current_player": "northside",
"game_status": "checkmate",
"result": "southside_wins"
}
}
Cross-Game: Xiongqi vs Chess
{
"meta": {
"name": "Hybrid Exhibition"
},
"games": {
"northside": "chess",
"southside": "XIONGQI"
},
"players": {
"northside": {"name": "Chess Player"},
"southside": {"name": "Xiongqi Player"}
},
"setup": {
"dimensions": [8, 8],
"squares": [
"r", "n", "b", "q", "k", "b", "n", "r",
"p", "p", "p", "p", "p", "p", "p", "p",
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
"P", "P", "P", "P", "P", "P", "P", "P",
"R", "E", "B", "Q", "K", "B", "E", "R"
],
"first_to_move": "southside"
},
"moves": [
[[52, 36, "P"]], // Xiongqi pawn advance
[[12, 28, "p"]] // Chess pawn response
],
"state": {
"current_player": "southside",
"game_status": "in_progress"
}
}
Compatibility with Other Specifications
PCN is standalone but compatible with Sashité specifications:
GAN Integration (Optional)
When cross-game disambiguation is needed, pieces can be qualified:
// Instead of: "K"
// Use: "CHESS:K" or "xiongqi:k"
FEEN Integration (Optional)
Initial position can be provided as FEEN string:
"setup": {
"feen_position": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR / CHESS/chess"
}
PMN Integration (Optional)
Moves can be expanded to full PMN objects when needed:
// Instead of: [52, 36, "P"]
// Use: {"src_square": 52, "dst_square": 36, "piece_name": "P", "piece_hand": null}
Validation Rules
- Required Fields:
games
,setup
,moves
,state
sections must be present - Game Identifiers: Must follow lowercase/uppercase convention for north/south
- Board Consistency:
squares
array length must equal product ofdimensions
- Move Format: Each action must have 3-4 elements in correct order
- Square Indices: Must be valid indices within board dimensions
- Turn Alternation: Moves should alternate between players
- Status Consistency:
game_status
andresult
must be consistent
Implementation Notes
File Format
- Extension:
.pcn
- MIME Type:
application/vnd.pcn+json
- Encoding: UTF-8
Square Indexing
For an 8×8 board, squares are indexed 0-63:
0 1 2 3 4 5 6 7 (rank 8)
8 9 10 11 12 13 14 15 (rank 7)
16 17 18 19 20 21 22 23 (rank 6)
24 25 26 27 28 29 30 31 (rank 5)
32 33 34 35 36 37 38 39 (rank 4)
40 41 42 43 44 45 46 47 (rank 3)
48 49 50 51 52 53 54 55 (rank 2)
56 57 58 59 60 61 62 63 (rank 1)
Multi-Action Moves
Complex moves use multiple actions in sequence:
// Castling: King e1-g1, Rook h1-f1
[[60, 62, "K"], [63, 61, "R"]]
// En passant: Pawn d5-e6, capture pawn at e5
[[35, 28, "P"], [36, 36, null]] // Remove captured pawn
Piece Naming
- Use consistent naming within each game system
- Consider standard conventions:
K
,Q
,R
,B
,N
,P
for Chess - Promotion indicated by piece name:
"Q"
for promoted pawn - State modifiers:
"+R"
for promoted Shogi rook
Future Considerations
Potential Extensions
- Time Control: Clock information and time per move
- Annotations: Move comments and analysis
- Media: Attached diagrams or photos
- Variations: Alternative move sequences
- Multi-dimensional: 3D board support
Extensibility Strategy
- Optional sections can be added without breaking compatibility
- Unknown fields should be preserved but ignored
- Version identification in
meta
section recommended
Conclusion
PCN provides a simple, practical format for chess game representation that balances ease of use with cross-variant flexibility. By focusing on standalone simplicity while maintaining compatibility with other Sashité specifications, PCN serves as an effective bridge between traditional chess notation needs and modern variant chess requirements.
The format’s straightforward structure makes it ideal for implementation in game viewers, databases, and analysis tools, while its cross-game support enables documentation of innovative hybrid chess scenarios.