All Projects → fly-apps → tictac

fly-apps / tictac

Licence: Apache-2.0 license
Demonstration of building a clustered, distributed, multi-player, turn-based game server written in Elixir.

Programming Languages

elixir
2628 projects
HTML
75241 projects
javascript
184084 projects - #8 most used programming language
CSS
56736 projects
Dockerfile
14818 projects
shell
77523 projects
Makefile
30231 projects

Projects that are alternatives of or similar to tictac

react-globally
Gives you setGlobalState, so you can set state globally
Stars: ✭ 22 (-92.09%)
Mutual labels:  global
fourinarow-app
An online version of the popular game four in a row, written in Flutter + Dart on the client and Rust on the server side.
Stars: ✭ 23 (-91.73%)
Mutual labels:  global
hippo game live
Elixir & Phoenix LiveView game
Stars: ✭ 43 (-84.53%)
Mutual labels:  liveview
shlinked
An open-source satirical social network. shlinkedin.com
Stars: ✭ 287 (+3.24%)
Mutual labels:  liveview
uncharted
No description or website provided.
Stars: ✭ 31 (-88.85%)
Mutual labels:  liveview
mfpb
My Frugal PostBin
Stars: ✭ 26 (-90.65%)
Mutual labels:  liveview
CSGSI
A simple C# library to interface with Counter-Strike: Global Offensive's Game State Integration
Stars: ✭ 124 (-55.4%)
Mutual labels:  global
ecto nested changeset
Helpers for manipulating nested Ecto changesets
Stars: ✭ 23 (-91.73%)
Mutual labels:  liveview
download water data
Downloader for the Global Surface Water Data of the Copernicus Programme
Stars: ✭ 25 (-91.01%)
Mutual labels:  global
lit-state
Simple shared app state management for LitElement.
Stars: ✭ 93 (-66.55%)
Mutual labels:  global
google scraper live view
Application for extracting large amounts of data from the Google search results page
Stars: ✭ 17 (-93.88%)
Mutual labels:  liveview
gogtags
GNU global compatible source code tagging for golang
Stars: ✭ 42 (-84.89%)
Mutual labels:  global
serverless-create-global-dynamodb-table
serverless plugin that would create global dynamodb tables for specified tables
Stars: ✭ 25 (-91.01%)
Mutual labels:  global
ambry
Self-hosted audiobook streaming server
Stars: ✭ 38 (-86.33%)
Mutual labels:  liveview
plotex
Elixir plotting utilities library
Stars: ✭ 74 (-73.38%)
Mutual labels:  liveview
livebook
Automate code & data workflows with interactive Elixir notebooks
Stars: ✭ 3,402 (+1123.74%)
Mutual labels:  liveview
CSGO-Offset-Scanner
Java Based Cross-Platform CSGO Offset and Netvar Scanner
Stars: ✭ 28 (-89.93%)
Mutual labels:  global
gpkg
🌎 A global Node binary manager written in Rust
Stars: ✭ 53 (-80.94%)
Mutual labels:  global
kandesk
Simple Kanban application written in elixir using phoenix liveview
Stars: ✭ 157 (-43.53%)
Mutual labels:  liveview
global-prefix
Get the npm global path prefix. Same code used internally by npm.
Stars: ✭ 27 (-90.29%)
Mutual labels:  global

Tictac

This is a demonstration of building a clustered, distributed, multi-player, turn-based game server written in Elixir. As designed, it plays Tic-Tac-Toe, but was designed to be extended to play almost any multi-player turn based game.

This uses Phoenix LiveView for the UI, TailwindCSS for styles, libcluster for clustering the nodes, horde for providing a distributed process registry, and fly.io for hosting and multi-region clustering support.

You can read the blog post about it here: fly.io/blog/building-a-distributed-turn-based-game-system-in-elixir/

Try it out locally

