Files
caro/docs/codebase-summary.md
T
tiennm99 ce101bd778 docs: add comprehensive project documentation
- project-overview-pdr.md: PDR, goals, features, tech stack
- system-architecture.md: diagrams, protocol, event codes, data flow
- codebase-summary.md: module breakdown, key classes, test structure
- code-standards.md: Java/JS conventions, JSDoc, Git rules
- deployment-guide.md: build, run, CI/CD, troubleshooting
- project-roadmap.md: completed phases, future ideas, decision log
2026-04-10 13:37:54 +07:00

17 KiB

Codebase Summary

Directory Structure

caro/
├── .github/
│   └── workflows/
│       ├── Build.yml                    CI: build + test
│       └── deploy-pages.yml             CD: deploy web client to GitHub Pages
├── landlords-common/                    Shared Java library (game logic, entities, protocol)
│   ├── src/main/java/org/nico/ratel/landlords/
│   │   ├── channel/                     Netty utilities
│   │   ├── entity/                      Data models (Board, Room, GameMove, etc.)
│   │   ├── enums/                       Type definitions (ServerEventCode, ClientEventCode, etc.)
│   │   ├── exception/                   Custom exceptions
│   │   ├── features/                    Feature flags
│   │   ├── handler/                     Protocol codec (Protobuf decoder)
│   │   ├── helper/                      Game logic & utilities
│   │   ├── print/                       Terminal formatting
│   │   ├── robot/                       AI engine (GomokuAI)
│   │   ├── transfer/                    Binary serialization (ByteKit, ByteLink)
│   │   └── utils/                       General utilities (JSON, List, Options, Time)
│   ├── src/test/java/
│   │   ├── helper/tests/GomokuHelperTest.java
│   │   └── robot/tests/GomokuAITest.java
│   └── pom.xml
├── landlords-server/                    Java Netty server (TCP + WebSocket)
│   ├── src/main/java/org/nico/ratel/landlords/server/
│   │   ├── event/                       ServerEventListener_* handlers
│   │   ├── handler/                     Netty pipeline handlers
│   │   ├── proxy/                       Message sending (ProtobufProxy, WebsocketProxy)
│   │   ├── timer/                       Background tasks (cleanup, heartbeat)
│   │   ├── SimpleServer.java            Server entry point
│   │   ├── ServerContains.java          Global state container
│   │   └── ... (event listeners)
│   ├── src/main/resources/
│   │   └── static/                      Built-in web UI (index.html, CSS, JS, images)
│   ├── src/test/java/                   (if any)
│   └── pom.xml
├── landlords-client/                    Java CLI client
│   ├── src/main/java/org/nico/ratel/landlords/client/
│   │   ├── entity/                      Client-specific entities
│   │   ├── event/                       ClientEventListener_* handlers
│   │   ├── handler/                     Protocol handlers
│   │   ├── proxy/                       Message sending
│   │   └── SimpleClient.java            CLI entry point
│   └── pom.xml
├── web-client/                          Phaser 3 + Vite web client
│   ├── src/
│   │   ├── main.js                      Phaser boot
│   │   ├── config/
│   │   │   ├── game-config.js           Phaser configuration
│   │   │   └── protocol-constants.js    Event code enums
│   │   ├── scenes/
│   │   │   ├── boot-scene.js            Initialize, connect to server
│   │   │   ├── menu-scene.js            Menus (overlay DOM)
│   │   │   └── game-scene.js            Main gameplay scene
│   │   ├── services/
│   │   │   ├── event-bus.js             Pub/sub event dispatcher
│   │   │   ├── connection-service.js    WebSocket client
│   │   │   └── game-state-service.js    Client-side state
│   │   ├── objects/
│   │   │   ├── board.js                 Game board renderer
│   │   │   └── stone.js                 Individual stone sprite
│   │   └── ui/
│   │       ├── menu-ui.js               Menu components
│   │       └── game-ui.js               Game HUD & notifications
│   ├── index.html
│   ├── vite.config.js
│   ├── package.json
│   └── dist/                            (build output)
├── docs/                                (this directory)
│   ├── project-overview-pdr.md
│   ├── system-architecture.md
│   ├── codebase-summary.md
│   ├── code-standards.md
│   ├── deployment-guide.md
│   └── project-roadmap.md
├── plans/                               (implementation plans)
├── pom.xml                              Maven parent POM
├── README.md
├── LICENSE
└── .gitignore

Key Java Modules

