# 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: ```bash cd shell ./build.bat # Cross-compiles for Linux even on Windows ``` Individual server builds (from project root): ```bash 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): ```bash ./slgserver # Port 8001 ./loginserver # Port 8003 ./chatserver # Port 8002 ./gateserver # Port 8004 ./httpserver # Port 8088 ``` ## Configuration All configuration is in [data/conf/env.ini](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: 1. **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 2. **loginserver** - Authentication and session management: - User login/logout with password hashing - Session token generation and validation - Server list for multi-server support 3. **chatserver** - Real-time messaging: - Chat groups and channels - Message queuing and delivery - Broadcast notifications 4. **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 5. **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](net/conn.go): ```go // Request { "seq": 12345, // Message sequence number "name": "army.myList", // Route: . "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: `.`. The router ([net/router.go](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](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](server/slgserver/logic/mgr/army_mgr.go)) - `mgr.RCMgr` - Role city manager - `mgr.NMMgr` - National map manager - `mgr.GMgr` - General manager - `mgr.SkillMgr` - Skill manager - `mgr.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/](data/conf/json/facility/) - Building definitions - [data/conf/json/general/](data/conf/json/general/) - Hero stats and attributes - [data/conf/json/skill/](data/conf/json/skill/) - Skill effects - [data/conf/json/basic.json](data/conf/json/basic.json) - Game constants - [data/conf/json/map_build.json](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 with `ToProto()` methods - `controller/` - WebSocket handlers, parse requests, validate - `logic/` - Business logic, game rules, calculations - `proto/` - Protocol buffers/data transfer objects **Key Systems**: 1. **Army System** ([server/slgserver/logic/army_war.go](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 2. **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 3. **General/Skill System**: - Generals have arms (兵种), levels, experience - Skills categorized: 主动 (active), 被动 (passive), 追击 (pursuit), 指挥 (command) - Conscription system for recruiting troops 4. **Coalition System**: - Player alliances with leadership structure - Must load before other systems (dependency in `run.Init()`) ### Middleware Pipeline WebSocket handlers support middleware ([middleware/](middleware/)): - `ElapsedTime()` - Request timing - `Log()` - Request/response logging - `CheckLogin()` - Session validation (checks `uid` property on connection) - `CheckRole()` - Role validation (checks `role` property) - `CheckRid()` - Role ID validation Middleware wraps handlers in reverse order (last added = innermost). ### Connection State Management WebSocket connections ([net/conn.go](net/conn.go), [net/serverconn.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 1. **Modify game logic**: Edit files in `server/slgserver/logic/` 2. **Add new routes**: Register in `server/slgserver/run/init.go` → `initRouter()` 3. **Add new models**: Create in `model/`, implement `ToProto()`, add to manager 4. **Update static config**: Edit JSON files in `data/conf/json/`, reload on startup 5. **Database changes**: Models use XORM tags, schema auto-syncs if configured ## Server Initialization Order Critical: The initialization sequence in [server/slgserver/run/init.go](server/slgserver/run/init.go) must be followed: 1. Test/create database (`db.TestDB()`) 2. Load static configs (facilities, generals, skills, etc.) 3. Set server ID from config 4. `logic.BeforeInit()` - Pre-initialization hooks 5. 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) 6. `logic.Init()` and `logic.AfterInit()` 7. Register routers (only after full initialization) ## Common Patterns **Getting a user's role from connection**: ```go r, _ := req.Conn.GetProperty("role") role := r.(*model.Role) ``` **Accessing managers**: ```go army, ok := mgr.AMgr.Get(armyId) general, ok := mgr.GMgr.Get(rid, generalId) ``` **Database operations with XORM**: ```go // 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](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