To try the project out locally:

  • Install dependencies with mix deps.get
  • Install Node.js dependencies with npm install inside the assets directory
  • Start Phoenix endpoint with mix phx.server

Now you can visit localhost:4000 from your browser.

Since ths is multi-player, open a second browser window to the same address. localhost:4000

This is what a game looks like:

Local Game Example

Running it multi-node and clustered

To run it clustered locally, in a terminal window, run the following command:

PORT=4000 iex --name [email protected] --cookie asdf -S mix phx.server

In a separate terminal window, run this command:

PORT=4001 iex --name [email protected] --cookie asdf -S mix phx.server

Now in one browser window, visit localhost:4000.

From another browser window, visit localhost:4001.

You created two clients that are connected to two separate Elixir nodes which are clustered together! This is what it looks like where "ABCD" is a started game.

Multi-node local machine

Deploying it to Fly.io

Deploy this to your own Fly.io account and see it in action for yourself!

  • Setup your Fly.io account
  • Clone this repo
  • Register your app on Fly.io
fly launch --name my-special-custom-name
  • Take all the defaults. As for the region, choose sea (Seattle, Washington (US))
  • Replace the generated fly.toml file with the following config but keep the app name that you chose for your app.
app = "<my-special-custom-name>"

kill_signal = "SIGTERM"
kill_timeout = 5

[[services]]
  internal_port = 4000
  protocol = "tcp"

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20

  [[services.ports]]
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "30s" # allow some time for startup
    interval = "15s"
    restart_limit = 6
    timeout = "2s"
  • Setup your Phoenix secrets
$ mix phx.gen.secret
gZNW554LeBx4VGuG2U+X3fe7OCmk28g3OIE0Ia+OFRxS7+bhEm/2ZnIvnGTRo4DO

$ fly secrets set SECRET_KEY_BASE=gZNW554LeBx4VGuG2U+X3fe7OCmk28g3OIE0Ia+OFRxS7+bhEm/2ZnIvnGTRo4DO
Secrets are staged for the first deployment
  • Deploy!
fly deploy
  • Open it in the browser
fly open

At this point you have a working system. This is where most systems stop!

Take it Multi-Region!

Ready to take it to multiple regions? We've got one in Seattle on the West Coast, let's add one on the East Coast to cover the whole US.

  • Add a region ewr (Parsippany, NJ (US))
fly regions add ewr
  • Scale it up
fly scale count 2
  • Check the Status - Re-run this command to see it balance out
fly status
  • Check out the logs
fly logs

2021-03-31T14:28:22.880Z c9b72c04 sea [info] [info] [libcluster:fly6pn] connected to :"tictac@fdaa:0:1da8:a7b:ab3:1c48:eb59:2"
2021-03-31T14:28:22.881Z c9b72c04 sea [info] [info] Starting Horde.RegistryImpl with name Tictac.GameRegistry
2021-03-31T14:28:22.884Z c9b72c04 sea [info] [info] Starting Horde.DynamicSupervisorImpl with name Tictac.DistributedSupervisor
2021-03-31T14:28:22.890Z c9b72c04 sea [info] [info] Running TictacWeb.Endpoint with cowboy 2.8.0 at :::4000 (http)
2021-03-31T14:28:22.892Z c9b72c04 sea [info] [info] Access TictacWeb.Endpoint at https://tictac.fly.dev

The first log line shows the nodes are connected.

You now have a clustered Elixir application where users connect to the nearest server for them. This can provide a better user experience!

Fly region cluster

What will you build?

Tic-Tac-Toe is a simple game. This architecture could support any multi-player turn-based game you might think of. What cool game do you want to make?

Livebook notebooks!

I used Livebook notebooks to document the app logic in a regular Phoenix Web application! I created two notebooks to document how the game state works and also how a game server runs that state.

They are just plain markdown files as far as the project is concerned. Open them with Livebook and follow this guide to execute them in the context of the application.

You will find them in the notebook folder.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].