Sashité for Developers
  1. Sashité for Developers
  2. Specifications
  3. STN
  4. 1.0.0
  5. Examples

STN Examples


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:

This represents scenarios such as position comparisons yielding identical results, null transformations, or baseline states.

Pass Move (Turn-Only Change)

{
  "toggle": true
}

Interpretation:

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:

Simple Movement (With Turn Change)

{
  "board_diff": {
    "e2": null,
    "e4": "C:P"
  },
  "toggle": true
}

Interpretation:


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:

Drop from Second Player Hand (With Turn Change)

{
  "board_diff": {
    "e5": "s:p"
  },
  "second_player_hand_diff": {
    "s:p": -1
  },
  "toggle": true
}

Interpretation:

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:

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:

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:

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:


Complex Movement Examples

Castling

{
  "board_diff": {
    "e1": null,
    "g1": "C:K",
    "h1": null,
    "f1": "C:R"
  },
  "toggle": true
}

Interpretation:

En Passant (First Player captures)

{
  "board_diff": {
    "e5": null,
    "f6": "C:P",
    "f5": null
  },
  "first_player_hand_diff": {
    "c:p": 1
  },
  "toggle": true
}

Interpretation:

Promotion with Capture (First Player)

{
  "board_diff": {
    "e7": null,
    "e8": "C:Q"
  },
  "first_player_hand_diff": {
    "c:r": 1
  },
  "toggle": true
}

Interpretation:


Multi-Dimensional Examples

3D Movement

{
  "board_diff": {
    "e2A": null,
    "f3B": "R:B"
  },
  "toggle": true
}

Interpretation:


Turn Management Examples

Multiple Moves (Same Player Active)

{
  "board_diff": {
    "e2": null,
    "e4": "C:P",
    "e7": null,
    "e5": "c:p"
  }
}

Interpretation:

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:


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:

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:


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

What STN Does NOT Represent

Toggle Semantics


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 }
}