A super simple story pointing application powered Gleam and the BEAM.
The simplest way to deploy points is with docker. Points binds to port 9000 so make sure to expose it. See this repo's docker-compose.yml for an example of using docker compose to run points.
It is also possible to deploy points via fly.io. This is how the version above is deployed. points works seamlessly with fly's networking to work as expected across any number of nodes. See this repo's fly.toml for an example configuration.
If you're running on one node no configuration is necessary
points assumes that the user will want to scale it across nodes as that's easy to do with OTP. If you don't need to scale no configuration is necessary. Just build the docker image and deploy it somewhere. However if you'd like it to scale the following options are available.
- DNS_CLUSTER_QUERY(default
erlang_node): This should resolve to a DNS name which, in the context that points is running, returns a list of every IP, V4 or V6, of the nodes points is running on. In the case of docker a network alias can be used. In the case offly.ioyou can use${FLY_APP_NAME}.internal. - ERLANG_COOKIE(default
OmNomNomNom): For production deploys this should be a secret value as it is a key which every node must have to connect to each other. - ERLANG_BASENAME(default
erlang_node): Every node is run with a name of${ERLANG_BASENAME}@<Node's IP>. This name doesn't really matter and will default toerlang_node. But if you need to avoid conflicts you can set it. - EXTRA_ERL_AFLAGS(default ``): Any number of extra flags to set.
-nameand `-setcookie` are the only two automatically set.
points aims to take full advantage of the BEAM and OTP. As such it can be scaled up and down and across many nodes while remaining a live multiplayer experience regardless of which node the users are connected to. This is done by implementing an eventually consistent approach where each user's connection knows the whole state of the room and when changes occur they are broadcast first to every connection in that room on the node and then the same message is broadcast across every node. This allows users to be in the same room but connected to arbitrary nodes.
When User A votes for 2, it tells all of the users on its node that it voted and then it tells all node communicators that it voted as well. This information is then synchronized across the cluster and sent back to each user.
┌────────┐ ┌────────┐ ┌────────┐
│User A │ │User B │ │User C │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
└────┬───┘ └────────┘ └────────┘
│ ▲ ▲
Vote for 2 │Update │Update
│ │ │
┌─────┼────────────┼────┐ ┌────┼────────────────────────┐
│ │ Node 1 │ ┼ │ │ │
│ │ │ │ │ │ │
│ │ │ │ │ │ │
│ ┌───▼──┐ ┌──┴───┐│ │ ┌──┴───┐ ┌──────────────┐┼
│ │A:2 │ │A:2 ││ │ │A:2 │ │node ││
│ │B:8 ├─────►│B:8 ││ │ │B:8 │◄───┼communicator ││
│ │C:5 │Vote │C:5 ││ │ │C:5 │Vote│ ││
│ └──┬───┘ └──────┘│ │ └──────┘ └──────────────┘│
└────┼──────────────────┘ └────────────────────▲────────┘
│ │
│ Vote │
└─────────────────────────────────────────┘