351 Commits
Author SHA1 Message Date
tiennm99 d5ad56023c chore: remove stale subagent reports
Both reports belonged to shipped work:
- docs-manager-260410-1344: docs sweep, superseded by docs/ updates in cbad690
- researcher-260410-2132: pre-2026 version audit, superseded by the pinned
  deps in server/build.gradle.kts and client/package.json
2026-04-11 10:01:29 +07:00
tiennm99 d5c1318a0f chore: remove shipped plans
All 5 plans implemented and merged. Deleting to keep the plans/ directory
focused on active work:
- 260409-1701-caro-simplification (shipped d871cc2)
- 260409-1812-web-gomoku-client (shipped 77e141c, later replaced by Phaser)
- 260410-0913-phaser-web-client (shipped 22bb9c1)
- 260410-1843-refactor-project-structure (shipped c71aa6a/5b68ee9/2d74117/1297b7d)
- 260410-2101-websocket-protobuf-migration (shipped 945a249 through 42d94a2)

plans/reports/ kept for historical cross-plan reports.
2026-04-11 10:00:12 +07:00
tiennm99 42d94a2aed fix: wire up spectator mode end-to-end
Watch feature was half-implemented since day one and stayed broken through
the typed-protobuf migration:

1. Server (WatchGameHandler): only pushed the WatchGameSuccessResponse ack.
   A mid-game watcher joined a blank scene because the server never told
   them who the players were or what moves had been played.
2. Client: had a Watch button that sent the request but no event bus
   handler for GAME_WATCH_SUCCESSFUL, so nothing happened visually.

Server fix:
- On successful watch, if room.status == STARTING, bootstrap the watcher
  with a synthesised GameStartingResponse (player ids, nicknames, board
  size) and replay every move in room.getMoveHistory() as individual
  GameMoveSuccessResponse messages on that channel.
- Black/white player lookup uses room.getBlackPlayerId/getWhitePlayerId
  against the clientSideMap so we don't reassign roles.
- Move replay resolves playerNickname from the same map.

Client fix:
- menu-ui.js: new GAME_WATCH_SUCCESSFUL handler flips gameState.isSpectating
  = true. The subsequent GameStartingResponse flows through the existing
  menu-scene handler (transitions to GameScene) and the existing
  game-state-service handler (populates room state, resets moves).
- Move replay events propagate through the global GAME_MOVE_SUCCESS handler
  in game-state-service before GameScene.create() runs, so GameScene's
  existing rejoin/spectate loop at create() renders every stone.
2026-04-11 09:22:54 +07:00
tiennm99 cea36323c9 fix(client): unwrap rooms array from ShowRoomsResponse payload
After the typed-protobuf migration the event bus delivers the full
ShowRoomsResponse message to the handler — a {rooms: [...]} object, not
the raw array the old JSON envelope used to unwrap. showRoomList was
still doing `Array.isArray(rooms) ? rooms : []`, so the guard always
failed and the UI rendered "No rooms available" even when rooms existed
server-side.

Repro: create a PVP room from tab A, open Join Room from tab B — empty list.

Fix: read payload.rooms (defensively default to [] so the empty-state row
still shows when protobufjs strips the empty repeated field).
2026-04-11 09:07:35 +07:00
tiennm99 f70c0eaa5f fix(client): drop stale COPY public in Dockerfile
docker build failed with "/public: not found" at the client stage. The
client tree has never contained a public/ directory (vite doesn't need one
for this project — index.html lives at the client root and vite.config.js
has no publicDir override). Remove the dead COPY line.

Verified: docker build -f client/Dockerfile client succeeds end-to-end.
2026-04-11 08:53:35 +07:00
tiennm99 35fb8cf2ef ci: fix gradlew path and permissions for Build Server job
Last Build & Test run failed with exit 127 "./gradlew: No such file or
directory". After the Maven-to-Gradle conversion the wrapper lives at
server/gradlew, not at the repo root. Two fixes:

