Is LiveView a suitable choice for serving as a game server for a simple Three.js game?

Hello,

I’m relatively new to Phoenix, having just started the Pragmatic Studio LiveView course. Concurrently, I’m learning Three.js via the Threejs-Journey course. My primary background is in JS/TS/Vue development.

I’m interested in creating a straightforward “memory card” game. I envision it as an online multiplayer game, where two players can connect or create a “game room” that displays the 3D memory card game. My idea is to utilize Phoenix as the game server, primarily responsible for tracking the positions of the cards.

My main question is: would LiveView be suitable for such a project? While I can conceptualize the connection between a Vue or React app and making REST calls on every card flip, I’m finding it challenging to visualize how I’d integrate the game with LiveView, especially in the context of websockets.

Any guidance or insights you can provide would be greatly appreciated!

1 Like

Hello and welcome to the forums!

I was typing up an answer to this earlier and then it disappeared! So, here it is:

The short answer is: yes, very-well suited. Almost tailor-made!

Here’s a talk and repo for implementing King of Tokyo (a multiplayer board game, if you are unfamiliar) in LiveView.

2 Likes

I don’t know how threejs works but have you looked at Phoenix Channels, which is part of what Liveview is written on top of

2 Likes

You should think of channels as bidirectional super controllers :slight_smile:

1 Like

I saw a talk about Three.JS a couple of weeks ago. Really cool technology!

Keep us posted on how this progresses.

1 Like

Hi @JsonKody, and welcome!

LiveView would be awesome for this project and simplifies a lot of the plumbing over raw Phoenix Channels. I have embedded Babylon JS (Threejs alternative), and Konvajs (2D rather than 3D) and they work great. Here are a few of the ingredients you need:

  1. A client hook - the javascript that manages the Threejs scene and receives user input.
    See JavaScript interoperability — Phoenix LiveView v0.19.5
    This can have event handlers to handle events pushed from the server (i.e. the server-side LiveView code) (see handleEvent in the linked doc. It can also push information back to the server LiveView using pushEvent or pushEventTo.

The fact that there is a long-lived server process on the other end of the conversation simplifies state management enormously.

  1. The LiveView itself. In the LiveView template you will need to install the client hook somewhere. Search phx-hook for instructions. Note that if threejs is doing DOM manipulation, you will need to mark the DOM node that it attaches to in a special way to prevent patching from the server (use phx-update="ignore" (see https://hexdocs.pm/phoenix_live_view/dom-patching.html)

The LiveView can send events to the client hook using push_event (see JavaScript interoperability — Phoenix LiveView v0.19.5) and handles event from the client side using handle_event.

  1. To get the multi-user thing going, the LiveViews need to talk to each other. Probably the easiest way is to use PubSub with a topic per game. When the LiveView mounts, it can subscribe to the PubSub topic related to the game. This will ensure that LiveView process receives the game events. In the project @sodapopcan linked, you can see it happening here: https://github.com/dkarter/king_of_tokyo/blob/27f992f28e5be80125f36aed79d95812c568b1c0/lib/king_of_tokyo_web/live/game_live.ex#L194. The events are handled in the various handle_info functions in the same file.

To notify other game participants in the same game, you would use Phones.PubSub to broadcast events to the game topic. It’s a bit hard to follow in the linked project as they spin up a backing process per game in the GameServer module, but there’s a call here: https://github.com/dkarter/king_of_tokyo/blob/27f992f28e5be80125f36aed79d95812c568b1c0/lib/king_of_tokyo/game_server.ex#L258 - if you backtrack where that’s called from (e.g. the broadcast_... functions) you can see how the payload is constructed and how that is matched in the handle_infos in the LiveView.

Good luck!

5 Likes

Wow! Thanks for such good answers … this feels like polar opposite of Stack Overflow ( ͡° ͜ʖ ͡°)
Elixir has amazing comunity <3

I’ll look at all those links after weekend, thank you again.

PS: ok I’ll share it when it’s done but it would be so much work (I’ve some other projects before it - they will help me become proficient with Elixir/Phoenix/Liveview hopefully)

1 Like