- Sashité for Developers
- Specifications
- STN
- 1.0.0
- Examples
STN Examples
- State Transition Notation (STN) v1.0.0
- Author: Cyril Kato
- License: Open Web Foundation Agreement 1.0
Overview
This document provides comprehensive examples of STN (State Transition Notation) usage across various game types and transition scenarios. These examples illustrate practical applications of the STN specification while remaining rule-agnostic.
Note: All examples are for illustration purposes only. STN does not define or assume any game-specific rules, movement patterns, or win conditions.
Basic Examples
No Changes
{}
Interpretation:
- No Board Squares change.
- No First Player Hand contents change.
- No Second Player Hand contents change.
- Active player remains the same (due to default
toggle: false).
This represents scenarios such as position comparisons yielding identical results, null transformations, or baseline states.
Pass Move (Turn-Only Change)
{
"toggle": true
}
Interpretation:
- No Board Squares change.
- No Hand contents change.
- Active player changes (explicit
toggle: true).
This represents pass moves, forfeit turns, or any transition where only the turn changes.
Simple Movement (No Turn Change)
{
"board_diff": {
"e2": null,
"e4": "C:P"
}
}
Interpretation:
- Square
e2becomes empty. - Square
e4now contains a white chess pawn. - Same player remains active (implicit
toggle: false).
Simple Movement (With Turn Change)
{
"board_diff": {
"e2": null,
"e4": "C:P"
},
"toggle": true
}
Interpretation:
- Square
e2becomes empty. - Square
e4now contains a white chess pawn. - Turn passes to opponent (explicit
toggle: true).
Hand Examples
Drop from First Player Hand (With Turn Change)
{
"board_diff": {
"e5": "S:P"
},
"first_player_hand_diff": {
"S:P": -1
},
"toggle": true
}
Interpretation:
- Square
e5now contains a Sente shogi pawn. - One Sente pawn removed from the First Player Hand.
- Turn passes to opponent.
Drop from Second Player Hand (With Turn Change)
{
"board_diff": {
"e5": "s:p"
},
"second_player_hand_diff": {
"s:p": -1
},
"toggle": true
}
Interpretation:
- Square
e5now contains a Gote shogi pawn. - One Gote pawn removed from the Second Player Hand.
- Turn passes to opponent.
Capture by First Player (Shogi-style, with Side mutation)
The First Player (Active Player, Side first) captures a Gote piece. The captured piece changes Side upon entering the First Player Hand.
{
"board_diff": {
"b1": "S:S",
"c2": null
},
"first_player_hand_diff": {
"S:B": 1
},
"toggle": true
}
Interpretation:
- A Sente silver moves to
b1. - Square
c2becomes empty (captured piece removed). - One Sente bishop added to the First Player Hand (captured piece, Side mutated to
first). - Turn passes to opponent.
Capture by Second Player (Shogi-style, with Side mutation)
The Second Player (Active Player, Side second) captures a Sente piece.
{
"board_diff": {
"g7": "s:p",
"f6": null
},
"second_player_hand_diff": {
"s:n": 1
},
"toggle": true
}
Interpretation:
- A Gote pawn moves to
g7. - Square
f6becomes empty (captured piece removed). - One Gote knight added to the Second Player Hand (captured piece, Side mutated to
second). - Turn passes to opponent.
Capture by First Player (Chess-style, no Side mutation)
The First Player (Active Player, Side first) captures a Black piece. In Chess, captured pieces do not change Side.
{
"board_diff": {
"d4": null,
"d5": "C:R"
},
"first_player_hand_diff": {
"c:p": 1
},
"toggle": true
}
Interpretation:
- White rook moves to
d5. - Square
d4becomes empty (captured piece removed). - One Black pawn added to the First Player Hand, retaining its original Side (
second). - Turn passes to opponent.
Capture by Second Player (Chess-style, no Side mutation)
{
"board_diff": {
"e5": null,
"e4": "c:p"
},
"second_player_hand_diff": {
"C:P": 1
},
"toggle": true
}
Interpretation:
- Black pawn moves to
e4. - Square
e5becomes empty (captured piece removed). - One White pawn added to the Second Player Hand, retaining its original Side (
first). - Turn passes to opponent.
Complex Movement Examples
Castling
{
"board_diff": {
"e1": null,
"g1": "C:K",
"h1": null,
"f1": "C:R"
},
"toggle": true
}
Interpretation:
- King moves from
e1tog1. - Rook moves from
h1tof1. - Turn passes to opponent.
En Passant (First Player captures)
{
"board_diff": {
"e5": null,
"f6": "C:P",
"f5": null
},
"first_player_hand_diff": {
"c:p": 1
},
"toggle": true
}
Interpretation:
- White pawn moves from
e5tof6. - Black pawn at
f5disappears (captured en passant). - One Black pawn added to the First Player Hand.
- Turn passes to opponent.
Promotion with Capture (First Player)
{
"board_diff": {
"e7": null,
"e8": "C:Q"
},
"first_player_hand_diff": {
"c:r": 1
},
"toggle": true
}
Interpretation:
- Pawn moves from
e7toe8and promotes to queen. - Black rook at
e8was captured. - One Black rook added to the First Player Hand.
- Turn passes to opponent.
Multi-Dimensional Examples
3D Movement
{
"board_diff": {
"e2A": null,
"f3B": "R:B"
},
"toggle": true
}
Interpretation:
- Piece moves from 3D coordinate
e2Atof3B. - Final piece is identified as
R:B. - Turn passes to opponent.
Turn Management Examples
Multiple Moves (Same Player Active)
{
"board_diff": {
"e2": null,
"e4": "C:P",
"e7": null,
"e5": "c:p"
}
}
Interpretation:
- Net result of two moves: both
e2→e4ande7→e5. - Original active player is still active (implicit
toggle: false). - Represents cumulative state difference over an even number of turns.
Multiple Moves (Different Player Active)
{
"board_diff": {
"e2": null,
"e4": "C:P",
"e7": null,
"e5": "c:p",
"f1": null,
"d3": "C:B"
},
"toggle": true
}
Interpretation:
- Net result of three moves including a bishop development.
- After all moves, the opponent is now active (explicit
toggle: true). - Represents an odd number of moves.
Complex Scenarios
Piece Exchange Involving Both Hands
{
"board_diff": {
"a1": "S:S",
"b2": "S:L",
"c3": null
},
"first_player_hand_diff": {
"S:G": -1
},
"second_player_hand_diff": {
"s:g": 1
}
}
Interpretation:
- Multiple pieces have moved on the Board.
- One Sente gold removed from the First Player Hand (dropped).
- One Gote gold added to the Second Player Hand (captured).
- Same player remains active.
Multi-Location Drop Pattern
{
"board_diff": {
"e5": "S:P",
"f5": "S:P",
"g5": "S:P"
},
"first_player_hand_diff": {
"S:P": -3
},
"toggle": true
}
Interpretation:
- Three squares now contain Sente pawns.
- Three Sente pawns removed from the First Player Hand.
- Turn passes to opponent.
State Transition Patterns
Incremental Position Building
Step 1 — Initial move:
{
"board_diff": {
"e2": null,
"e4": "C:P"
},
"toggle": true
}
Step 2 — Response move:
{
"board_diff": {
"e7": null,
"e5": "c:p"
},
"toggle": true
}
Cumulative result (from initial position):
{
"board_diff": {
"e2": null,
"e4": "C:P",
"e7": null,
"e5": "c:p"
}
}
Position Comparison
Position A: Standard opening. Position B: After White’s development.
STN diff (A → B):
{
"board_diff": {
"e2": null,
"e4": "C:P",
"g1": null,
"f3": "C:N",
"f1": null,
"c4": "C:B"
}
}
This shows the net development without indicating turn sequence.
Integration with FEEN
Standard Chess Example
Given the initial Western Chess position:
-rnbqk^bn-r/+p+p+p+p+p+p+p+p/8/8/8/8/+P+P+P+P+P+P+P+P/-RNBQK^BN-R / C/c
After the first move (e2-e4):
-rnbqk^bn-r/+p+p+p+p+p+p+p+p/8/8/4P3/8/+P+P+P+P1+P+P+P/-RNBQK^BN-R / c/C
STN representation:
{
"board_diff": {
"e2": null,
"e4": "C:P"
},
"toggle": true
}
After the second move (e7-e5):
-rnbqk^bn-r/+p+p+p+p1+p+p+p/8/4p3/4P3/8/+P+P+P+P1+P+P+P/-RNBQK^BN-R / C/c
STN representation (cumulative from initial):
{
"board_diff": {
"e2": null,
"e4": "C:P",
"e7": null,
"e5": "c:p"
}
}
Note: toggle is omitted (default false) because after two moves, the original active player is active again.
Shogi Drop Example
Before drop:
+l+n+s+g+k+g+s+n+l/1+r5+b1/+p+p+p+p+p+p+p+p+p/9/9/9/PPPPPPPPP/1B5R1/LNSGK^GSNL / S/s
After Sente pawn drop to 5e:
+l+n+s+g+k+g+s+n+l/1+r5+b1/+p+p+p+p+p+p+p+p+p/9/4P4/9/PPPP1PPPP/1B5R1/LNSGK^GSNL / s/S
STN representation:
{
"board_diff": {
"e5": "S:P"
},
"first_player_hand_diff": {
"S:P": -1
},
"toggle": true
}
Understanding STN Semantics
What STN Represents
- Net changes between two complete Positions.
- Final states of changed Board Squares.
- Delta quantities in each Player Hand separately.
- Active player after transition (explicit toggle control).
What STN Does NOT Represent
- How the changes occurred.
- Order of Actions within a Move.
- Intermediate positions during transition.
- Legality or validation of transitions.
Toggle Semantics
- Default behavior:
toggle: false(same player remains active). - Explicit turn change:
toggle: true(player changes). - Empty object:
{}means genuinely no changes (including turn). - Pass move:
{"toggle": true}means only the turn changes.
Best Practices
When to Use STN
Position comparison:
// Calculate difference between two positions
const stn = diffPositions(positionA, positionB);
Move validation:
// Check if proposed change is valid
if (isValidTransition(currentPosition, proposedSTN)) {
applySTN(currentPosition, proposedSTN);
}
Undo/redo systems:
// Store reversible changes
const undoSTN = invertSTN(forwardSTN);
historyStack.push(undoSTN);
Network synchronization:
// Send only what changed
sendToClients(stnDelta);
Optimization Patterns
Minimal representation — Only include changed locations/pieces:
// Good - only changed elements
{
"board_diff": { "e2": null, "e4": "C:P" },
"toggle": true
}
// Avoid - unnecessary unchanged elements
{
"board_diff": { "e2": null, "e4": "C:P", "a1": "C:R" },
"toggle": true
}
Batch changes — Combine related modifications:
// Efficient - combined castling
{
"board_diff": {
"e1": null, "g1": "C:K",
"h1": null, "f1": "C:R"
},
"toggle": true
}
Toggle optimization — Use default behavior when possible:
// Good - implicit toggle: false
{
"board_diff": { "e2": null, "e4": "C:P" }
}
// Unnecessary - explicit false
{
"board_diff": { "e2": null, "e4": "C:P" },
"toggle": false
}
Common Pitfalls
Forgetting explicit toggle — Pass moves need toggle: true:
// Wrong - this means no changes at all
{}
// Correct - pass move
{ "toggle": true }
Zero hand deltas — Hand values must be non-zero:
// Wrong
{
"first_player_hand_diff": { "S:P": 0 }
}
// Correct - omit unchanged entries
{}
Routing captures to the wrong Hand — Captured pieces always go to the Active Player’s Hand, per the Game Protocol:
// First Player is Active: captured piece goes to first_player_hand_diff
{
"board_diff": { "d5": "C:R", "d4": null },
"first_player_hand_diff": { "c:p": 1 },
"toggle": true
}
// Second Player is Active: captured piece goes to second_player_hand_diff
{
"board_diff": { "e4": "c:p", "e5": null },
"second_player_hand_diff": { "C:P": 1 },
"toggle": true
}
Invalid QPI consistency — Use consistent piece identification:
// Ensure QPI format compliance
{
"board_diff": { "e4": "C:P" },
"first_player_hand_diff": { "c:p": 1 }
}
