Looking to design and develop an online game with this community

Introduction

Hi all,

Looking to design and develop this fun paper game from my childhood in digital with elixir, phoenix (channels, presence), and possibly LiveView with the members of this community.

I already have a working one with angular+socketio+python so this is a good learning curve with the elixir community.

Here is the game, rules, and a sample round of me trying to explain how the game works. This game might exist online already under different names for different cultures. I didn’t investigate.

Rules and Play

Design

I aim to follow the design principles that are demonstrated and explained brilliantly in this article as much as possible

https://www.theerlangelist.com/article/spawn_or_not

Aspirations (intentionally left vague)

  • Hoping for store nothing approach
  • If things need to be stored somewhere, prefer eviction and memory based storage.
  • things should keep a tidy house at all times within their scope.

Behaviours

Player

Scenario: New user identification success
Given I am an anonymous user
  and I visit the Game Server 
  and I am required to enter my name
When I enter "nickname"
Then the "nickname" is accepted

Scenario: New user identification, nickname non UTF-8 encoding
Given I am an anonymous user
  and I visit the Game Server 
  and I am required to enter my name
When I enter "0xC0, 0xC1, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF"
Then the "0xC0, 0xC1, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF" is rejected

Scenario: New user identification, nickname too long
Given I am an anonymous user
  and I visit the Game Server 
  and I am required to enter my name
When I enter "nickname longer than 20 characters"
Then the "nickname longer than 20 characters" is rejected

I will slowly expand the following Rooms, Gathering Hall, and Server as scenarios in time.

Rooms

  • Can be created
  • Should have a string identifying the name
  • Should have a string language identifying the language used in the room.
  • Should have an identifier of being private or public
  • Minimum 3 players needed to start a round and play the game.
  • Able to know which players are in the room
  • There is no maximum player limit to a room but should investigate for performance reasons.
  • Can be joined only, if it hasn’t reached maximum user count and no active round is in play
  • Can initiate a new round by the ‘administrator’ if there are more than 2 players in the room.
  • Can be destroyed by the creator or administrator
  • Can be destroyed only if there is no active round
  • Players should be able to chat with each other outside of an active round
  • Should do self-cleaning where possible