landlords-common (Shared Library)

Entities:

  • Board.java — 15x15 game board, move validation, win/draw detection

    • BOARD_SIZE = 15
    • WIN_CONDITION = 5
    • Methods: isValidMove(), makeMove(), checkWin(), reset()
  • Room.java — Game session state

    • id (UUID), type (PVP/PVE), status (WAITING/PLAYING/FINISHED)
    • players (2), spectators, board, moveHistory
  • GameMove.java — Single move record

    • row, col, piece (BLACK/WHITE), timestamp
  • ServerTransferData.java — Network message from client

    • code (ServerEventCode), data (payload), info (metadata)
  • ClientTransferData.java — Network message from server

    • code (ClientEventCode), data, info
  • ClientSide.java — Player connection state

    • nickname, status (ONLINE/OFFLINE/PLAYING), role (PLAYER/SPECTATOR)

Enums:

  • ServerEventCode (14 codes) — client→server actions
  • ClientEventCode (24 codes) — server→client responses
  • PieceType — EMPTY, BLACK, WHITE
  • GameResult — IN_PROGRESS, BLACK_WIN, WHITE_WIN, DRAW
  • RoomType — PVP, PVE
  • RoomStatus — WAITING, PLAYING, FINISHED
  • ClientRole — PLAYER, SPECTATOR
  • ClientStatus — ONLINE, OFFLINE, PLAYING

Game Logic:

  • GomokuHelper.java — Win detection (checks 4 directions)

    • canWin(Board, row, col, piece) → boolean
    • getWinCount(Board, row, col, piece, direction) → int
    • 37 unit tests in GomokuHelperTest.java
  • GomokuAI.java — AI move selection (3 difficulties)

    • getNextMove(Board, difficulty) → GameMove
    • getEasyMove() — random valid move
    • getMediumMove() — find win or block opponent
    • getHardMove() — minimax scoring at depth 3
    • 37 unit tests in GomokuAITest.java

Utilities:

  • JsonUtils.java — Serialize/deserialize POJO ↔ JSON
  • ListUtils.java — List filtering, mapping
  • OptionsUtils.java — Command-line argument parsing
  • StreamUtils.java — I/O helpers
  • TimeHelper.java — Timestamp formatting
  • I18nHelper.java — Internationalization (English)
  • MapHelper.java — Map utilities

Protocol:

  • ByteKit.java — Byte buffer operations
  • ByteLink.java — Byte stream builder
  • TransferProtocolUtils.java — Serialize/deserialize messages
  • DefaultDecoder.java — Protobuf message decoder

landlords-server (Netty Server)

Entry Point:

  • SimpleServer.java — Bootstrap
    • Parses args: -p {port} (default: 1024)
    • Creates two Netty ServerBootstrap instances (TCP + WebSocket)
    • Registers handlers in pipeline

Event Handlers (ServerEventListener_*):

  • CODE_CLIENT_NICKNAME_SET — Store player nickname
  • CODE_ROOM_CREATE / CODE_ROOM_CREATE_PVE — Create room, assign players
  • CODE_GET_ROOMS — Send room list to client
  • CODE_ROOM_JOIN — Add player to existing room
  • CODE_GAME_STARTING — Check both players ready, begin game
  • CODE_GAME_READY — Mark player ready
  • CODE_GAME_MOVE — Validate move, apply to board, broadcast, check win, run AI
  • CODE_GAME_RESET — Reset board for rematch
  • CODE_GAME_WATCH / CODE_GAME_WATCH_EXIT — Spectator join/exit
  • CODE_CLIENT_EXIT / CODE_CLIENT_OFFLINE — Cleanup disconnection

Network Handlers:

  • ProtobufTransferHandler — TCP/Protobuf codec, encodes/decodes binary messages
  • WebsocketTransferHandler — WebSocket JSON codec
  • StaticFileHandler — HTTP file serving (index.html, CSS, JS, etc.)
    • Maps GET /static/index.html
    • Rejects path traversal (..)
    • Supports MIME types: html, css, js, json, mp3, png, jpg, svg, ico
    • Passes /ratel requests to WebSocket handler

Message Proxies:

  • ProtobufProxy — Send binary message to TCP client
  • WebsocketProxy — Send JSON message to WebSocket client
  • Proxy (abstract) — Base interface

Global State:

  • ServerContains.java — Singleton holding all rooms, active connections
    • Methods: addRoom(), removeRoom(), getRoomList(), findRoom(id)

