Files
caro/docs/project-overview.md
tiennm99 cbad690565 docs,chore: single-port 1999 websocket protobuf
Phase 05 — sync infrastructure and documentation with the typed-protobuf
refactor:
- docker-compose.yml: drop 1024/1025 mappings, single "1999:1999"
- server/Dockerfile: EXPOSE 1999, -p 1999 entrypoint
- README.md: rewrite transport description, architecture diagram, protocol
  section, server options, project structure, add proto:gen script note
- docs/project-overview.md: update transport + dependencies sections
- docs/system-architecture.md: rewrite diagrams + pipeline + file inventory
  for the WebSocket-only typed-dispatch path
- docs/codebase-summary.md: refresh file tree, java package inventory,
  gradle deps, vite deps, networking and game-flow sections
- docs/deployment-guide.md: single-port walkthrough for local / docker /
  systemd / nginx; remove all 1024/1025 firewall and troubleshooting
- docs/code-standards.md: replace dead ServerEventListener_CODE_* class-name
  example, fix sample ws:// URL to port 1999
2026-04-11 08:33:46 +07:00

8.1 KiB

Caro (Gomoku) — Project Overview & Requirements

What Is Caro?

Caro (also known as Gomoku or Five-in-a-Row) is a classic strategy board game. This project implements a multiplayer online version with:

  • Professional 2D game UI (browser-based)
  • Real-time server synchronization
  • AI opponents at multiple difficulty levels
  • Spectator mode to watch ongoing games

Version: 0.0.1 License: Apache 2.0 Base: Converted from ainilili/ratel (Landlords card game framework)


Core Features

Player vs Player (PVP)

  • Create rooms with custom settings
  • Join existing rooms to play against other players
  • Real-time board synchronization
  • Turn indicators and move history

Player vs AI (PVE)

  • Three difficulty levels:
    • Easy: Random valid moves
    • Medium: Simple heuristic (find winning move, block opponent)
    • Hard: Minimax scoring with depth 3+

Spectator Mode

  • Watch ongoing games in real-time
  • No ability to interact with board
  • Useful for learning strategies

Game UI

  • Client (Phaser 3): 800x800 board with wood texture, stone animations, sound effects, move history panel

WebSocket Protocol

  • Binary WebSocket: BINARY frames carrying TYPED PROTOBUF messages at port 1999
  • ws://localhost:1999/ratel endpoint
  • Typed message dispatch via ClientRequest records and sealed interface pattern
  • Single-port architecture (no legacy transports)

Game Rules

  • 15x15 board with standard Gomoku rules
  • Black plays first
  • Players alternate placing stones (black/white)
  • Win condition: First to form an unbroken line of 5 pieces in any direction (horizontal, vertical, diagonal)
  • Draw: All 225 board positions filled with no winner
  • Game duration: Typically 5-30 minutes (depends on player skill)

Target Users

Primary

  • Casual gamers — play in browser without installation
  • Competitive players — real-time multiplayer with friends
  • Learning players — practice against AI or spectate matches

Secondary

  • Developers — fork and extend the codebase (well-structured, documented)
  • Game developers — use as reference implementation for multiplayer game servers

Technical Stack Summary

Component Technology Details
Server Java 25 + Netty 4.1.128 Asynchronous, event-driven, low-latency
Network Protocol Typed Protobuf over WebSocket (binary frames) Single protocol, typed record dispatch
Game Logic Pure Java 25 (records, switch expressions) Board state, move validation, win detection, AI
Client Phaser 3 + Vite + Vanilla JS No framework dependencies (besides Phaser)
Build Gradle 9.x (Kotlin DSL) + Shadow plugin / Vite Standalone server jar + static client bundle
Deployment Docker Compose Two services: server + client

Feature Completeness Matrix