Round

  • Can be initiated by 'administrator
  • All the players should receive the first question at the roughly same time
  • After answering a question, player should be presented with the next one.
  • If a player finishes all their questions, they simply wait for all players to finish.
  • If the player count has fallen below the minimum players at any instance, the round should be abandoned
  • Should be able to identify which players have answered the current/past questions
  • Should have a maximum time set to end the round if it does not end by player interaction.
  • Round finishes when all the questions are answered by all the players`
  • Round should be able to display the stories on each player’s screen upon finishing.
  • Chat should be activated when a round has finishes regardless of reason
  • Should do self-cleaning where possible

Gathering Hall

  • Should list all the public rooms that are available to join
  • Should include name, language, player count of each room
  • Should be able to filter by language
  • Should be able to sort by player count
  • Should do self-cleaning where possible

Community

I want this to be a community effort where people can peer-review each other’s code and approach and we can all learn from each other in a fun small project.

Repositories

Elixir Library - GitHub - ykurtbas/elixir-www: Elixir library for the online multiplayer game WhoWhatWhere

Phoenix UI - GitHub - ykurtbas/phoenix-www: The phoenix application for WhoWhatWhere game

More Questions?

I didn’t take any further design restrictions and decisions.

I probably missed a couple of important points, either on purpose - not to dictate the design or genuinely forgot. Please ask away!

Please let me know what you think or ideas for implementation, developing together.

Review

Please have a look at the commits to check if I am on the right path, specifically where to mutate the players in the room.

6 Likes

Behavior Driven Development :slight_smile:

I haven’t seen this in ages. In a previous work I tried to convince my colleagues to use it, but without success :frowning:


Your game idea looks cool and the Programming Elixir 1.6 book Elixir for Programmers video course also builds the Hangman game in a very decoupled way, but not using Umbrellas, instead it uses path dependencies, also called Poncho projects by the Nerves community.

The video course:

EDIT:

The book from the same author, but as @kokolegorille pointed out below is not the same content as the video course, as I misleading said initially:

1 Like

I always loved it as it helps to define threat vectors and code defensively :slight_smile: as well as other multiple benefits.

Showing someone some text and they can visualise it in their head without me going through some wireframes and talking it through!

I have the book in my O’Reilly and I think I skipped that part as I wanted to learn the basics back then. I will definitely have a read-through now, those sound interesting!

Ideally, the whole thing would be a runnable code with gen-server (doesn’t matter how it is packaged) and then the phoenix app puts the UI, socket capabilities around it.

1 Like

That is exactly what is done in the Elixir for Programmers video course form @pragdave, but without using Umbrellas, and makes each part of the game reusable as standalone projects, like the Dictionary that powers the game.

1 Like

AFAIK I don’t think it is the same content. The hangman game is only in the video course, as well as the poncho organization. While the book is more on the Elixir language.

3 Likes

Oh, it was a long time ago that I made both and got confused now :frowning:

Thanks for the correction :slight_smile:

2 Likes

I have been building some servers for 2 players board game (chess and go), as a hobby, when I started Elixir. It teached me a lot about OTP.

But I can tell managing the game is not the most complicated. You need to manage match maker, tournaments, clocks, ratings. I also enjoyed to see what happens when You kill random processes, and see the system heals.

Building a lobby, a match maker, a room manager is really fun. Whatever the frontend You choose.

4 Likes

Hoping it will do the same to me and more people :relaxed: it would be a fun community thing to do.

When things don’t work out as expected this will be the first place to come and ask for help anyways, best to get you guys involved earlier :grin:

1 Like

I need some help wrapping my head around GS, supervisors, and processes.

Following is my current experimental state, where I have WWW GS and Hall, Room, Player structs.

I think my ideal setup should be Application managing a long stable Hall GS/process to list the rooms and online players.

A Room GS - or supervised module, hence my confusion - that spawns room processes for the room when you create one so if one room fails doesn’t affect the hall

a chat process within each spawned room to handle the chat.
a round process within the room to handle round and disappear when we are done with the round or start another one.

(I had a look at ETS tables and Sasa Juric mentions do the process and mutation one first to see if you need the performance need for ETS)

I have several questions about:

  • Do I spin up GS for Hall, Room, Chat, Round and use supervisor to create processes (instances) of them?
  • where to hold my state, globally or per individual process, or both? in either scenario, do I communicate data through messages?

I think I have made some progress.

Now, need to figure out how to pass state, context to my newly created gen servers.

How to shut them down cleanly also, so unless I can find them in children I will have to keep a handle to them somewhere.

I have seen some context examples with child_spec methods but at this stage, they are black magic, don’t understand the concept - yet.

image

Hey @cenotaph! I recently released a PoC Elixir application that is similar to what you are talking about. I did it as a multi-player turned-based Tic-Tac-Toe game. But the game itself is really a “placeholder” for any kind of game that works in turns.

You can find it here: GitHub - fly-apps/tictac: Demonstration of building a clustered, distributed, multi-player, turn-based game server written in Elixir.

Hopefully it can help! I’m happy to answer any questions as well.

6 Likes

@brainlid thank you! This is amazing guidance and help. I don’t have the need for Horde. DynamicSupervisor would be enough for me.

The main difference I aim to store the state in a GenServer, not sure how the updated state would reflect to list my rooms, players.

Is this how I would pass context to dynamic spinup of my RoomServer per room?

Horde is helpful if you want multi-node support (ie clustered nodes). But if you don’t want that, then just use Registry. Horde.Registry is API-compatible with Registry.

https://hexdocs.pm/elixir/Registry.html

Registry handles matching your Game ID to the running server/pid. So using the tictac app as a starting point, you just replace Horde.DynamicSupervisor with DynamicSupervisor and Horde.Registry with Registry.

When I was creating this, that’s how I actually started it out. :slight_smile:

Registry is great and uses ETS under the hood. Just a built-in support for what you need.

3 Likes

Thanks to your code I have managed to spin up my rooms with the room context I needed.

I thought the id would also nicely name the process but haven’t been successful.

3 Likes

I found this repo very helpful. GitHub - nshafer/answercast_lv: Forkable repo for entries in Phoenix Phrenzy (https://phoenixphrenzy.com/)

I had to resolve a few bugs to get it working, but the process was straightforward. Uses GenServer, broadcasting, a game registry, pinging, process persistence.

I created a game concept that works well in development mode, but not yet deployed into production.

My game includes per game chat. I’ll try to get involved in your repo.

2 Likes

Hi @cenotaph, for state management you can check out the book by @lance Halvorsen, which is amazing. It uses a state machine to manage the state of a battleship game which was very helpful for my own little round-based game.

4 Likes

Thanks for the plug, @marcelfahle! A number of people have told me that the state machine chapter was their favorite one in the book. I know I had the most fun writing it. Cheers!

2 Likes

You can also go through “Designing Elixir Systems with OTP”.

1 Like