1. Workflow invokes server/gradlew directly instead of ./gradlew.
2. Mark server/gradlew as executable (mode 100755) in the git index so the
   Linux runner can exec it without a chmod step.
2026-04-11 08:39:13 +07:00
tiennm99 4bacae555d docs: mark websocket protobuf migration phases 01-05 as shipped 2026-04-11 08:34:24 +07:00
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
tiennm99 ecc617790e refactor(client): typed protobuf binary websocket on port 1999
Phase 04 of the WebSocket protobuf migration:
- Add protobufjs@7.5.4 runtime dep and protobufjs-cli@1.1.3 devDep
- Add proto:gen npm script that runs pbjs + pbts against server/src/main/proto/
- Commit static-module output at client/src/generated/protocol.{js,d.ts}
- Rewrite connection-service.js:
  * Set binaryType='arraybuffer' and default URL to ws://localhost:1999/ratel
  * Replace string-keyed send(code, data) with 13 typed send helpers
    (sendNickname, sendGameMove, sendCreatePveRoom, ...)
  * Decode incoming BinaryWebSocketFrame via Response.decode and map
    each oneof case to a ClientEventCode for the event bus
- Update 14 call sites across menu-ui, game-ui, game-scene
- game-state-service CLIENT_CONNECT now reads data.clientId
- menu-ui NICKNAME_SET toast only triggers when invalidLength > 0
- Drop ServerEventCode enum from protocol-constants.js
2026-04-11 08:25:20 +07:00
tiennm99 3ad9a7b9d1 refactor(server): drop gson and dead json/map/tcp helpers
Phase 03 cleanup — now that typed records replace JSON envelopes and inner
JSON payloads, remove the helpers that served them:
- delete common/entity/Msg.java (envelope record)
- delete common/utils/JsonUtils.java (gson wrapper)
- delete common/helper/MapHelper.java (JSON dict builder)
- delete common/helper/TimeHelper.java (orphaned)
- delete common/transfer/{ByteKit,ByteLink,TransferProtocolUtils}.java (TCP framing)
- delete common/handler/DefaultDecoder.java (TCP framing)
- delete common/enums/ServerEventCode.java (string keys for reflection dispatch)
- delete common/enums/ClientEventCode.java (no longer referenced after proto migration)
- drop com.google.code.gson:gson from build.gradle.kts

All 37 unit tests still pass.
2026-04-11 08:15:39 +07:00
tiennm99 b75733fd2d refactor(server): migrate event handlers to typed records
Replace every UnsupportedOperationException stub in RequestDispatcher with a
real handler call. All 15 handlers now live under com.miti99.caro.server.event.handler
and take a typed ClientRequest record, emitting typed Response protos via
ChannelUtils.push.

Handlers ported:
- SetClientInfoHandler, SetNicknameHandler
- CreateRoomHandler, CreatePveRoomHandler, GetRoomsHandler, JoinRoomHandler
- GameStartingHandler, GameReadyHandler
- GameMoveHandler (full PVP + PVE AI + game-over broadcast)
- GameResetHandler (noop, never wired before)
- WatchGameHandler, WatchGameExitHandler
- ClientExitHandler, ClientOfflineHandler

WebsocketTransferHandler.clientOfflineEvent now dispatches to ClientOfflineHandler.
RoomClearTask reuses ClientExitHandler for stale-room cleanup.

