{"id":13802662,"url":"https://github.com/asrytis/dice-game","last_synced_at":"2025-05-13T13:32:38.058Z","repository":{"id":187768110,"uuid":"64503525","full_name":"asrytis/dice-game","owner":"asrytis","description":"A multiplayer dice game","archived":true,"fork":false,"pushed_at":"2023-09-20T03:52:41.000Z","size":11515,"stargazers_count":58,"open_issues_count":1,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-02-15T00:36:18.645Z","etag":null,"topics":["game","react-native"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asrytis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-29T18:51:03.000Z","updated_at":"2024-08-04T00:07:36.406Z","dependencies_parsed_at":null,"dependency_job_id":"7685f69c-e407-4e05-a72a-2e359a29a86f","html_url":"https://github.com/asrytis/dice-game","commit_stats":null,"previous_names":["asrytis/dice-game"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asrytis%2Fdice-game","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asrytis%2Fdice-game/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asrytis%2Fdice-game/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asrytis%2Fdice-game/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asrytis","download_url":"https://codeload.github.com/asrytis/dice-game/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253950285,"owners_count":21989334,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game","react-native"],"created_at":"2024-08-04T00:01:49.759Z","updated_at":"2025-05-13T13:32:37.504Z","avatar_url":"https://github.com/asrytis.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Multiplayer dice game\n\n\u003cimg src=\"https://github.com/asrytis/dice-game/blob/master/docs/images/gameplay.png\" align=\"right\"\u003e\n\nHey there! This is my first public repo and a playground for React Native. I didn't want to litter the net with yet another Todo List app and decided to go with a simple game instead.\n\nDeveloping a dice game was actually a programming task for a tech startup. The following were the original requirements:\n\n- First user in the system selects the number of dice to roll (1-4)\n- The game can begin when there are at least 2 users online\n- They roll the dice (by clicking the button)\n- The one with the greatest score wins\n- If they want they can play again\n- Dice are 6 sided (1-6)\n- When one player rolls the dice others have up to 5 seconds to respond, otherwise they will lose\n- The game is not limited to 2 players\n- Backend: Python or Node\n- Frontend: preferred: React.js + Redux, but you can use AngularJS too\n \nInstead of hacking something together in a few hours I decided to walk that extra mile and do a proper graphical design + go with React Native instead of building a Web App.\n\n## Installation\n\nType the following in terminal to install \u0026 run the server:\n\n```\ncd server\nnpm install \u0026\u0026 npm run start\n```\n\nTo run the client, make sure you have React Native CLI installed:\n```\nnpm install -g react-native-cli\n```\nThen run the following to install \u0026 run the app:\n```\ncd client/mobile\nnpm install \u0026\u0026 react-native run-ios\n```\n\nYou will need to have at least 2 clients running to be able to play. You can [run multiple simulators](http://stackoverflow.com/questions/26446346/xcode6-run-two-instances-of-the-simulator) or download the [tyrus-client-cli](https://repo1.maven.org/maven2/org/glassfish/tyrus/ext/tyrus-client-cli/1.1/tyrus-client-cli-1.1.jar) which I personally used while testing the game. The CLI is very easy to use:\n```\njava -jar tyrus-client-cli-1.1.jar ws://localhost:3000/ws\n```\n\n## Tech stack\n\n### Server\n\n* [Node JS](https://nodejs.org/) version 6 as a game server\n* [TypeScript](https://www.typescriptlang.org/) to sleep better at night and enjoy code completion\n* [Mocha](https://mochajs.org/) + [Chai](http://chaijs.com/) for TDD\n* [tyrus-client-cli](https://repo1.maven.org/maven2/org/glassfish/tyrus/ext/tyrus-client-cli/1.1/tyrus-client-cli-1.1.jar) to test WebSocket connection from command line\n\n### Client\n\n* [React Native](https://facebook.github.io/react-native/)\n* [Redux](https://github.com/reactjs/redux) to manage all the state\n* [redux-create-reducer](https://github.com/kolodny/redux-create-reducer) to manage verbosity\n* [redux-thunk](https://github.com/gaearon/redux-thunk)\n* [react-native-animatable](https://github.com/oblador/react-native-animatable) an excellent library with all sorts of common use animations\n* [react-native-router-flux](https://github.com/aksonov/react-native-router-flux) a React Native router that blends well with Redux\n* [ESLint](http://eslint.org/) with [Airbnb's linting rules](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb)\n\n## Server API\n\nThe basic idea is each websocket connection is treated as a new player. The server allocates players to virtual game rooms, 6 players per room. The game room itself is an implementation of a state machine pattern and transitions between setup, waiting, ready, and in-progress states based on various events.\n\n### HTTP\nTo get the number of active players online make a GET request to [http://localhost:3000/api/player-count]\n\nExample JSON response:\n```\n{\n    \"playerCount\": 3\n}\n```\n\n### WebSocket\n\nConnect to the game server via the following URL:\nws://localhost:3000/ws?**player_name**\n\nPlayer name is a string, for example \"John Doe\". If left blank, the server will generate a random name.\n\nTo keep things simple all the communication is done in JSON. Both incoming and outgoing messages conform to the following format:\n```json\n{\n    \"type\": \"\u003cstring\u003e\",\n    \"payload\": \"\u003cany\u003e\"\n}\n```\n\n#### Server sent messages\n\n#### SV_GAME_STATE\nOnce joined, the player receives full game state along with a unique player ID. See typescript definition of [gameRoom](https://github.com/asrytis/dice-game/blob/master/server/src/game-room.ts#L35) and [gameData interface](https://github.com/asrytis/dice-game/blob/master/server/src/game-room.ts#L22) in source code.\n\n```json\n{\n    \"type\": \"SV_GAME_STATE\",\n    \"payload\": {\n        \"state\": {\n            \"stateName\": \"GAME_STATE_SETUP\",\n            \"gameData\": {\n                \"round\": 0,\n                \"roundDuration\": 5000,\n                \"roundStarted\": null,\n                \"numberOfDice\": 0,\n                \"score\": {},\n                \"winners\": {}\n            },\n            \"players\": [\n                {\n                    \"id\": \"342f36af-df53-4cb8-be56-ec00b6f80267\",\n                    \"name\": \"Joe\"\n                }\n            ]\n        },\n        \"player\": {\n            \"id\": \"342f36af-df53-4cb8-be56-ec00b6f80267\",\n            \"name\": \"Joe\"\n        }\n    }\n}\n```\n\n#### SV_PLAYER_JOINED\nNew player has joined the game room.\n```json\n{\n    \"type\": \"SV_PLAYER_JOINED\",\n    \"payload\": {\n        \"id\": \"97013348-4960-4530-8634-9760a4d70582\",\n        \"name\": \"Rytis\"\n    }\n}\n```\n\n#### SV_PLAYER_LEFT\nPlayer has left the game room.\n```json\n{\n    \"type\": \"SV_PLAYER_LEFT\",\n    \"payload\": {\n        \"id\": \"97013348-4960-4530-8634-9760a4d70582\",\n        \"name\": \"Rytis\"\n    }\n}\n```\n\n#### SV_GAME_STATE_CHANGED\nGame state has changed. See the list of all game states below.\n```json\n{\n    \"type\": \"SV_GAME_STATE_CHANGED\",\n    \"payload\": \"GAME_STATE_WAITING\"\n}\n```\n\n#### SV_GAME_DATA_CHANGED\nYou will receive this notification everytime game data changes. Current server timestamp will be included along with the data that changed (not necessarily be the full gameData object!). See response example of [SV_GAME_STATE](#sv_game_state) for a full list of gameData properties.\n```json\n{\n    \"type\": \"SV_GAME_DATA_CHANGED\",\n    \"payload\": {\n        \"serverTime\": 1471437904627,\n        \"changes\": {\n            \"round\": 0,\n            \"roundStarted\": null,\n            \"score\": {},\n            \"winners\": {}\n        }\n    }\n}\n```\n\n### Client sent messages\n\n#### CMD_SET_DICE\nThe first player to join a room will have to choose the number of dice to play with. An integer between 1 and 4 is expected. The server will only process the command if the game is in GAME_STATE_SETUP state and sender is the first player on the room players list.\n```json\n{\n    \"type\": \"CMD_SET_DICE\",\n    \"payload\": 4\n}\n```\n\n#### CMD_ROLL_DICE\nRolls the dice! Works only if the game is in GAME_STATE_READY or GAME_STATE_IN_PROGRESS state.\n```json\n{\n    \"type\": \"CMD_ROLL_DICE\"\n}\n```\n\n### Game states\n* **GAME_STATE_SETUP** - waiting for the host (first player on the list) to select number of dice to play with. If host leaves, the next player will become the host. If there are no other players, the room will be closed.\n* **GAME_STATE_WAITING** - only 1 player in the room, waiting for at least 1 more to join\n* **GAME_STATE_READY** - waiting for players to start the round\n* **GAME_STATE_IN_PROGRESS** - round is in progress. Players have 5 seconds to roll the dice before the round ends.\n\n## Contribution\nThere's always room for improvement and I am open to comments, suggestions, and PRs. I would love to see client implementations in other languages/frameworks! A CLI client would be awesome.\n\n## Licence\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasrytis%2Fdice-game","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasrytis%2Fdice-game","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasrytis%2Fdice-game/lists"}