Online tabletop game set in the atomic world. For one or two players.
- Node.js
- Express
- Socket.io
- Bootstrap 5
- JavaScript Vanilla
- Jest
- Playwright
- Node.js 14 or higher
- npm
- Clone the repository.
- Install dependencies:
npm install
- Create local environment:
cp .env.example .env
- Development with automatic reload:
npm run dev
- Standard execution:
npm start
Application available at http://localhost:3000.
- Unit tests:
npm test
- Unit tests (watch):
npm run test:watch
- E2E tests:
npm run test:e2e
- E2E tests for CI (with 1 retry for flaky scenarios):
npm run test:e2e:ci
Playwright starts the web server automatically for E2E tests and reuses an existing server when one is already running on port 3000.
- Currently there are 2 scenarios marked as
fixmeintests/e2e/game-flow.spec.js:Multi-step cascade explosions produce animation sequenceWin condition triggers when opponent has no atoms
- Reason: unstable multi-client synchronization between browsers (timing/race conditions in Chromium/WebKit).
- Current E2E test suite status: passes correctly with those cases omitted.
- Chain-reaction animations (
18.6): visually verify that the sequence is clear and smooth in real browser. - Screen reader (
18.9): validate ARIA announcements with NVDA or VoiceOver during turns, errors, and game end.
- Open the app in two tabs or two browsers.
- Choose game mode:
Vs Jugadorfor multiplayerVs Máquinafor single-player mode
- Press
New Gameto create a session. - In
Vs Jugador, the second player joins using the same session in the other tab. - On your turn, select an empty cell or your own cell to add an atom.
- When a cell reaches its critical mass, it explodes and distributes atoms to adjacent cells.
- The last player to keep atoms on the board wins.
- Default board size:
6x6. - Allowed size: from
4x4to10x10. - Player colors:
- Player 1: Blue
#007bff - Player 2: Orange
#fd7e14
- Player 1: Blue
- Base animation delay:
300ms.
client:statusRequestclient:game:startclient:game:moveclient:game:stateRequest
server:statusUpdateserver:game:startedserver:game:machineMoveserver:game:stateUpdateserver:game:turnChangedserver:game:ended
error:internalerror:game:invalidMoveerror:game:notYourTurnerror:game:notActiveerror:game:notFounderror:game:roomFull
src/server/: Express and Socket.io serversrc/client/: Client HTML, CSS and JavaScripttests/unit/: Unit teststests/e2e/: End-to-end testsopenspec/: Specification artifacts
- Lint:
npm run lint
- If the server fails to start due to port already in use:
- check processes on port
3000and free the port
- check processes on port
- If board cells don't appear:
- verify Socket.io connection and that
server:game:startedis being emitted
- verify Socket.io connection and that
- If Playwright fails due to server unavailable:
- confirm that
http://127.0.0.1:3000/healthresponds with{"status":"ok"}
- confirm that
- If accessibility tests fail:
- check
aria-label,aria-liveattributes and visible focus on cells/buttons
- check