YOVI is a fully deployed web platform for playing Game Y โ an abstract strategy board game where two players compete to connect all three sides of a triangular board. Developed as part of the Software Architecture (ASW) course at the University of Oviedo.
๐ฎ Play now โ yovi.13.63.89.84.sslip.io
![]() Ana Pรฉrez Bango UO294100@uniovi.es |
![]() Adriana Garcรญa Suรกrez UO300042@uniovi.es |
Game Y is an abstract two-player strategy game played on a triangular board. Each player takes turns placing pieces of their colour. The first player to form a connected group that simultaneously touches all three sides of the triangle wins.
B โ Blue (B) piece
. B
B B ยท
ยท ยท B ยท
ยท ยท ยท B ยท
Blue wins by connecting the top, left, and right edges with a single connected group. Simple rules, deep strategy.
| Feature | Description |
|---|---|
| AI opponents | Six difficulty levels from random to Monte Carlo Tree Search |
| Real-time multiplayer | Private rooms with shareable codes via Socket.IO |
| Admin panel | Manage users, roles, and account data |
| User profiles | Editable name, bio, location, and preferred language |
| Social | Friend requests, friend list, and user search |
| Notifications | In-app friend request and welcome notifications |
| Statistics | Match history, personal stats, and top-10 ranking |
| Hint system | AI-powered move suggestions during gameplay |
| Internationalization | English and Spanish |
| Themes | Dark and light mode, persisted per user |
| Bot interop API | External bots can compete against our AI via REST |
| Monitoring | Prometheus metrics + Grafana dashboard |
YOVI follows an eight-service microservices architecture with Nginx as the single public entry point.
Browser / External Bot
โ
โผ
Nginx (80 / 443)
โ
โโโ / โ webapp:80 React SPA
โโโ /api/* โ gateway:8080 REST API
โโโ /socket.io/* โ multiplayer:7000 WebSocket (Socket.IO)
โโโ /interop/* โ botapi:4001 Bot interoperability API
Gateway routes internally to:
โโโ authentication:5000 register ยท login ยท verify
โโโ users:3000 profiles ยท friends ยท notifications ยท admin ยท game results
โโโ gamey:4000 game logic ยท bot moves ยท hints
โโโ multiplayer:7000 room management (REST)
Multiplayer and BotAPI also call:
โโโ gamey:4000 game/new ยท pvp/move ยท pvb/move ยท ybot/choose
Key architectural decisions: Rust was chosen for the game engine for memory safety and performance. Socket.IO powers real-time multiplayer with automatic reconnection. JWT with role claims enables stateless admin authorization without extra database lookups. See the Arc42 architecture docs and Architecture Decision Records for full rationale on all 16 architectural decisions.
yovi_en2c/
โโโ webapp/ # React + TypeScript SPA (Vite)
โโโ gateway/ # Node.js + Express API gateway (port 8080)
โโโ authentication/ # Node.js + Express JWT auth service (port 5000)
โโโ users/ # Node.js + Express user management (port 3000)
โโโ gamey/ # Rust + Axum game engine (port 4000)
โโโ multiplayer/ # Node.js + Socket.IO PvP service (port 7000)
โโโ botapi/ # Node.js + TypeScript interop API (port 4001)
โโโ nginx/ # Reverse proxy config + TLS certs
โโโ tests/load/ # k6 load test scripts
โโโ docs/ # Arc42 architecture documentation
| Bot ID | Algorithm | Difficulty |
|---|---|---|
random_bot |
Random valid move | โ |
heuristic_bot |
Side connection heuristic | Easy |
minimax_bot |
Minimax (depth 3) | Medium |
alfa_beta_bot |
Minimax + alpha-beta pruning | Hard |
monte_carlo_hard |
Monte Carlo Tree Search | Expert |
monte_carlo_extreme |
MCTS (more iterations) | Extreme |
All strategies implement the YBot Rust trait โ adding a new strategy requires only a new struct and
one registration call. See the Bot Implementations wiki page.
All game state is exchanged in YEN (Y Exchange Notation), a JSON format inspired by chess FEN:
{
"size": 5,
"turn": 0,
"players": ["B", "R"],
"layout": "B/BR/.R./..../....."
}sizeโ board edge length (size 7 โ 28 total cells)turnโ index intoplayersarray (0 = Blue's turn)playersโ token characters; Blue (B) always moves firstlayoutโ rows separated by/;.= empty,B/R= occupied
External bots can compete against our AI at:
https://yovi.13.63.89.84.sslip.io/interop
Create a game and play:
# 1. Create a game against random_bot
curl -X POST "https://yovi.13.63.89.84.sslip.io/interop/games" \
-H "Content-Type: application/json" \
-d '{"size": 5, "bot_id": "random_bot"}'
# โ {"game_id": "...", "position": {...YEN...}, "status": "ONGOING"}
# 2. Play a move (send updated YEN with your piece placed)
curl -X POST "https://yovi.13.63.89.84.sslip.io/interop/games/{game_id}/play" \
-H "Content-Type: application/json" \
-d '{"position": {...YEN with your move...}}'
# โ {"position": {...YEN after bot response...}, "status": "ONGOING"}
# 3. Stateless move (no session required)
curl "https://yovi.13.63.89.84.sslip.io/interop/play?position={YEN_JSON}&bot_id=heuristic_bot"Full OpenAPI 3.1 spec at botapi/src/openapi/openapi.yaml.
Requires Docker and Docker Compose.
1. Create a .env file at the project root:
MONGODB_URI=mongodb+srv://<user>:<password>@cluster.mongodb.net/yovi
JWT_SECRET=your_secret_key_here
JWT_EXPIRES=24h2. Build and start all services:
docker-compose up --build3. Open the app: http://localhost
| Service | URL |
|---|---|
| Web application | http://localhost |
| Bot interop API | http://localhost/interop |
| Prometheus | http://localhost:9090 |
| Grafana | http://localhost:9091 (admin / admin) |
Requires Node.js โฅ 20 and Rust.
# Start all backend services
cd users && npm install && npm start # :3000
cd authentication && npm install && npm start # :5000
cd gateway && npm install && npm start # :8080
cd multiplayer && npm install && npm start # :7000
cd botapi && npm install && npm run build && npm start # :4001
cd gamey && cargo run -- --mode server --port 4000 # :4000
# Start the frontend
cd webapp && npm install && npm run dev # :5173cd users && npm test # Jest + mongodb-memory-server
cd authentication && npm test # Vitest + Supertest
cd gateway && npm test # Vitest + Supertest
cd multiplayer && npm test # Jest + socket.io-client
cd botapi && npm test # Vitest + Supertest
cd gamey && cargo test # unit + integration + property-based (proptest)cd webapp && npm run test:e2e # Playwright# Requires k6: https://k6.io/docs/getting-started/installation/
./tests/load/run_load_tests.sh # local
./tests/load/run_load_tests.sh https://yovi.13.63.89.84.sslip.io/api # production| Scenario | VUs | p95 threshold |
|---|---|---|
| Registration | 50 | < 2 000 ms |
| Login | 50 | < 1 500 ms |
| Start game | 20 | < 3 000 ms |
See the Load Testing Guide and Load Testing Results.
Prometheus scrapes metrics from gateway, users, and gamey every 15 seconds. The "Yovi Services Overview" Grafana dashboard shows request rate, p95 latency, and error rate for all three services in real time.
- Prometheus: http://localhost:9090
- Grafana: http://localhost:9091
See the Monitoring wiki page.
| Resource | Link |
|---|---|
| ๐ Arc42 Architecture Docs | arquisoft.github.io/yovi_en2c |
| ๐ GitHub Wiki | wiki home |
| ๐ง Architecture Decision Records | 16 ADRs documented |
| ๐ Bot API OpenAPI spec | openapi.yaml |
| ๐ CI/CD Pipeline | pipeline docs |
| ๐งช Usability Testing | usability results |
This project is developed for educational purposes as part of the ASW course at the University of Oviedo.