All 37 unit tests pass.
2026-04-11 08:14:52 +07:00
tiennm99 945a249b89 refactor(server): typed protobuf wire + sealed record dispatcher scaffolding
Phase 01+02a of the WebSocket protobuf migration:
- Add request.proto / response.proto with typed oneofs (14 request + 20 response variants)
- Wire com.google.protobuf Gradle plugin v0.9.6 (protoc 3.25.5)
- Drop TCP stack: ProtobufProxy, Proxy, ProtobufTransferHandler, SecondProtobufCodec
- Delete old envelope types ClientTransferData, ServerTransferData
- Delete reflection-based ServerEventListener + 13 ServerEventListener_CODE_* classes
- Create sealed ClientRequest interface + 14 record variants
- Create RequestConverter (wire -> record) and RequestDispatcher (record -> handler)
- Rewrite ChannelUtils.push(Channel, Response) for BinaryWebSocketFrame
- Rewrite WebsocketTransferHandler for BinaryWebSocketFrame + typed dispatch
- Flip default port 1024 -> 1999; SimpleServer starts only WebsocketProxy
- Move RoomClearTask scheduling into WebsocketProxy.start()
- Bump netty 4.1.115.Final -> 4.1.128.Final, junit-bom 5.11.3 -> 5.11.4, shadow 8.3.5 -> 8.3.8
- Heartbeat handled as no-op in dispatcher; all other cases throw until phase 02b

Phase 02b will port the 14 business-logic handlers and wire the dispatcher.
2026-04-11 08:10:16 +07:00
tiennm99 687cab7863 docs: plan WebSocket typed-protobuf migration
7-phase plan to drop TCP, replace JSON envelope with typed protobuf
Request/Response oneofs on single port 1999, and dispatch via Java
sealed records. Includes pre-2026 dep version audit (netty, junit,
shadow, protobufjs).
2026-04-10 21:38:20 +07:00
tiennm99 45e22124ac chore: bump version to 0.0.1 and replace "frontend" with "client"
Version change:
- Drop the "-beta" suffix across all version declarations.
- server/build.gradle.kts: version = "0.0.1"
- client/package.json: "version": "0.0.1"
- client/package-lock.json: regenerated
- server/Dockerfile: COPY path references the new jar filename
- All docs + README refer to caro-server-0.0.1.jar.

Terminology cleanup:
- Replace the word "frontend" with "client" so the whole project uses
  one consistent term (server / client).
- README.md Credits section: "Frontend build tool" -> "Client build tool".
- No other "frontend" occurrences found in code or docs.

Also correct two lingering Maven-era stale paths in deployment-guide.md
("server/target/..." -> Gradle output location) that slipped past the
earlier Maven-to-Gradle commit.

Versioning note in codebase-summary.md simplified to plain MAJOR.MINOR.PATCH
(dropped the "-beta suffix during pre-1.0" clause).

Validation: gradlew clean shadowJar + test passes (37 tests on Java 25);
client build succeeds with new package name/version.
2026-04-10 20:55:29 +07:00
tiennm99 b7ff184387 refactor: convert server from Maven to Gradle
Replace server/pom.xml with Gradle 9.2.1 (Kotlin DSL) + Shadow plugin
for fat jar packaging.

New files:
- server/build.gradle.kts   (Kotlin DSL script)
- server/settings.gradle.kts
- server/gradle/wrapper/    (committed wrapper, pinned to 9.2.1)
- server/gradlew, gradlew.bat

Deleted:
- server/pom.xml

Gradle config:
- plugins: java, com.gradleup.shadow 8.3.5
- toolchain: JavaLanguageVersion.of(25) (auto-provisions if missing)
- deps: netty-all 4.1.115.Final, protobuf-java 3.25.5, gson 2.11.0,
  junit-bom 5.11.3 + junit-jupiter (test)
- compiler: -parameters, UTF-8
- test: useJUnitPlatform()
- shadowJar: main class com.miti99.caro.server.SimpleServer,
  mergeServiceFiles(), append META-INF/io.netty.versions.properties
- default assembly depends on shadowJar

Output path migration:
- server/target/caro-server-0.0.1-beta.jar moves under Gradle output conventions.

Infrastructure:
- server/Dockerfile: eclipse-temurin:25-jdk + committed wrapper
  (no Maven image); runtime stage unchanged. COPY order optimized.
- .github/workflows/build.yml: setup-java temurin 25 +
  gradle/actions/setup-gradle, run gradlew with -p server.
- .gitignore: add .gradle/, whitelist wrapper jar after *.jar rule.

