MVP Spec Draft - Honte/phantom-go GitHub Wiki

Goal

Let 2 players play Phantom Go in real time.

Scope (by priority)

  1. setting up new game
  2. playing game in real time
  3. browsing games

Setting up new game

Available via button on home page.

Possible configuration:

  • board size (13 by default)
  • observators (whether to allow watching the game)

Clicking "Create game" button should redirect to game page (unique url)

Playing game in real time

The game can be in several states:

  1. Awaiting for players
  2. Mid-play
  3. Score counting
  4. Completed

Awaiting for players

The page should let user to join as Black, White or Observer. If Black or White option is already taken by other player, it should not be available. Once Black and White options are taken, the game starts. If any player is disconnected or leaves the game, it should return to this screen.

Mid-play

Black and White players should see only their goban. Observators can see all three gobans.

User can also see event log with any of these messages:

  • User joined as Black|White|Observervator
  • User left
  • Black|White played
  • Black|White move illegal
  • Black|White passed
  • Black|White resigned
  • X White|Black stones were captured
  • X White|Black stones were put in an atari

Requirements:

  • Observer cannot modify the game.
  • Black or White player can place stone of his/hers color if it's his/hers turn (left click; there's no submit move button so misclicks can happen).
  • Black or White player can place stone of opponent's color any time (right click; clicking right click again on the stone removes it).
  • User should see the number of prisoners for every player
  • User should see the number of opponent moves that are not present on the board (can be negative number)

Exits

  • If any player resignes, game goes into Completed state.
  • If both player passes, game goes into Score counting state.
  • If any player is disconnected or leaves the game, it goes into Awaiting for players state

Score counting

tbd

Completed

  • User should see 3 boards side by side
  • User should be able to travel in time with game progress :)

Browsing games

Basic list of all games on the server, possibly paginable. They should have statuses.

Technology

Front: Vue
Backend: .NET Core
Communication: SignalR

Tech spec

Commands

Command Description Input Output
/games Returns list of games none GameInfo[]
/game/:id Returns list of games none GameDetails
/game/create Creates new game GameRequest GameDetails
/game/:id/join/:role Join the game as black, white or observer none Response
/game/:id/leave Leave the game none Response
/game/:id/play Makes a move in game GamePlay GameResponse

Events

Games events

Broadcasted to every connected user.

Event Decription Data
/games/created New game created GameInfo
/games/removed Game removed GameInfo

Game events

Broadcasted to users that joined the game.

Event Decription Data
/game/:id/joined Player joined as black, white or observer PlayerStatus
/game/:id/left Player left PlayerStatus
/game/:id/event Event that takes place in a game GameEvent
/game/:id/completed Game has been completed GameDetails

Data structures

Response

{ success: boolean }

GameInfo

{ 
  id: string|number,
  status: string, // game status: awaiting, playing, counting, completed
  black: string|number, // black player id (connection/session id until user accounts are introduced) 
  white: string|number, // white player id,
  observators: number, // number of observators or list of observators ids (to consider)
  config: { // game configuration, e.g. board size, observators
    size: number
  } 
}

GameDetails

{ 
  // same as for GameInfo plus below
  
  // list of game events
  events: GameEvent[], 
  
  // if game is completed
  sgf,
  blackSgf,
  whiteSgf,
  
  // if game is being played and user is Black
  blackSgf
  
  // if game is being played and user is White
  whiteSgf
}

GameRequest

{
  size: number,
  observators: boolean
}

GamePlay

{
  type: string, // 'move', 'pass' or 'resign',
  x, // coords in case of 'move'
  y,
  opponents: [ // list of changes in opponent color stones (right clicks) since the last move
    {
      type: string, // 'add' or 'remove' 
      x, 
      y
    }
  ] 
}

GameResponse

{
  success: boolean, // true for move accepted, false for illegal move,
  blackSgf|whiteSgf: string // (optional) updated sgf for given player that includes the move and other changes on the board,
}

PlayerStatus

{
  id: number|string,
  role: string // black, white or observer
}

GameEvent

{
  type: string, // move, pass, resign, illegal
  player: string, // white or black,
  whiteAtari: number,
  blackAtari: number,
  captured: [ // list of stones that has been captured
   { x, y }
  ]
}