Background Tasks:

  • RoomClearTask — Periodic cleanup (remove finished rooms after timeout)

landlords-client (Java CLI Client)

Entry Point:

  • SimpleClient.java — Bootstrap
    • Parses args: -h {host} -p {port} -ptl {protocol} -lang {language}
    • Connects via TCP/Protobuf or WebSocket
    • Reads moves from stdin (row,col or exit)

Event Handlers (ClientEventListener_*):

  • CODE_CLIENT_CONNECT — Connection successful, display lobby menu
  • CODE_SHOW_ROOMS — Display room list
  • CODE_ROOM_CREATE_SUCCESS / CODE_ROOM_JOIN_SUCCESS — Enter waiting room
  • CODE_GAME_STARTING — Display board, wait for moves
  • CODE_GAME_MOVE_SUCCESS — Update local board display
  • CODE_GAME_MOVE_INVALID / CODE_GAME_MOVE_OCCUPIED / etc. — Show error
  • CODE_GAME_WIN / CODE_GAME_LOSE / CODE_GAME_DRAW — Game over
  • CODE_CLIENT_KICK — Disconnected by server

Protocol Handlers:

  • ProtobufTransferHandler — TCP codec
  • WebsocketTransferHandler — WebSocket codec
  • Same proxy pattern as server

Web Client (JavaScript/Phaser 3)

Boot:

  • main.js — Create Phaser game instance, start boot scene

Config:

  • game-config.js — Phaser config object

    • Resolution: 800x800
    • Scale mode: Scale.FIT (responsive)
    • Physics: Enabled (for animations)
    • Scene list: [BootScene, MenuScene, GameScene]
  • protocol-constants.js — Export event code enums

    • Maps ServerEventCode and ClientEventCode names to numbers

Scenes (Phaser.Scene subclasses):

  • BootScene — Initialization

    • Create event bus and services
    • Connect to server (WebSocket)
    • Load assets (images, audio)
    • Transition to menu on connect
  • MenuScene — DOM overlay menus

    • Nickname input form
    • Lobby with room list and create room button
    • Difficulty selector (for PVE)
    • Settings menu
  • GameScene — Main gameplay

    • Render board and stones
    • Handle mouse clicks (place stones)
    • Display move history panel
    • Show turn indicator (whose turn?)
    • Display game over message
    • Handle rematch/exit options
    • Listen to WebSocket events (opponent moves, AI moves)

Services (Singleton-like, event-driven):

  • EventBus.js — Simple pub/sub

    • emit(event, data)
    • on(event, callback)
    • Decouples scenes and services
  • ConnectionService.js — WebSocket client

    • connect(url) → returns Promise
    • Maintains ws connection
    • Heartbeat every 30 seconds (send CODE_CLIENT_HEAD_BEAT)
    • Auto-reconnect on close (exponential backoff)
    • send(code, data) — send message to server
  • GameStateService.js — Client-side state container

    • room object (id, players, board, status)
    • nickname string
    • board (15x15 array, mirrored from server)
    • Methods: update(), reset(), addMove()
    • Notify listeners on state change

Game Objects (Phaser.GameObjects.*):

  • Board.js — Game board renderer

    • Create 15x15 grid of cells
    • Wood texture background
    • Cell dimensions: ~50x50 pixels
    • placeStone(row, col, color) method
    • Hover effect (highlight hovered cell)
  • Stone.js — Individual stone sprite

    • Phaser.GameObjects.Sprite subclass
    • Gradient fill (black or white)
    • Drop animation (tweens)
    • Glow effect on hover

UI Components (DOM + Phaser):

  • MenuUI.js — Menu rendering

    • Nickname input, validation
    • Room creation form (PVP/PVE selector, AI difficulty)
    • Room list (with join buttons)
    • Settings panel
  • GameUI.js — Game HUD

    • Move history panel (list of moves: 7,7 Black, 8,8 White, etc.)
    • Turn indicator (waiting for opponent / your turn)
    • Game over modal (winner announcement, rematch button)
    • Toast notifications (connection lost, reconnected, etc.)

Build Configuration

Maven (Java)

File: pom.xml

Parent: Spring Boot 2.0.5.RELEASE

Key Plugins:

  • maven-compiler-plugin — Java 8 source/target
  • maven-surefire-plugin — Run unit tests
  • maven-source-plugin — Generate source JAR
  • maven-javadoc-plugin — Generate docs