Docs + README fully updated to Gradle commands across:
README.md, codebase-summary.md, code-standards.md, deployment-guide.md,
project-overview.md, system-architecture.md.

Validation: gradlew clean assemble check passes all 37 tests on Java 25.
2026-04-10 20:50:53 +07:00
tiennm99 1f7133526f docs: rename project-overview-pdr.md to project-overview.md
The PDR suffix was unclear (Product Design Requirements). Plain
project-overview.md matches the file's contents better and aligns
with the naming of the other docs.

Also update the directory tree in codebase-summary.md.
2026-04-10 20:04:26 +07:00
tiennm99 5b2c3dd0e8 docs: remove roadmap and sync remaining docs with current project state
- Delete docs/project-roadmap.md (no longer maintained).
- project-overview-pdr.md: drop Roadmap & Status table; tweak PVP
  feature description (remove non-existent chat); update Success
  Criteria to reference CI instead of CI/CD with deploy.
- codebase-summary.md: drop project-roadmap.md from directory tree.
- system-architecture.md: simplify static handler note to describe
  current pipeline state instead of refactor history.
2026-04-10 20:01:54 +07:00
tiennm99 4feee3b858 chore: remove deploy-pages workflow and cleanup unused files
- Remove .github/workflows/deploy-pages.yml. Docker Compose is now the
  canonical deployment path.
- Delete unreferenced demo.gif (tracked, no markdown references).
- Delete stale landlords-client/ leftover from pre-refactor Maven cache.
- Delete empty client/public/ directory.
- Drop demo.gif entry from .dockerignore.
- Clean up .gitignore: dedupe target/.project/.classpath/.settings/.DS_Store
  entries, remove stale /ratel-landlords/.project line, group by purpose.
- Bump client/README.md Node.js requirement 18+ to 22+ (aligns with CI).
- Update docs to drop GitHub Pages references:
  - codebase-summary.md: drop deploy-pages.yml from tree and CI section.
  - deployment-guide.md: replace Option A (GH Pages) with Docker Compose.
  - project-overview-pdr.md: Phase 4 no longer mentions GH Pages.
  - project-roadmap.md: Phase 6 describes CI-only, notes deploy-pages
    removal; Phase 7 entry lists cleanup items; maintenance schedule
    now says rebuild Docker images.
  - system-architecture.md: deployment diagram shows Docker Compose only.

Validation: mvn -f server/pom.xml clean verify passes 37 tests on Java 25.
2026-04-10 19:48:19 +07:00
tiennm99 a69fccbaf0 docs: sweep all docs + README for post-refactor state
Update root README + all 6 docs in ./docs/ to reflect the completed
monorepo refactor (server/ + client/, Java 25, gson, JUnit 5,
com.miti99.caro.{common,server}.*, caro-server 0.0.1-beta).

- README.md: quickstart commands, project structure, architecture
  diagram; drop CLI + built-in web UI sections. Credits preserved
  verbatim (Ratel/ainilili historical attribution).
- docs/codebase-summary.md: full rewrite — new directory tree,
  package layout, build config, CI, version.
- docs/code-standards.md: package prefix (com.miti99.caro), Java 25
  tools, modernization guidelines (records, var, switch expressions),
  JUnit 5.
- docs/deployment-guide.md: full rewrite — Java 25 prereqs,
  docker-compose path, standalone jar commands, nginx reverse proxy
  updated, JUnit 5 test output, zero-downtime update flow.
- docs/project-overview-pdr.md: tech stack (Java 25 + gson + JUnit 5
  + shade), features matrix (no CLI/built-in UI), architecture
  diagram, deps table, version history, quick start commands.
- docs/project-roadmap.md: add Phase 7 (2026-04-10 refactor) with
  full change list; mark Phase 4 built-in UI as removed; update
  version history with 0.0.1-beta; Decision 1 updated to Java 25.
