Thank you for your interest in contributing to Coup Online! This document provides guidelines and information to help you get started.
Use the Bug Report template to file a bug. The template will ask for:
- What happened -- a clear, concise description of the bug
- Steps to reproduce -- numbered steps to trigger the issue
- Device and browser -- dropdown selectors
- Anything else -- screenshots, room code, number of players, etc.
You can also report bugs directly from the in-app Settings modal (gear icon) via the "Report Bug" button.
Please search existing issues before creating a new one to avoid duplicates.
Feature suggestions are welcome! Use the Feedback / Feature Request template or click "Send Feedback" in the in-app Settings modal (gear icon). The template asks for:
- What would you like to see -- describe your idea or feedback
- Category -- Gameplay, UI/Design, Bots/AI, Mobile experience, or Other
- Anything else -- mockups, examples, or additional context
- Node.js 18+ (LTS recommended)
- npm (comes with Node.js)
- Git
# Fork and clone the repository
git clone https://github.com/your-username/coup-online.git
cd coup-online
# Install dependencies
npm install
# Start the development server
npm run dev
# Run tests
npm test
# Run tests in watch mode
npm run test:watchThe development server runs at http://localhost:3000 with hot reloading for both the Next.js frontend and the Express/Socket.io backend (via tsx).
docs/-- project documentation (CONTRIBUTING.md, PRD.md, BOT-STRATEGY.md)tests/-- test suite mirroringsrc/structure (tests/engine/,tests/server/,tests/app/)src/shared/-- types, constants, and protocol definitions shared between client and serversrc/engine/-- pure game logic with no I/O dependencies (start here if working on rules)src/server/-- Socket.io handlers, room management, state serializationsrc/app/-- Next.js App Router pages, components, hooks, stores, utils, and audioserver.ts-- application entry point wiring Express, Socket.io, and Next.js
- Strict mode is enabled (
strict: trueintsconfig.json) - Use explicit types for function parameters and return values in shared/engine code
- Prefer
interfaceovertypefor object shapes - Use
enumfor fixed sets of values (seeCharacter,ActionType,TurnPhase)
- Use descriptive variable and function names
- Keep functions focused -- single responsibility
- Engine code (
src/engine/) must remain pure: no timers, no I/O, no Socket.io references. Side effects are expressed as data (SideEffect[]) and applied by theGameEngine - Shared types go in
src/shared/types.ts; do not import server-only or client-only code into shared modules - All game constants (costs, timers, player limits) live in
src/shared/constants.ts
- React components:
PascalCase.tsx - Hooks:
useCamelCase.ts - Stores:
camelCaseStore.ts - Engine/server classes:
PascalCase.ts
- Use Tailwind CSS utility classes for all styling
- Follow the existing dark theme and color conventions
- Touch targets must be at least 48px for mobile usability
-
Create a branch from
mainwith a descriptive name:feature/add-spectator-modefix/steal-zero-coins-crashrefactor/extract-timer-logic
-
Make your changes with clear, focused commits
-
Run tests and make sure they pass:
npm test -
Test manually with at least 2 browser tabs to verify multiplayer behavior
-
Open a Pull Request against
mainwith:- A clear title summarizing the change
- A description of what changed and why
- Screenshots or recordings for UI changes
- Notes on any edge cases tested
-
Address review feedback -- maintainers may request changes before merging
- Tests pass (
npm test) - No TypeScript errors (
npx tsc --noEmit) - Tested with multiple players in the browser
- No console errors or warnings in the browser
- Game rules remain accurate (if engine code changed)
This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior by opening an issue.
If you have questions about contributing, feel free to open a discussion or issue on GitHub. We are happy to help!