We are developing a game, using elixir and phoenix channels as backend, it is a turn based game.
Player joins to lobby channel after starting the game, when a new game starts a genserver is created and players got joined to a new game channel.
We are using Nebulex for caching our game state, while genserver is used for keeping track of timing for single game instance. If genserver crashed for any reason, it will be restarted by supervisor but restore its state from Nebulex cache.
The state in cache is stored as map as value and game id as key :
game_state = %{
playing_players_ids: [1,2,3],
players_on_table_ids: [1,2,3,4],
numbers_of_players: 3,
round_scores: %{ 1 => %{1: 2, 2: 1, 3: 5}, 2 => %{1: 2, 2: 1, 3: 5}},
players_turn: %{1 => 2, 2 => 3, 3 => 1},
players_local_to_global_ids: %{1 => 51, 2 => 41, 3 => 56},
players_global_to_local_ids: %{51 => 1, 41 => 2, 56 => 3},
next_turn_id: 2,
rounds_played: 1,
first_card_suit: “”,
last_turn_winner: 2,
number_of_cards_played: 1,
last_turn_cards: %{1: “H5”, 2: “H1”, 3: “H10”},
bet_info: %{single_bet_amount: 30, collected_amount: 90}
genserver_pid: #PID<0.104.0>
}
Cache.set(game_id, game_state)
After every player turn, we have to update the state. Get state from cache, update one or more value and save it again in cache. The problem is: to update a single value, an entire map is recreated because of elixir immutability when saved in cache.
We want to know, is it ok? or is there any other way we can implement this?
Also let us know, if this application structure can be improved.
Thanks