defmodule BackendWeb.GameChannel do @moduledoc """ Channel for handling game events and player movements. """ use BackendWeb, :channel require Logger @impl true def join("game:lobby", _payload, socket) do Logger.info("WebSocket connected to #{node()}, waiting for name") Phoenix.PubSub.subscribe(Backend.PubSub, "game_state") current_state = Backend.GameState.get_state() {:ok, %{players: current_state}, socket} end @impl true def handle_info({:game_state_updated, state}, socket) do push(socket, "game_state", %{players: state}) {:noreply, socket} end @impl true def handle_in("join_game", %{"name" => name}, socket) do Logger.info("Player '#{name}' joining game on #{node()}") socket = assign(socket, :player_name, name) Backend.GameState.add_player(name) {:reply, :ok, socket} end @impl true def handle_in("move", %{"directions" => directions}, socket) do case socket.assigns[:player_name] do nil -> Logger.warning("Move attempted without joining game") {:noreply, socket} player_name -> Logger.debug("Player '#{player_name}' moved #{inspect(directions)} on #{node()}") Backend.GameState.move_player(player_name, directions) {:noreply, socket} end end @impl true def terminate(_reason, socket) do case socket.assigns[:player_name] do nil -> Logger.info("WebSocket disconnected from #{node()}") player_name -> Logger.info("Player '#{player_name}' disconnected from #{node()}") Backend.GameState.remove_player(player_name) end :ok end end