A catcher game web app where the user controls a boat with the mouse and catches falling items. Based on the type of the item, the score is calculated. When the game ends, players can enter their names and submit their scores to the Leaderboard.
The Leaderboard displays the top 100 players with the highest scores in decreasing order.
This game is built on a microservice architecture with two microservices: client
and leaderboard
, managed by Docker and Kubernetes. The development workflow is overseen by Skaffold (https://skaffold.dev), which handles the processes of building, pushing, and deploying our application.
- Multiple microservices can be added, and different teams can work on the project independently.
- Asynchronous communication using an event bus like JetStream or Kafka can be easily configured.
- GitHub workflows are in place for CI/CD. These workflows include automated tests upon the creation of a pull request and automated deployment when code is pushed to the
main
branch.
The client
is a React application created using "create-react-app"
. It utilizes Redux to manage the global state.
The leaderboard
is an Express application that fetches and stores player data from a MongoDB database.
The following development tools must be installed (in the same order) on your machine before you begin editing the code.
- Docker Desktop. (https://www.docker.com/products/docker-desktop)
- Enable Kubernetes from Settings in Docker Desktop. Before proceeding, make sure that docker and kubernetes are running and configured correctly.
ingress-nginx
for Docker Desktop. (https://kubernetes.github.io/ingress-nginx/deploy/#docker-desktop). I recommend usingkubectl
to installingress-nginx
with the following command.kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
- Skaffold (https://skaffold.dev)
- Edit your
hosts
file and add"127.0.0.1 catcher.amansingh.dev"
at the end of the file. Editing this file require admin privileges.hosts
file can be found at:
Windows -C:\Windows\System32\drivers\etc
Mac & Linux -/etc/hosts
- Extract
catcher.zip
or clone the repository. - Pull the required images from docker hub using the following command or build the images locally.
docker pull amansinghs/catcher-client && docker pull amansinghs/catcher-leaderboard
- Run the following command from the project root directory.
skaffold dev
- Visit
catcher.amansingh.dev
from your web browser. - Your web browser will show you an HSTS error because of self-signed SSL certificate from Kubernetes. Type
"thisisunsafe"
anywhere in the browser window to bypass this screen. Note that this is only for development environment. Correct SSL certificate is already in place for production environment.
Skaffold will automatically create the required Deployments
and Services
. If you edit any file, it will re-deploy the latest changes. See skaffold.yaml
for details.
Note: There is a known bug with Skaffold where the deployments fail to stabilize sometimes. (GoogleContainerTools/skaffold#8972). Just add "--tolerate-failures-until-deadline"
flag with "skaffold dev"
command.
skaffold dev --tolerate-failures-until-deadline
GET
/api/leaderboard
(Fetches Top 100 players sorted by score in decreasing order)
name type data type description N/A N/A N/A N/A
http code content-type response 200
application/json
[{id: '1', name: 'Player Name', score: 100}]
500
application/json
{errors: [{message: 'Something went wrong'}]}
POST
/api/leaderboard
(Saves player name and score)
name type data type description name required string name of the player score required number player's score
http code content-type response 201
application/json
{id: '1', name: 'Player Name', score: 100}
400
application/json
{errors: [{message: 'Player name is required', field: 'name'}, {message: 'Invalid score', field: 'score'}]}
500
application/json
{errors: [{message: 'Something went wrong'}]}
name | type |
---|---|
id |
ObjectId |
name |
string |
score |
number |
- Collision detection is not perfect. Sometimes if the mouse is placed in a certain way, game fails to register the
catch
event.
- Add Levels with increasing difficulty. For example, item fall speed will increase every four items caught with a positive score.
- Currently, the game requires a mouse to play. If a user is on a mobile device, move the the boat using tilt events.
- Create a separate npm module
common
to store common code such as Error classes, middlewares, events, etc.