# JavaScript Public Game Protocol

## Session Attach

Session Attach is the first message that should be sent from JavaScript client using Authorization token. For test purposes you can use following token:

`ws.send(enc(tuple( atom('client'), tuple( atom('session_attach'), 'EBAs6dg2Xw6XuCdg8qiPmlBLgYJ6N4Ti0P+oGpWgY'+ 'z4NW4nBBUzTe/wAuLYtPnjFpsjCExxSpV78fipmsP'+ 'xcf+NGy+QKIM6rmVJhpnIlKf0bpFNuGaAPjZAWthh'+ 'GO8nZ0V8UnA=='))));`

## Join Game

After session established you can join the game table. You should specify existed ID of game table. 1000001 is permanent lobby game ID:

`ws.send(enc(tuple( atom('client'), tuple(atom('join_game'),1000001))));`

## Game Events

Just after joining the table you will be able to listen the air. All messages from server to client are encoded as game events. You can make BERT huamn readable with:

`String(dec(raw))`

### Game Info

During each new game okey_game_info issued with full list of players. You should remeber thirs names to display in client.

`{game_event,undefined,okey_game_info, {players, {PlayerInfo,<<"dunes1500113">>, <<"dunes">>,<<"Abe">>,Kobo,undefined,undefined,undefined, <<"/files/users/user_dunes/avatar/1-small.jpg">>,true}, {PlayerInfo,<<"wolves1500114">>, <<"wolves">>,<<"Herman">>,Hesse,undefined,undefined,undefined, <<"/files/users/user_wolves/avatar/1-small.jpg">>,true}, {PlayerInfo,<<"wolves1500115">>, <<"wolves">>,<<"Herman">>,Hesse,undefined,undefined,undefined, <<"/files/users/user_wolves/avatar/1-small.jpg">>,true}, {PlayerInfo,<<"dunes1500112">>, <<"dunes">>,<<"Abe">>,Kobo,undefined,undefined,undefined, <<"/files/users/user_dunes/avatar/1-small.jpg">>,false}}, {timeouts,{OkeyTimeouts,normal,30000,10000,25000,45000}}, {game_type,standard}, {finish_with_gosterge,undefined}, {pairs,null}, {table_name,<<"I'm filling lucky">>}, {sets,null},{set_no,null},{rounds,undefined}, {mul_factor,1},{slang_flag,false},{observer_flag,false}, {pause_enabled,true},{social_actions_enabled,true}, {tournament_type,lucky},{series_confirmation_mode,<<"no">>}}`

### Player State

`{game_event,undefined,okey_game_player_state, {whos_move,null},{game_state,game_initializing}, {piles,null},{tiles,null},{gosterge,null}, {pile_height,null},{current_round,0},{game_sub_type,null}, {next_turn_in,0},{paused,false},{chanak_points,0}, {round_timeout,null},{set_timeout,null}}`

### Game Started

During each new game okey_game_started issued with full list of cards. You should remeber them in client along with Gosterge Jocker card.

`{game_event,undefined,okey_game_started, {tiles,{OkeyPiece,3,2}, {OkeyPiece,3,4}, {OkeyPiece,2,12}, {OkeyPiece,3,8}, {OkeyPiece,1,0}, {OkeyPiece,1,10}, {OkeyPiece,2,13}, {OkeyPiece,2,6}, {OkeyPiece,2,10}, {OkeyPiece,2,10}, {OkeyPiece,4,5}, {OkeyPiece,2,11}, {OkeyPiece,2,4}, {OkeyPiece,4,10}}, {gosterge,{OkeyPiece,2,8}},{pile_height,48}, {current_round,1},{current_set,1},{game_type,null}, {game_speed,null},{game_submode,null},{chanak_points,0}, {round_timeout,null},{set_timeout,null}}`

### Next Turn

You should handle okey_next_turn message in order to give user ablity to play only when player is his name. Otherwise you messages will be ignored by server.

`{game_event,undefined,okey_next_turn, {player,<<"oldman1500118">>},{can_challenge,false}}`

