Keywords
- Section 1
- Multiplayer
- Game
- Pair-programming
- Real-time
Project Abstract
This repository contains a multiplayer web game that is meant to teach collaborative programming concepts. It utilizes pair-programming, where each user must complete their part to ensure the solution meets all requirements. The coder writes the code to solve the prompt. The quality assurance user cannot edit the code. They can write test cases, and run them. They can discuss potential approaches or failing tests and how to fix them with the coder.
High Level Requirement
From a user's perspective, the application must provide an intuitive way to complete their tasks. It needs to support low latency communication between clients. It also must support fast and secure untrusted code execution for user submissions and test cases. The scoring system must be robust and fair, prioritizing efficient code over fast submissions.
Conceptual Design
Tech Stack:
- Bun
- Node.js
- Next.js
- TypeScript
- Socket.io
- Socket.io Redis Adapter
- JavaScript
- Playwright
- Jest
- BetterAuth
- Prisma ORM
- PostgreSQL
- Redis
The frontend includes Bun as a runtime, which launches a Node.js websocket server using Next.js routing.
The backend is designed to be stateless and inherently scalable. Redis is used for game state, such as timers, code, etc. PostgreSQL is used for persistence data such as match results through Prisma ORM.
Background
Previous similar projects include leetcode.com and hackerrank.com, known for their programming challenges. They do not offer any form of collaboration, which fails to realistically simulate a developer's life.
Pair-programming has been shown to be "faster than solo programming when programming task complexity is low and yields code solutions of higher quality when task complexity is high." (See here).
We hope that necessitating pair-programming will encourage better testing, documentation, and communication among those learning to write code.
As far as we can tell, this is the first platform of its type.
Required Resources
To use the web application, a computer with an active internet connection will be required.
Development
To develop, you will need a computer with Git, Node, Bun, and Docker Compose.
Environment Setup
- Clone the repository.
- Create a
.envfile and populate it with the following (filling the tokens as needed, they shouldn't matter too much for local development):Remember to# config
PORT=3000
NODE_ENV=development
# better auth
BETTER_AUTH_SECRET=SOME_SECRET_TOKEN
BETTER_AUTH_URL=http://localhost:3000
# postgres
POSTGRES_USER=appuser
POSTGRES_PASSWORD=SOME_SECRET_TOKEN
POSTGRES_DB=appdb
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
# redis
REDIS_HOST=localhost
REDIS_PORT=6379
# executor image
EXECUTOR_PORT=6969
# for prisma
DATABASE_URL=postgresql://appuser:SOME_SECRET_TOKEN@localhost:5432/appdbsourceas needed! - Run
bun installto install the dependencies. - Run
bunx --bun prisma generateto generate the Prisma client and database migrations. - Run
docker compose -f ./dev-docker-compose.yml up -dto bring up the containers (you may need to run as root). - Run
bunx --bun prisma migrate devto bring the database up to schema. - Run
bunx --bun prisma db seedto add mock data to the dev database. - Run
bun devto launch the development server and navigate tolocalhost:3000to view the page. - When done,
docker compose -f ./dev-docker-compose.yml downwill bring the containers down.
Helpful Common Commands and Tricks
docker compose -f ./dev-docker-compose.yml down -vwill stop the containers and purge the volumes. Good if you really mess something up (you WILL lose data!).bunx --bun prisma migrate resetwill drop the DB (you WILL lose data!).- If your database is stuck out of sync and you can't apply migrations, run
rm -rf ./prisma/migrations/**to remove all pending migrations. Then recreate the migration withbunx prisma migrate dev --name devand apply it. - To see how the websockets are working, try opening up the game page in an incognito tab to be registered as a different client.
Testing
We use two testing libraries: Jest and Playwright. Jest is used for individual API tests while Playwright is used for end-to-end flow tests.
To run the Playwright tests, ensure you have the application running and run bunx playwright test --workers=1.
You may need to have Chromium headless installed.
For the Jest tests, run bunx jest tests/api/ --forceExit.
Collaborators
Made with contrib.rocks.