A real-time multiplayer snake game with an always-active AI opponent.
Play it live at: snake.heyanabelle.com
This project implements a classic Snake game with real-time multiplayer capabilities. The game uses a centralized server architecture to manage game state, with Socket.IO for real-time communication between clients and server.
- Multiplayer: Play with friends in real-time
- AI Snake: Always-present AI opponent that adapts its difficulty based on length
- Player Management: Handles players joining, leaving, and preserves stats (score, deaths) for returning players
- Deterministic Game Logic: Ensures all players experience the same game events
- Power-Ups: Collect power-ups for temporary effects:
- SPEED: Move faster than other players
- SLOW: Move at half speed
- INVINCIBILITY: Pass through other snakes without dying
- DOUBLE_SCORE: Double points for eating food
- Collision Detection: Handles snake-snake collisions with death tracking
- Score Tracking: Updates and syncs scores based on food consumption and multipliers
- Responsive UI: Built with React and TypeScript
- Frontend: React with TypeScript, using Socket.IO for client-server communication
- Backend: Node.js server using Socket.IO for real-time state synchronization and game logic
- Game Loop: Server-managed tick system ensures consistent gameplay across all clients
- Testing: Jest (unit/integration), Cypress (E2E)
- Linting/Formatting: ESLint, Prettier
- Git Hooks: Husky, lint-staged
- CI/CD: GitHub Actions for automated testing and deployment
- Node.js (v18 or later recommended)
- npm (usually comes with Node.js)
# Check versions
node -v
npm -v
-
Clone the repository:
git clone https://github.com/anabelle/p2p-snake.git cd p2p-snake
-
Install dependencies:
# Using npm ci is recommended for CI environments or clean installs npm ci # Or, for typical development: npm install
You can run both the React frontend and the backend server simultaneously:
npm run start:dev
This will:
- Start the game server on port 3001
- Start the React app on port 3000
- Configure the React app to use localhost:3001 as the server
Alternatively, you can run them separately:
-
Start the Game Server:
npm run start:server
-
Start the React App:
npm start
To manually lint and format the codebase:
# Lint and attempt to fix issues
npm run lint
# Format the code
npm run format
Run the Jest unit and integration tests:
# Run tests once
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with coverage report
npm test -- --coverage
Run the Cypress E2E tests. This requires the development server to be running (npm run start:dev
).
# Open the Cypress Test Runner UI
npm run cypress:open
# Run Cypress tests headlessly in the terminal
npm run cypress:run
- Open the game in your browser (typically
http://localhost:3000
when running locally) - You'll automatically be connected to the game server
- Use the arrow keys or WASD to control your snake
- Collect food (red circles) to grow your snake and earn points
- Collect power-ups for temporary advantages
- Avoid collisions with other players' snakes and the AI snake
- Your score and stats persist if you return to the game
This project uses GitHub Actions for automated deployment.
- Pushing to the
main
branch triggers the CI workflow (unit-test.yml
, thene2e-test.yml
). - If both unit and E2E tests pass on
main
, thedeploy.yml
workflow is triggered. - The
deploy.yml
workflow builds the production version of the frontend and deploys the contents of thebuild/
directory via FTP to the production server.
No manual deployment steps are typically required.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-new-feature
- Make your changes.
- Important: This project uses pre-commit hooks (Husky + lint-staged) to automatically lint and format your code before committing. Ensure these hooks run successfully.
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin feature/my-new-feature
- Submit a pull request against the
main
branch. - Your pull request will automatically trigger the CI workflow (
unit-test.yml
,e2e-test.yml
) to run checks.