- docs/system-architecture.md: full rewrite — Netty pipeline without
  StaticFileHandler, new package layout, single-module dependency
  graph, gson on WebSocket, Msg as record, deployment diagram with
  docker-compose services, proto files staged for future use.

Grep verification: all remaining mentions of legacy names
(landlords-, org.nico.ratel, StaticFileHandler, I18nHelper, noson,
1.4.0) appear only in:
  - the Phase 7 refactor description in project-roadmap.md
    (intentional historical context)
  - protoc-generated ClientTransferData.java / ServerTransferData.java
    internal variable names and embedded descriptor byte strings
    (public Java package is correct; preserving wire format)
2026-04-10 19:33:00 +07:00
tiennm99 1297b7d25a refactor: rename web-client/ to client/ and update compose + CI references
- git mv web-client/ -> client/ (internal files untouched, history preserved).
- docker-compose.yml: rename service web-client -> client, container
  caro-web-client -> caro-client, build context ./web-client -> ./client.
- .github/workflows/build.yml: rename job build-web-client -> build-client,
  working-directory web-client -> client, cache-dependency-path updated.
- .github/workflows/deploy-pages.yml: update paths filter, working-directory,
  cache-dependency-path, upload-pages-artifact path (web-client/** -> client/**),
  workflow display name.
- client/package.json: rename npm package caro-web-client -> caro-client,
  version 1.0.0 -> 0.0.1-beta to align with server artifact.
- Regenerate package-lock.json with new name/version.
- .gitignore: web-client/dist -> client/dist.

Validation: npm run build in client/ succeeds (20 modules transformed).
2026-04-10 19:22:39 +07:00
tiennm99 a5aa3606cd refactor(java25): convert Msg to record, use switch expressions + var
Modernization (opportunistic, low-risk only):
- Convert Msg (WebSocket JSON envelope) from mutable POJO to record.
  Gson 2.11 natively supports record serialization via canonical
  constructor + accessor methods, so wire format is preserved
  (null components still skipped by default). Update both producers
  (ChannelUtils) and consumer (WebsocketTransferHandler).
- Convert 3 switch statements to switch expressions:
  GomokuHelper.getWinnerMessage (GameResult -> String, exhaustive),
  GomokuHelper board-cell rendering (PieceType -> char),
  GomokuAI.getNextMove (difficulty -> strategy),
  ServerEventListener_CODE_ROOM_CREATE_PVE.getDifficultyName.
- Sprinkle var for obvious local types in ChannelUtils and
  WebsocketTransferHandler where RHS type is self-evident.

Non-goals preserved: no Netty handler rewrites, no threading changes,
no sealed types, no pattern matching in switches.

Validation: mvn verify on Java 25 — all 37 tests pass.
2026-04-10 19:17:02 +07:00
tiennm99 2d74117fe2 refactor: rename packages org.nico.ratel.landlords -> com.miti99.caro.{common,server}
- Move all 11 shared sub-packages (channel, entity, enums, exception,
  features, handler, helper, print, robot, transfer, utils) under
  com.miti99.caro.common.
- Move server sub-packages (event, handler, proxy, timer) + SimpleServer
  + ServerContains under com.miti99.caro.server.
- Move tests under com.miti99.caro.common.{helper,robot}.tests.
- Rewrite package declarations and imports across all 58 .java files via
  regex script (server rules applied before common to avoid overlap).
- Update <mainClass> in server/pom.xml to com.miti99.caro.server.SimpleServer.
- Update .proto files' package + java_package to com.miti99.caro.common.entity
  (for future regeneration).
- Fix generate.sh relative output path (common/ no longer exists).
- Include rewrite-packages.py script under plans/ for auditability.

Note: protoc-generated ClientTransferData.java / ServerTransferData.java
retain internal_static_* variable names and embedded descriptor byte strings
with the old package — these are implementation details that do not affect
the public Java package and preserve protobuf wire compatibility.

Validation: mvn -f server/pom.xml clean verify on Java 25 — all 37 tests
pass (29 GomokuHelperTest + 8 GomokuAITest).
2026-04-10 19:14:02 +07:00
tiennm99 5b68ee9cc4 refactor: standalone maven, java 25, shade, gson, junit 5, rename to server/
Build system modernization:
- Delete root parent pom.xml; server/pom.xml is now standalone.
- Drop Spring Boot parent; use maven-shade-plugin 3.6.0 for fat jar.
- Upgrade source/target to Java 25 (LTS); pin explicit dep versions:
    netty-all 4.1.115.Final, protobuf-java 3.25.5, gson 2.11.0,
    junit-jupiter 5.11.3, maven-compiler-plugin 3.13.0,
    maven-surefire-plugin 3.5.2, maven-shade-plugin 3.6.0.
- New coordinates: com.miti99.caro:caro-server:0.0.1-beta.
- Shade transformers: manifest (main class), services, appending
  (Netty io.netty.versions.properties merge).

Dependency migration:
- Replace com.smallnico:noson with gson across 5 files (7 call sites):
    MapHelper, TransferProtocolUtils, ServerEventListener_CODE_GAME_WATCH,
    ServerEventListener_CODE_GET_ROOMS, ServerEventListener_CODE_ROOM_CREATE.
  All call sites now funnel through existing JsonUtils wrapper (DRY).
- Migrate GomokuHelperTest + GomokuAITest from JUnit 4 to JUnit 5
  (org.junit.Test -> org.junit.jupiter.api.Test,
   org.junit.Assert.* -> org.junit.jupiter.api.Assertions.*).

Directory + infra:
- git mv landlords-server/ -> server/.
- Rewrite server/Dockerfile: Java 25 base images
  (maven:3.9-eclipse-temurin-25 build, eclipse-temurin:25-jre-alpine runtime),
  simplified COPY paths (no more multi-module layout).
- docker-compose.yml: dockerfile points to server/Dockerfile.
- .github/workflows/build.yml: setup-java temurin 25,
  `mvn -f server/pom.xml -B clean verify`.

Validation: mvn verify on Java 25 passes all 37 tests (29 GomokuHelper
+ 8 GomokuAI), shade produces caro-server-0.0.1-beta.jar cleanly.

Note: package names remain org.nico.ratel.landlords.* in this phase;
renamed to com.miti99.caro.{common,server}.* in Phase 4.
2026-04-10 19:10:51 +07:00
tiennm99 c71aa6a160 refactor: consolidate landlords-common into landlords-server
- Move all 11 common sub-packages (channel, entity, enums, exception,
  features, handler, helper, print, robot, transfer, utils) into
  landlords-server/src/main/java with git mv (history preserved).
- Move common test sources (helper, robot) into landlords-server/src/test.
- Move protoc-resource (.proto files + generate.sh) into
  landlords-server/src/main/resources/proto/ for future proto-over-WS use.
- Delete landlords-common/ and protoc-resource/ dirs.
- Drop landlords-common module from root pom.xml.
- Drop landlords-common dependency from landlords-server/pom.xml.
- Simplify Dockerfile COPY lines (only server/ remains).
2026-04-10 19:03:26 +07:00
tiennm99 0b686ef0a5 refactor: delete CLI client, i18n helper, and legacy static web UI
- Remove landlords-client module (CLI client, superseded by web-client).
- Remove I18nHelper + messages_en_US.properties (only used by CLI).
- Remove SimplePrinter.printTranslate() (zero callers after CLI removal).
- Remove StaticFileHandler + static/ resources (legacy built-in web UI).
- Remove StaticFileHandler from WebsocketProxy pipeline + import.
- Drop landlords-client module from parent pom.xml.
- Drop landlords-client COPY lines from server Dockerfile.
2026-04-10 19:00:29 +07:00
tiennm99 705abcd698 docs(plans): add refactor plan to consolidate monorepo structure
6-phase serial plan: remove CLI client + static UI, merge common into
server, collapse to standalone Maven (Java 25, shade, gson, JUnit 5),
rename to com.miti99.caro.{common,server}, rename web-client to client.
2026-04-10 18:56:05 +07:00
tiennm99 ac4bb07d65 docs: reflect Docker Compose setup, GAME_OVER payload, build.yml rename 2026-04-10 18:21:14 +07:00
tiennm99 c3cd3c0f94 fix(server): drop formatted board from GAME_OVER payload to keep JSON parseable 2026-04-10 18:16:28 +07:00
tiennm99 f6b94a6af4 chore: untrack .claude/settings.local.json and add to gitignore 2026-04-10 18:07:57 +07:00
tiennm99 f66a68b590 fix(web-client): surface nickname rejection and stop scene restart loop 2026-04-10 18:03:56 +07:00
tiennm99 3615310335 fix(web-client): determine win/lose by result+piece, align nickname length to server 2026-04-10 18:02:20 +07:00
tiennm99 760ec9cb5e fix(web-client): eliminate hover preview flicker on micro mouse movement 2026-04-10 17:55:55 +07:00
tiennm99 15a88373be fix(web-client): restore canvas clicks by excluding .game-hud from overlay pointer-events 2026-04-10 17:42:12 +07:00
tiennm99 cdddbc4d4f feat: add Docker Compose setup for server and web client 2026-04-10 17:34:53 +07:00
tiennm99 58820fbb9f ci: rename Build.yml to build.yml for naming consistency 2026-04-10 17:23:55 +07:00
tiennm99 c8c2c1f896 docs: add docs-manager completion report, gitignore repomix output 2026-04-10 13:38:43 +07:00
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
tiennm99 e8c08139db ci: modernize GitHub Actions, add Pages deployment
- Replace outdated Build.yml (v2 actions, JDK 1.8, 3-OS matrix)
  with modern workflow (v4 actions, JDK 21, single ubuntu runner)
- Add separate web client build job
- Add deploy-pages.yml for auto-deploying web-client to GitHub Pages
  on push to master (web-client/** changes only)
- Set Vite base path to /caro/ for GitHub Pages compatibility
2026-04-10 10:29:36 +07:00
tiennm99 4bad51314d docs: comprehensive README with setup, architecture, and credits
- Full project README: quick start, game rules, project structure,
  server/client architecture diagrams, CLI/web options, protocol docs
- Web client README: setup, scripts, tech stack
- Credit to ainilili/ratel original project
2026-04-10 10:15:53 +07:00
tiennm99 22bb9c1371 feat: add Phaser 3 web client with Vite scaffold
Separate web-client/ directory with Phaser 3 + Vite + vanilla JS:
- Services: event bus, WebSocket connection (heartbeat, reconnect),
  game state, protocol constants matching server enums
- Scenes: BootScene (connect), MenuScene (DOM overlay), GameScene
  (canvas board with grid, stones, hover, click-to-move, animations)
- Objects: Board (wood grid, star points, labels), Stone (gradient
  circles with drop tween animation)
- UI: DOM overlays for nickname, lobby, PVP/PVE menus, room list,
  waiting room, game HUD, game over, toast notifications
- Audio: Web Audio API stone click + win/lose tones
- Full game flow: nickname → lobby → create/join/PVE → play → game over
2026-04-10 09:46:06 +07:00
tiennm99 cb0761bedd plan: Phaser 3 web client - 6 phases, separate deployment
Standalone Phaser 3 + Vite + vanilla JS (JSDoc) Gomoku web client.
Connects to existing server via WebSocket. DOM overlays for menus,
Canvas for board. 6 phases, ~12h effort.
2026-04-10 09:34:45 +07:00
tiennm99 77e141c017 feat: add professional web 2D Gomoku client
- Add StaticFileHandler to serve static files from Netty WS server
- Create single-page HTML with 8 screens (nickname, lobby, PVP/PVE
  menus, room list, waiting room, game, game over)
- Dark theme CSS with responsive layout and animations
- WebSocket connection with heartbeat and auto-reconnect toast
- Event bus state machine for screen transitions
- Canvas board: wood texture, grid, gradient stones, hover preview,
  last-move indicator, placement animation (easeOutBack)
- Full lobby: create/join rooms, room list, spectator mode
- Move history panel with coordinate display
- Game over with personalized win/lose/draw result
- Web Audio API sound effects (no external files needed)
- Toast notification system for errors
2026-04-10 09:03:37 +07:00
tiennm99 c8a933a786 plan: web 2D Gomoku client - 7 phases, served from Netty server
Professional vanilla JS/Canvas game client with lobby, PVP/PVE,
spectator mode, animations, and audio. No build tools required.
2026-04-10 08:37:31 +07:00
tiennm99 c2573fe31b test: add comprehensive Gomoku tests, fix redundant win check
- Fix Board.checkWin: remove redundant duplicate direction checks
- Expand GomokuHelperTest: 29 tests covering win detection (all 4 axes,
  edges, middle-piece, overline), move validation, turn management,
  game flow, utilities, and reset
- Add GomokuAITest: 8 tests covering all difficulties, win-taking,
  opponent-blocking, empty board, and fallback behavior
2026-04-09 18:04:31 +07:00
tiennm99 aaafb9509a fix: upgrade maven-surefire-plugin to 3.2.5 for JDK 21 compat 2026-04-09 17:38:03 +07:00
tiennm99 b2e489f16a refactor: final cleanup - remove dead code, fix broken refs, update README
- Remove unused currentPlayer field from Room
- Remove unused RobotEventListener interface
- Remove RobotDecisionMakers.init() calls from proxy classes
- Delete dead RegxUtils class
- Fix poker javadoc in TransferProtocolUtils
- Remove Chinese date in TimeHelper
- Update README for Gomoku project
2026-04-09 17:30:11 +07:00
tiennm99 8ed528fce6 feat(client): rewrite event handlers for Gomoku game flow
- Rewrite GAME_STARTING to display board info and prompt moves
- Rewrite GAME_OVER for Gomoku win/draw display
- Create 5 new move handlers (success, invalid, occupied, OOB, not turn)
- Rewrite GAME_WATCH for Gomoku spectator mode
- Simplify SimpleClient (remove remote server list fetching)
- Simplify settings handler (remove poker display format)
- Remove all Chinese comments from client code
2026-04-09 17:27:56 +07:00
tiennm99 13ee8ea7f3 feat(server): rewrite event handlers for Gomoku game flow
- Create ServerEventListener_CODE_GAME_MOVE with move validation,
  win detection, and inline AI response for PVE
- Rewrite GAME_STARTING for 2-player Gomoku (black/white assignment)
- Rewrite ROOM_JOIN to auto-start at 2 players
- Rewrite ROOM_CREATE_PVE for single AI opponent
- Simplify RoomClearTask (remove robot substitution logic)
- Fix ClientRole.PLAYER references in handlers
- Replace Chinese comments with English
2026-04-09 17:25:56 +07:00
tiennm99 640fce79e8 refactor: clean shared code - remove poker/score/landlord fields
- Delete ClientType enum (LANDLORD/PEASANT)
- Remove score, scoreRate, baseScore from Room
- Remove score, scoreInc, type, next, pre, round from ClientSide
- Simplify ClientRole to BLACK_PLAYER, WHITE_PLAYER, SPECTATOR
- Remove CALL_LANDLORD from ClientStatus
- Strip poker imports from SimplePrinter and ClientEventListener
- Remove initLastSellInfo() calls from client handlers
2026-04-09 17:23:20 +07:00
tiennm99 d871cc2352 refactor: delete all landlords card game code and obsolete docs
Remove ~35 files: poker entities/enums/helpers, old robot AI,
legacy server/client event handlers, Chinese i18n, docker configs,
and obsolete markdown docs.
2026-04-09 17:16:04 +07:00