Feature Status Notes
PVP Multiplayer DONE Full room/lobby management
PVE AI (3 difficulties) DONE Random, heuristic, minimax
Spectator Mode DONE Real-time game observation
Client (Phaser 3) DONE Full-featured, polished UI
Sound Effects DONE Web Audio API (client)
Move Animations DONE Phaser physics + tweens
Game Replay NOT IMPLEMENTED Could store move history
Chat During Games NOT IMPLEMENTED Messaging layer separate from game
Persistent Accounts NOT IMPLEMENTED All players anonymous (no login)
Leaderboards NOT IMPLEMENTED No score tracking across sessions
Mobile Responsive PARTIAL Desktop-first design, touch not optimized
Alternative Board Sizes NOT IMPLEMENTED Hardcoded to 15x15
Tournament Mode NOT IMPLEMENTED Single games only

Non-Goals (Out of Scope)

  • Single-player offline mode — AI is PVE only, requires server
  • Persistent user accounts — design is stateless, no database
  • Monetization features — fully open-source, no premium content
  • Complex AI — current minimax is lightweight; alpha-beta pruning not implemented
  • Cross-platform mobile app — web-based only
  • Real-time chat — message system separate from game events
  • Game analytics — no telemetry or tracking

Success Criteria

Technical

  • All 37 unit tests passing (GomokuHelper + GomokuAI)
  • Server handles 100+ concurrent players without latency spike
  • Web client loads under 2 seconds on 4G
  • Zero data loss during network reconnection

User Experience

  • New player can join game in under 1 minute
  • Game moves appear on opponent screen within 500ms
  • AI makes moves within 1 second (all difficulties)
  • No crashes on invalid input

Code Quality

  • No dead code (lint passes)
  • All public methods documented with JSDoc/Javadoc
  • File size under 200 lines for maintainability
  • CI pipeline green (./gradlew build + npm run build)

Architecture Overview (High-Level)

┌─────────────────┐         ┌─────────────────────┐
│  Web Browser    │◄───────►│  Phaser 3 Client    │
│  (http://...)   │ Typed   │  (Vite + JS, :8080) │
└─────────────────┘ Protobuf└─────────────────────┘
                                      │
                                 WS :1999/ratel
                                 BINARY frames
                                      ▼
┌─────────────────────────────────────────────────────┐
│  Java 25 Netty Server (com.miti99.caro.server)      │
│  ├─ WebsocketTransferHandler (WS decoder)           │
│  ├─ RequestConverter (wire → ClientRequest)         │
│  ├─ RequestDispatcher (pattern-match dispatch)      │
│  └─ *Handler classes (14 typed request handlers)    │
└─────────────────────────────────────────────────────┘

Getting Started

Quick Start (Docker Compose)

git clone https://github.com/tiennm99/caro.git
cd caro
docker compose up --build -d
# Open http://localhost:8080

Quick Start (Local)

./server/gradlew -p server build -x test
java -jar server/build/libs/caro-server-0.0.1.jar
# In another terminal:
npm --prefix client install
npm --prefix client run dev
# Open http://localhost:5173

See deployment-guide.md for detailed setup instructions.


Key Stakeholders & Maintainers

  • Maintainer: @tiennm99
  • Original Framework: @ainilili (ratel)
  • Contributors: Community forks welcome

Dependencies & Versions

Dependency Version Purpose
Java 25 (LTS) Language runtime
Netty 4.1.128.Final Async networking
Protobuf 3.25.5 Binary serialization (WS wire)
protobufjs 7.5.4 JavaScript protobuf codec (client)
JUnit Jupiter 5.11.3 Test framework
Gradle 9.2.1 (wrapper) Java build tool
Shadow plugin 8.3.5 Fat jar packaging
Phaser 3.87.0 Web game engine
Vite 6.3.1 Web bundler
Node.js 22+ Client dev tooling

Known Limitations

  1. No persistence — all games lose history after server restart
  2. Single board size — only 15x15, no custom dimensions
  3. No accounts — players are anonymous by nickname
  4. AI depth limited — minimax scores at depth 3 only
  5. No chat — games-only communication
  6. Desktop-first — web client not mobile optimized
  7. No replay — games not recorded or reviewable

Contributing & License

  • License: Apache 2.0 (see LICENSE file)
  • Public source: https://github.com/tiennm99/caro
  • Contributions: Fork, branch, PR welcome
  • Code style: See code-standards.md

All contributions must:

  • Pass all unit tests
  • Follow code standards
  • Include Javadoc/JSDoc for public methods
  • Not introduce dead code (linting clean)