Help me decide between Phoenix Presence and a custom solution

I am trying to decide if Phoenix Presence is right for my application, or if I should use my own custom solution to track “players”. Let me explain what I’m working on:

I am making an online multiplayer game. I am using the Phaser Javascript library client side, and I will use Phoenix Channels for the backend to facilitate the multiplayer, realtime features that I’d like to have. Consider these basic features:

  • When a new player logs in to the game, their character is now “online” for others to see and interact with.
  • When a player leaves the . game, their character is now “offline”
  • A player can click around the map to move their player, and the changes should be reflected for all online users as well.

I can see how Presence can handle the first two features easily, but the third one, I’m not so sure the more I look into it. For example, to try and track the player movements, I am doing this:

Presence.update(socket, "player:#{player_id}", %{
    id: player_id,
    x: x,
    y: y
})

The client application will receive this update, but there’s not a good way to determine what the event was, it just returns the entire payload of data. I suppose I could include another key-value pair in the update, which signifies the action, eg. action: "move" and then parse that out on the client side and let the game know what to do with it.

Maybe it would be easier in this case to create a GenServer and use my own Phoenix Channel events to communicate the state of the app. I could pass a “player_id” from the client to the server, and create a GenServer for each active player, which would keep track of their state while they’re logged in and playing. It could also handle saving to the database periodically, or when they log out of the game.

I initially thought Presence would be good for this, but I am having second thoughts. Most of the examples I’ve seen is a chat room, and displaying a list of online users. In this case it’s fine to wipe out the entire list of users each time an event occurs and replace it with a new sync’d state. However, in this game I’m working on, I need to handle individual actions. Would love some opinions and thoughts about this. Thanks!

It’s probably better if You dedicate a process per game, which will register/unregister players.

The idea is to be able to switch interface easily, it should be possible to switch from Phoenix to a Text Based client. Thus, it’s not recommended to have your game depend on Presence…

This is the way they do in…

  • Island game in Functional Web development with Elixir, by @lance
  • Multi player Bingo game
5 Likes

Your 3rd feature sounds like a feature I did which is real time user privilege change, eg you want a ban to take effect immediately.

I don’t use Phoenix, only Phoenix.PubSub to broadcast changes, and GenServer to track user state/logic/etc. Each change is just a JSON message sent over websocket.

2 Likes

You may want to look at the implementation of ExVenture since it solves many of the same problems. There’s a number of good posts about it on this forum: https://elixirforum.com/search?q=exventure

2 Likes

Hello,

Have you finished your Phaser-Phoenix-based game?

Would be nice to see it in action or read how you achieved it.