8.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
This is a Three Kingdoms strategy game (SLG) server written in Go, featuring a microservices architecture with WebSocket-based real-time communication. The game includes army management, city building, coalition systems, and turn-based combat mechanics.
Build Commands
Build all servers for Linux deployment:
cd shell
./build.bat # Cross-compiles for Linux even on Windows
Individual server builds (from project root):
go build -o bin/slgserver main/slgserver.go # Main game logic server
go build -o bin/loginserver main/loginserver.go # Authentication server
go build -o bin/chatserver main/chatserver.go # Chat/messaging server
go build -o bin/gateserver main/gateserver.go # Gateway/proxy server
go build -o bin/httpserver main/httpserver.go # HTTP API server
Run servers individually (from bin directory):
./slgserver # Port 8001
./loginserver # Port 8003
./chatserver # Port 8002
./gateserver # Port 8004
./httpserver # Port 8088
Configuration
All configuration is in data/conf/env.ini:
- Database connection settings (MySQL)
- Server ports and addresses
- XORM logging and SQL debugging
- WebSocket proxy routes for gateserver
- Server ID for multi-server support
Configuration is loaded via the config package using spf13/viper.
Architecture
Microservices Structure
The system consists of 5 independent servers:
-
slgserver - Core game logic server handling:
- Army operations (conscription, movement, combat)
- City management (facilities, resources, building)
- Coalition/alliance systems
- National map and territory control
- General (hero) management and skills
-
loginserver - Authentication and session management:
- User login/logout with password hashing
- Session token generation and validation
- Server list for multi-server support
-
chatserver - Real-time messaging:
- Chat groups and channels
- Message queuing and delivery
- Broadcast notifications
-
gateserver - Gateway and routing:
- Central entry point for clients
- WebSocket proxy to backend services
- Connection lifecycle management
- Routes requests to slg/chat/login servers based on message prefix
-
httpserver - HTTP REST API (Gin framework):
- Alternative HTTP endpoints for web clients
- Account operations via REST
WebSocket Message Protocol
All servers use a custom WebSocket message format defined in net/conn.go:
// Request
{
"seq": 12345, // Message sequence number
"name": "army.myList", // Route: <group>.<handler>
"msg": {...}, // Payload
"proxy": "slg" // Target service (for gateserver routing)
}
// Response
{
"seq": 12345,
"name": "army.myList",
"code": 0, // Response code (0 = OK)
"msg": {...}
}
Message routing uses dot notation: <group>.<handler>. The router (net/router.go) supports:
- Grouped routes with middleware
- Per-route and per-group middleware
- Wildcard handlers (
*)
Data Layer Architecture
Database: MySQL accessed via XORM ORM (db/conn.go)
- Connection pooling with configurable limits
- Automatic database creation on first run
- SQL logging to file for debugging
In-Memory Managers: Core game state is cached in memory for performance:
mgr.AMgr- Army manager (logic/mgr/army_mgr.go)mgr.RCMgr- Role city managermgr.NMMgr- National map managermgr.GMgr- General managermgr.SkillMgr- Skill managermgr.UnionMgr- Coalition/alliance manager
Managers maintain indexed maps (by ID, by RID, by CityId) loaded at startup. Database writes happen via XORM but reads primarily from cache.
Static Configuration: JSON files loaded at startup:
- data/conf/json/facility/ - Building definitions
- data/conf/json/general/ - Hero stats and attributes
- data/conf/json/skill/ - Skill effects
- data/conf/json/basic.json - Game constants
- data/conf/json/map_build.json - Map structure
Loaded via static_conf package during run.Init().
Game Logic Patterns
Model-Controller-Logic Pattern:
model/- Database entities withToProto()methodscontroller/- WebSocket handlers, parse requests, validatelogic/- Business logic, game rules, calculationsproto/- Protocol buffers/data transfer objects
Key Systems:
-
Army System (server/slgserver/logic/army_war.go):
- Turn-based combat with 10 max rounds
- Position-based strategy (3 general positions per army)
- Attributes: force, defense, strategy, speed, destroy
- Facility bonuses from cities
- Battle results stored as war reports
-
City/Facility System:
- Cities have multiple facility slots
- Each facility type provides bonuses (TypeForce, TypeDefense, etc.)
- Upgrade system with resource costs and time delays
- Facilities loaded from JSON config
-
General/Skill System:
- Generals have arms (兵种), levels, experience
- Skills categorized: 主动 (active), 被动 (passive), 追击 (pursuit), 指挥 (command)
- Conscription system for recruiting troops
-
Coalition System:
- Player alliances with leadership structure
- Must load before other systems (dependency in
run.Init())
Middleware Pipeline
WebSocket handlers support middleware (middleware/):
ElapsedTime()- Request timingLog()- Request/response loggingCheckLogin()- Session validation (checksuidproperty on connection)CheckRole()- Role validation (checksroleproperty)CheckRid()- Role ID validation
Middleware wraps handlers in reverse order (last added = innermost).
Connection State Management
WebSocket connections (net/conn.go, net/serverconn.go) maintain properties:
uid- User ID (set after login)role- Role object (set after role selection)- Properties stored in sync.Map for concurrent access
The ConnMgr singleton tracks all active connections.
Development Workflow
- Modify game logic: Edit files in
server/slgserver/logic/ - Add new routes: Register in
server/slgserver/run/init.go→initRouter() - Add new models: Create in
model/, implementToProto(), add to manager - Update static config: Edit JSON files in
data/conf/json/, reload on startup - Database changes: Models use XORM tags, schema auto-syncs if configured
Server Initialization Order
Critical: The initialization sequence in server/slgserver/run/init.go must be followed:
- Test/create database (
db.TestDB()) - Load static configs (facilities, generals, skills, etc.)
- Set server ID from config
logic.BeforeInit()- Pre-initialization hooks- Load managers in dependency order:
- NMMgr (national map)
- UnionMgr (coalitions - must load first)
- RAttrMgr, RCMgr, RBMgr, RFMgr (role data)
- SkillMgr, GMgr (generals/skills)
- AMgr (armies - depends on generals)
logic.Init()andlogic.AfterInit()- Register routers (only after full initialization)
Common Patterns
Getting a user's role from connection:
r, _ := req.Conn.GetProperty("role")
role := r.(*model.Role)
Accessing managers:
army, ok := mgr.AMgr.Get(armyId)
general, ok := mgr.GMgr.Get(rid, generalId)
Database operations with XORM:
// Query
db.MasterDB.Table(model.Army{}).Where("rid=?", rid).Find(&armies)
// Insert
db.MasterDB.Table(model.Army{}).Insert(army)
// Update
db.MasterDB.Table(model.Army{}).ID(armyId).Cols("soldiers").Update(army)
Response codes: Use constants from constant/code.go (OK, DBError, InvalidParam, etc.)
Multi-Server Support
The logic.server_id config enables running multiple game servers with separate databases. Table names are suffixed with server ID (e.g., tb_role_1).
Deployment Notes
- Build script cross-compiles for Linux (CGO_ENABLED=0, GOOS=linux)
- Servers run independently, start all 5 for full functionality
- Gateserver acts as reverse proxy, client connects only to port 8004
- Configuration file must be in working directory or specify path