I’ve finished reading the Functional Web Development book by Lance Halvorsen where we build a game of islands (similar to a battleship game). I’ve been interested in live view so I thought building a live view interface for the game would be a pretty cool project.
This is my second medium-sized project in Phoenix. The first was a JSON API for a job interview, which is a much more straightforward project.
My current implementation works:
- A user can register with an email and password and get access to the lobby. User auth is managed by Pow
- While in the lobby, a player can start a game
- Another player in the lobby can select the first player’s game. This starts the game for both players
- Both player’s can set their islands on the board
- As soon as both players have their islands set, they can guess coordinates in alternating turns. Hit and missed guesses are shown in the opponent’s board. The opponent’s hits are shown in the player’s board.
- When a player wins the game, he can see that he won. The loser also sees he lost.
While this all works, the code organization is quite unruly. This is all managed by a live view that manages two channel topics:
- The Lobby topic. In this channel I have messages about new players joining the lobby and creating games. I’m using the Phoenix.Presence module for this together with multiple handle_info() clauses for displaying the open games in the live view.
- The Game topic. In this channel I exchange messages between the players (setting islands, guessing coordinates, winning the game etc.)
The live view also manages user events from the browser with multiple handle_event() clauses.
The actual game is managed by the GameEngine. The GameEngine is a separate application (another repo actually) with it’s own supervisor. This application manages the game state and decides what’s possible and when.
Finally, to my question: how can I organize the code so that it’s more manageable? My current live view is responsible for handling user events in handle_event() clauses, dispatching messages with PubSub and handling them in handle_info() clauses, presence diffing, handling two different topics and managing a medium sized list of assigns. I’ve tried using a nested live view for the player’s boards but I don’t think it helped much (the same problems persist, just in a smaller scale). This complexity shunned me away from testing and now I have a big fragile mess in my hands . Maybe I’m juggling too many balls at once
I’ll post the github repo here by the end of day if anyone wants to read the code. I’m a bit ashamed by it but I also want to sharpen my skills