### Discarded Notification

When someone discards the Tash you should update you corner cards placeholders with discarded Tash.

`{game_event,undefined,okey_tile_discarded, {player,<<"oldman1500118">>},{tile,{OkeyPiece,1,4}},{timeouted,true}}`

### Taken Notification

When someone take a cards from center of the table pile=0 or from its neighbour pile=1 you will be notified to update the pile_height cards left:

`{game_event,GameId,okey_tile_taken, {player,<<"wolves1500121">>},{pile,0}, {revealed,null},{pile_height,47}}`

You the card was taken by you, you can see it in tile:

`{game_event,GameId,okey_tile_discarded, {player,<<"dunes1500120">>}, {tile,{OkeyPiece,1,1}},{timeouted,false}}`

### Timeout Notification

Send when player was inactive during 30 seconds (timeout by default). Server is automaticaly take and discard cards

`{game_event,GameId,okey_turn_timeout,[{tile_taken,{'OkeyPiece',2,4}}, {tile_discarded,{'OkeyPiece',2,4}}]}`

### Player Left Notification

Send when someone left the game and have replaced. Server will send additional information about new plyaer: is bot or is human - {bot_replaced,false} and {human_replaced,true} and new PlayerInfo in field replacment

`{game_event,GameId,player_left, [{player,<<"radio1500012">>}, {bot_replaced,false}, {human_replaced,true}, {replacement, {'PlayerInfo',<<"betul_dogan1500001">>, <<"undefined">>,<<"Betul">>,<<"Dogan">>, undefined,0,0,<<"undefined">>,false}}]}`

## Game Actions

Game Actions is something that you can send only from client to server. But for debugging purposes during development phase your game actions will mirror from server as DATA BERT event also.

### Take

Take a card from.
Fields:

- GameId: current game id (by default use 1000001)
- {pile: From}: from which pile take a card. values: 0 - from table, 1 - from pile of left player

`ws.send(enc(tuple(atom('client'),tuple(atom('game_action'),GameId, atom('okey_take'),{'pile': From}))));`

### Discard

Discard card from a hand.
Fields:

- GameId: current game id (by default use 1000001)
- {'tile':tuple(atom('OkeyPiece'),Color,Vaue)}: card description (#'OkeyPieces'{} record)
  when Colour is card colour, number from 1 to 4, Value is card value, number from 1 to 13

`ws.send(enc(tuple( atom('client'), tuple( atom('game_action'), GameId, atom('okey_discard'), {'tile':tuple(atom('OkeyPiece'),Color,Vaue)}))));`

### Pause/Resume

Game pause or resume.
Fields:

- GameId: current game id (by default use 1000001)
- Action: Send action. Value 'pause' or 'resume'

`ws:send(enc(tuple(atom('client'), tuple(atom("pause_game"),atom('undefined'),GameId, atom(Action)))));`

### Reveal

Reveal a card: Fields:

- GameId: current game id (by default use 1000001)
- {discarded, tuple(atom("OkeyPiece"), Color, Value)}: a card with you want reveal, (#'OkeyPieces'{} record)
  when Colour is card colour, number from 1 to 4, Value is card value, number from 1 to 13
- {hand, Hand}: rest of hand, without revealed card
  value - two lists in lists (upper and lower rows) of tuple(atom("OkeyPiece"), Color, Value) or 'null' if card doesn't exist

`ws:send(enc(tuple(atom('client'),tuple(atom("game_action"), GameId,atom("okey_reveal"), [{discarded, tuple(atom("OkeyPiece"), Color, Value)},{hand, Hand}]))));`

### I Saw Okey

Send by player when he sees Gosterge. (not tested fully) `ws:send(enc(tuple(atom('client'), tuple(atom("game_action"),GameId,atom("okey_i_saw_okey"),[]))));`

### I Have 8 Tashes

Send by player when he has 8 tashes. (not tested fully) `ws:send(enc(tuple(atom('client'), tuple(atom("game_action"),GameId,atom("okey_i_have_8_tashes"),[]))));`