The 'New' prefix was a phase-06 naming compromise to avoid colliding
with a legacy Room type. That legacy type is gone now, so the prefix
is misleading — in Go 'NewX' conventionally reads as a constructor,
not a type.
- NewRoom type → Room
- JoinNewRoom → JoinRoom
- GetNewRoom → GetRoom
- LeaveNewRoom → LeaveRoom
- WatchNewRoom → WatchRoom
- UnwatchNewRoom → UnwatchRoom
- deleteNewRoom → deleteRoom
Also remove dead code uncovered by the pass:
- Delete lobby/events.go entirely — RoomEvent + BroadcastEvent wrapped
a no-op placeholder, never called.
- Delete BroadcastToNewRoom no-op from lobby/store.go — kept only for
the dead BroadcastEvent wrapper.
- Delete TestBroadcastToRoom_SkipsExcludedIDs — theater test that never
actually called BroadcastToNewRoom, just built a manual exclude map.
go vet + go test ./... green.
Rename
- server/database/ → server/lobby/ (17 import sites + qualified references)
- Package was named "database" but there is no database — it's in-memory
hashmaps for players/rooms/spectators. "lobby" accurately names its role:
the multiplayer game lobby state (who is in what room, joining/leaving,
spectating).
Ratel-online legacy cleanup
- Delete server/README.md — 100% Chinese, entirely about ratel card games
(斗地主/跑得快/德州扑克/麻将/骗子酒馆/Uno). Zero relevance to gomoku.
- Delete server/build.sh + server/build.ps1 — multi-platform ratel-server
build scripts with mixed Chinese comments, superseded by Makefile +
Dockerfile.
- Delete server/docs/ — Chinese Docker deployment guide + quickstart,
superseded by root docs/deployment-guide.md and root README.md.
- Delete server/demo.gif — ratel card-game demo screenshot.
Comment fixes: update "database" references in consts/const.go and
game/board.go package docs to point at "lobby" instead.
go vet + go test ./... green.
Protocol type safety
- Add Piece, GameResult, RoomType, RoomStatus proto3 enums; replace
unsafe string fields in GameMoveSuccessResponse, GameOverResponse,
RoomCreateSuccessResponse, RoomSummary, WatchGameSuccessResponse.
- Go compiler now rejects typos like "PVP" or "BLACK". protobufjs
toJSON() serializes enums as UPPERCASE names, so existing client
comparisons keep working.
- Fixes turn-change bug where lowercase "black"/"white" server strings
never matched client 'BLACK'/'WHITE' checks, freezing currentTurn
and blocking the non-starting player's clicks.
- Regenerate Go + JS stubs.
Room-join bug fix
- home.go handleJoinRoom now broadcasts RoomJoinSuccessResponse to all
players in the room (owner + joiner), not just the joiner. Owner
can see the player count flip to 2/2 and the Start Game button
enables. Remove superseded broadcastJoined + GameReadyResponse path.
- client menu-scene _onRoomJoinSuccess: read correct proto camelCase
field names (roomOwner, roomClientCount, clientNickname).
Dead code removal
- Delete GameReadyRequest/Response proto messages entirely; leaveRoom
notifies via ClientExitResponse.
- Delete server/network/{network,wss}.go empty stubs.
- Delete server/pkg/consts/ unused re-export package.
- Slim server/consts/const.go from 117 LOC to 24: drop legacy TCP
constants, duplicated RoomType/RoomStatus enums, Error/NewErr types,
StateJoin/StateCreate=0 type-unsafe aliases, unused GameTypes maps.
- database/player.go: remove unused IP, Mode, Type, Amount, legacy
private state field.
- Fix gopls findings: unused forPlayer, gameOverOnce, runAIMove player,
handleGameReset player params.
go vet + go test ./... green, npm run build green.
Two jobs on push/PR to main (paths-ignore: docs, plans, markdown):
- server: go vet + go test + go build (Go 1.23)
- client: npm ci + npm run build (Node 22)
menu-ui.js exceeded 200-line limit. Extract room-list, PVE difficulty panel,
and waiting-room into menu-ui-rooms.js. menu-ui.js re-exports showRoomList
and showWaiting so menu-scene.js import paths are unchanged.
menu-ui.js: nickname screen, lobby, PVP/PVE submenus, room list table,
role-aware showWaiting() — owner gets Start Game button (disabled until
playerCount=2); joiner gets passive wait message. Returns update() handle
for live ROOM_JOIN_SUCCESS pushes from menu-scene. All user strings set
via textContent for XSS safety.
game-ui.js: game HUD with turn indicator dots, scrollable move history,
showGameOver modal with Play Again (sendGameReset) and Leave buttons,
showToast auto-dismissing after 2s into #toast-container. Error toasts
wired for all GAME_MOVE_* and spectator-cannot-act events.
Replace phase-09 stubs with real Phaser.GameObjects.Graphics implementations.
Board draws wood-textured 15x15 grid with star points and coordinate labels.
Stone renders gradient black/white circle with 180ms Back.easeOut drop tween.
createLastMoveMarker draws a red filled circle at the last-played intersection.
menu-scene.js wired for live waiting-room updates and role-aware showWaiting.
27 tests covering: welcome/setNickname/home transitions, runner exit on
ErrClientExit, waiting owner/joiner role split with StartCh signal,
PVP move validation (turn order, bounds, occupancy, win detection with
GameOverCh cross-goroutine sync), PVE human+AI alternation and AI-first
when human is White, gameover reset/rematch for both PVP and PVE.
Remove database/legacy.go (legacy hashmap store, Room/Gomoku types).
Remove state/create.go and state/join.go (collapsed into home.go).
Remove state/game/gomoku.go (replaced by game_pvp.go + game_shared.go).
Remove server/pkg/{model,network,protocol,async,json,strings} packages
that are no longer imported after the state machine rewrite.
Stub out network/network.go (legacy TCP handler retired).
Rewrite database/player.go to remove legacy conn/data fields.
Replace legacy AskForString/AskForPacket state machine with channel-based
runner. Each state reads *protocol.Request from player.CmdCh. Adds PVP
waiting (owner/joiner role split with StartCh signal), gamePvp (GameOverCh
for cross-goroutine game-end sync), gamePve (AI alternates with human,
AI-first when human is White), and gameover (reset/rematch support).
- index.html: dark shell with #game-container (Phaser canvas parent),
#ui-overlay containing #menu-root, #game-hud-root, #toast-container
- vite.config.js: port 5173, strictPort, sourcemap build, no GitHub Pages base
- src/main.js: instantiates Phaser.Game from gameConfig
- src/config/game-config.js: 800x800 FIT canvas, parent=game-container, scene list
- src/config/protocol-constants.js: ClientEventCode enum aligned to response.proto
oneofs; adds SPECTATOR_CANNOT_ACT, renames GAME_WATCH_SUCCESSFUL to
WATCH_GAME_SUCCESS, drops CLIENT_KICK (no proto case)
- src/scenes/boot-scene.js|menu-scene.js|game-scene.js: minimal stubs for Phaser
scene registry; phase-09 replaces them with real implementations
Adds Phaser+Vite+protobufjs package.json with proto:gen script, installs
dependencies, and commits generated protocol.js and protocol.d.ts so
builds work without requiring protoc or pbjs on every dev box.
Also adds node_modules/ to root .gitignore.
Adds tools.go to pin protoc-gen-go, updates go.mod/go.sum with
google.golang.org/protobuf, generates request.pb.go and response.pb.go,
and adds a make proto target to server/Makefile for regen.
Copies request.proto and response.proto from caro, renames package to
com.miti99.gomoku.proto, drops Java options, adds go_package option,
and appends SpectatorCannotActResponse (field 21) to the Response oneof.
Port GomokuAI.java to Go with three difficulty levels:
- Easy: uniform random (seeded RNG for determinism)
- Medium: immediate win/block heuristic from caro
- Hard: true minimax depth-3 with alpha-beta pruning
evaluatePosition uses caro threat-pattern weights (open-four=100000,
closed-four=10000, open-three=1000, etc.) as leaf evaluator.
candidateMoves limits branching to radius-2 Chebyshev neighbours.
Benchmark: ~71µs/move on 30-stone mid-game board (budget: <1s).
Port Board.java and GomokuHelper.java to idiomatic Go under server/game/.
Board is a value type ([15][15]Piece) enabling zero-allocation Clone().
Helper provides ValidMoves, FormatBoard, WinnerMessage as pure functions.
Covers all 4 win directions, draw, OOB, occupied-cell, and reset cases.
Rewrite README with usage guide, deployment instructions, and protocol
docs. Update CLAUDE.md to reflect gomoku-only architecture. Add English
doc comments to all key server Go files, replacing Chinese comments.
Create docs/system-architecture.md (state machine, protocol, database
schema) and docs/deployment-guide.md (local dev, Docker, production
nginx, resource requirements).
Update Dockerfile to Go 1.22 with repo-root build context to include
web client. Update docker-compose to match.
Remove 3,612 lines of card game implementations (Dou Dizhu, Texas
Hold'em, Mahjong, Uno, Liar's Bar, Run Fast), their database models,
rule engine, skill system, and render package.
Simplify Room struct by removing card-game-specific fields, clean up
consts to only gomoku game type, and remove unused dependencies
(mahjong, uno, cast, color).
Add server-side gomoku (five-in-a-row) as game type 9 with 15x15 board,
2-player rooms, move validation, win detection in 4 directions, and
draw detection. Includes channel-based turn sync with mutex-protected
board access.
Add vanilla JS web client served as static files from the Go server:
WebSocket connection with base64 packet encoding, state machine
navigation, Canvas-based board renderer with gradient stones, hover
ghost, last-move highlight, and game-over overlay.
Import source files from ratel-online organization repos into monorepo
structure for gomoku game development. Update README with project
structure and credits for original authors.