Dependencies:

  • Netty (async networking)
  • Protobuf 3.25.5 (binary serialization)
  • Gson (JSON parsing)
  • JUnit (testing)

Modules:

  • landlords-common (library)
  • landlords-server (executable JAR)
  • landlords-client (executable JAR)

Build Command:

mvn clean package -DskipTests
# Produces:
#   landlords-server/target/landlords-server-1.4.0.jar
#   landlords-client/target/landlords-client-1.4.0.jar

Vite (JavaScript)

File: web-client/package.json

Scripts:

  • npm run dev — Start dev server (port 5173, hot reload)
  • npm run build — Production build to dist/
  • npm run preview — Preview production build

Dependencies:

  • phaser ^3.87.0 — Game engine
  • vite ^6.3.1 — Bundler

Output: web-client/dist/ (index.html + bundled JS)


Testing

Test Framework: JUnit 4

Test Files:

  1. GomokuHelperTest.java (landlords-common)

    • 37+ test cases for win detection
    • Tests all 4 directions (horizontal, vertical, 2 diagonals)
    • Tests edge cases (board edges, corners)
    • Tests draw condition (full board)
  2. GomokuAITest.java (landlords-common)

    • Tests Easy AI (random valid moves)
    • Tests Medium AI (finds winning move, blocks opponent)
    • Tests Hard AI (minimax scoring)
    • Tests move validity after AI selection

Run Tests:

mvn clean test
# or
mvn test -DskipTests=false

Coverage: ~100% for game logic (Board, GomokuHelper, GomokuAI)


Dependencies Summary

Module Dependencies
landlords-common Netty, Protobuf, Gson, JUnit
landlords-server landlords-common, Netty, Protobuf
landlords-client landlords-common, Netty, Protobuf
web-client Phaser 3, Vite (dev-only)

Important Files by Feature

Game Logic

  • landlords-common/src/main/java/.../entity/Board.java — Board state
  • landlords-common/src/main/java/.../helper/GomokuHelper.java — Win detection
  • landlords-common/src/main/java/.../robot/GomokuAI.java — AI engine

Networking

  • landlords-server/src/main/.../handler/StaticFileHandler.java — HTTP file serving
  • landlords-server/src/main/.../handler/WebsocketTransferHandler.java — WS codec
  • landlords-server/src/main/.../handler/ProtobufTransferHandler.java — TCP codec
  • web-client/src/services/connection-service.js — WebSocket client

Game Flow

  • landlords-server/src/main/.../event/ServerEventListener_CODE_GAME_MOVE.java — Move processing
  • landlords-server/src/main/.../event/ServerEventListener_CODE_GAME_STARTING.java — Game start
  • web-client/src/scenes/game-scene.js — Game rendering & input

UI

  • web-client/src/objects/board.js — Board renderer
  • web-client/src/ui/game-ui.js — HUD & notifications
  • web-client/src/ui/menu-ui.js — Menus & forms

Code Quality

Metrics:

  • Lines of Code: ~5,000 Java, ~1,500 JavaScript
  • Test Coverage: Game logic 100%, server 80%+, client varies
  • File Size: Most Java files < 200 lines, JavaScript < 300 lines
  • Linting: No major violations (follow code-standards.md)

Documentation:

  • Javadoc on public methods (Java)
  • JSDoc on exported functions (JavaScript)
  • Inline comments for complex logic

Build Artifacts

Artifact Location Purpose
Server JAR landlords-server/target/landlords-server-1.4.0.jar Executable server
Client JAR landlords-client/target/landlords-client-1.4.0.jar Executable CLI client
Web dist web-client/dist/ Static files for web UI
Source JAR landlords-*/target/*-sources.jar Source code archive

Continuous Integration

GitHub Actions:

  1. Build.yml

    • Trigger: Push to any branch
    • Steps:
      • Checkout code
      • Setup Java 8
      • Run mvn clean test
      • Run npm install && npm run build (web-client)
  2. deploy-pages.yml

    • Trigger: Push to master
    • Steps:
      • Build web-client
      • Deploy to GitHub Pages (https://tiennm99.github.io/caro/)

Version & Release

Current Version: 1.4.0

Release Process:

  1. Tag commit: git tag v1.4.0
  2. Push tag: git push origin v1.4.0
  3. Create GitHub Release with JAR artifacts
  4. Auto-deploy web-client to Pages

Versioning: Semantic versioning (MAJOR.MINOR.PATCH)