12 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Erupe is a community-maintained server emulator for Monster Hunter Frontier written in Go. It reverse-engineers the game server protocol to enable self-hosted Monster Hunter Frontier servers, supporting multiple game versions (Season 6.0 through ZZ) and platforms (PC, PS3, PS Vita, Wii U).
Module name: erupe-ce
Go version: 1.25+
Current branch purpose: Clean transition from 9.2.0 to future 9.3.0 release
Build and Development Commands
Building and Running
# Build the server
go build
# Build and produce binary
go build -o erupe-ce
# Run without building
go run .
# Run with hot reload during development
go run main.go
Testing
# Run all tests
go test -v ./...
# Run tests for specific package
go test -v ./server/channelserver/...
# Run specific test
go test -v ./server/channelserver/... -run TestName
# Check for race conditions (important!)
go test -v -race ./...
# Generate test coverage
go test -v -cover ./...
go test ./... -coverprofile=/tmp/coverage.out
go tool cover -html=/tmp/coverage.out -o /tmp/coverage.html
Code Quality
# Format code (ALWAYS run before committing)
gofmt -w .
# Lint code
golangci-lint run ./...
# Fix linting issues automatically
golangci-lint run ./... --fix
Database Operations
# Connect to PostgreSQL
psql -U postgres -d erupe
# Apply schema patches (must be done in order)
psql -U postgres -d erupe -f patch-schema/01_patch.sql
psql -U postgres -d erupe -f patch-schema/02_patch.sql
# ... continue in order
# With password from environment
PGPASSWORD='password' psql -U postgres -d erupe -f schema.sql
Docker Development
# Start database and pgadmin
docker compose up db pgadmin
# Start server (after configuring database)
docker compose up server
# Full stack
docker compose up
Log Analysis
The project includes a comprehensive log analyzer tool in tools/loganalyzer/:
# Build log analyzer
cd tools/loganalyzer
go build -o loganalyzer
# Filter logs by level
./loganalyzer filter -f ../../logs/erupe.log -level error
# Analyze errors with stack traces
./loganalyzer errors -f ../../logs/erupe.log -stack -detailed
# Track player connections
./loganalyzer connections -f ../../logs/erupe.log -sessions
# Real-time log monitoring
./loganalyzer tail -f ../../logs/erupe.log -level error
# Generate statistics
./loganalyzer stats -f ../../logs/erupe.log -detailed
Architecture
Three-Server Architecture
Erupe uses a multi-server architecture that mirrors the original Monster Hunter Frontier server design:
-
Sign Server (Port 53312)
- Handles authentication and account management
- Located in
server/signserver/ - Two versions: legacy (signserver) and modern HTTP-based (signv2server)
- Creates sign sessions with tokens for channel server authentication
-
Entrance Server (Port 53310)
- Manages world/server selection and character list
- Located in
server/entranceserver/ - Routes players to available channel servers
- Maintains server availability information
-
Channel Servers (Ports 54001+)
- Handle actual gameplay sessions, quests, and player interactions
- Located in
server/channelserver/ - Multiple instances can run simultaneously
- Organized by world types (Newbie, Normal, Cities, Tavern, Return, MezFes)
Channel Server Internal Architecture
The channel server is the most complex component:
Session Management (sys_session.go)
- Each player connection creates a
Sessionstruct - Sessions handle packet queuing, encryption, and client state
- Uses goroutines for send/receive loops
- Thread-safe with mutex locks
Handler System (handlers_table.go)
- Packet handlers registered in
handlerTablemap - Maps
network.PacketIDtohandlerFunc - Handlers organized by feature in separate files:
handlers_quest.go- Quest systemhandlers_guild.go- Guild operationshandlers_stage.go- Stage/room managementhandlers_character.go- Character datahandlers_*.go- Feature-specific handlers
Stage System (sys_stage.go)
- Stages are game rooms/areas where players interact
- Thread-safe stage creation, entry, movement, and destruction
- Stage locking/unlocking for privacy
- Stage binary data for synchronizing state between players
Semaphore System (sys_semaphore.go)
- Resource locking mechanism for shared game resources
- Used for quests, events, and multiplayer coordination
- Global and local semaphores
Special Event Systems
- Raviente: Large-scale raid event (in
Server.raviente) - Diva Defense, Hunter's Festa, VS Tournament (handlers in
handlers_event.go,handlers_festa.go,handlers_tournament.go)
Network Layer
Packet Structure (network/mhfpacket/)
- Packet definitions in
msg_*.gofiles - Each packet type implements
MHFPacketinterface - Packets prefixed by type:
MSG_SYS_*,MSG_MHF_*,MSG_CA_* - Binary packet handling in
network/binpacket/
Encryption (network/crypt_packet.go)
- Custom encryption layer wrapping connections
- Different crypto for different server types
Compression (server/channelserver/compression/)
- Delta compression (
deltacomp) for bandwidth optimization - Null compression (
nullcomp) for debugging
Common Utilities
ByteFrame (common/byteframe/)
- Buffer for reading/writing binary data
- Provides methods for reading/writing various data types
- Critical for packet construction and parsing
PascalString (common/pascalstring/)
- Length-prefixed string format used by game protocol
- Different variants for different string types
Client Context (network/clientctx/)
- Stores client version and capabilities
- Used for multi-version support
Database Schema Management
Schema Types:
- Initialization Schema: Bootstraps database to version 9.1.0 (in
schemas/) - Patch Schemas: Development updates in
patch-schema/(numbered, apply in order) - Update Schemas: Production-ready consolidated updates (for releases)
- Bundled Schemas: Demo data templates in
schemas/bundled-schema/(shops, events, gacha)
Important: Patch schemas are subject to change during development. They get consolidated into update schemas on release. Apply patches in numerical order.
Configuration System
Configuration uses Viper and is defined in config/config.go. The ErupeConfig global variable holds runtime configuration loaded from config.json.
Key configuration sections:
DevModeandDevModeOptions- Development flags and debuggingGameplayOptions- Gameplay modifiers (NP/RP caps, boost times, quest allowances)Database- PostgreSQL connection settingsSign,SignV2,Entrance,Channel- Server enable/disable and portsDiscord- Discord bot integrationLogging- File logging with rotation (uses lumberjack)
Concurrency Patterns
Critical: This codebase heavily uses goroutines and shared state. Always:
-
Use mutexes when accessing shared state:
- Server-level:
s.server.Lock()/s.server.Unlock() - Stage-level:
s.server.stagesLock.Lock()/s.server.stagesLock.Unlock() - Session-level:
s.Lock()/s.Unlock()
- Server-level:
-
Use RWMutex for read-heavy operations:
s.server.stagesLock.RLock()for readss.server.stagesLock.Lock()for writes
-
Test with race detector:
go test -race ./... -
Common concurrency scenarios:
- Stage access: Always lock
s.server.stagesLockwhen reading/writing stage map - Session broadcasts: Iterate sessions under lock
- Database operations: Use transactions for multi-step operations
- Stage access: Always lock
Packet Handler Development
When adding new packet handlers:
- Define packet structure in
network/mhfpacket/msg_*.go - Implement
Build()andParse()methods - Add handler function in appropriate
handlers_*.gofile - Register in
handlerTablemap inhandlers_table.go - Use helper functions:
doAckBufSucceed(s, ackHandle, data)- Success response with datadoAckBufFail(s, ackHandle, data)- Failure responsestubEnumerateNoResults(s, ackHandle)- Empty enumerate responsestubGetNoResults(s, ackHandle)- Empty get response
Example handler pattern:
func handleMsgMhfYourPacket(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfYourPacket)
// Process packet
resp := byteframe.NewByteFrame()
resp.WriteUint32(someValue)
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
}
Testing Practices
- Use table-driven tests for multiple scenarios
- Mock database operations where appropriate
- Test concurrent access patterns with goroutines
- Test both success and error paths
- Add tests in
*_test.gofiles next to source files
Common Pitfalls
- Thread Safety: Always consider concurrent access. If unsure, add locks.
- Database Queries: Use parameterized queries (
$1,$2) to prevent SQL injection - Error Handling: Never ignore errors - log them or handle appropriately
- Session State: Be careful with session state during disconnects
- Packet Ordering: Some packets have ordering requirements - check client expectations
- Binary Data: Always use
byteframefor binary reads/writes to ensure correct endianness
Commit and PR Guidelines
Commit message format:
feat: description- New featuresfix: description- Bug fixesrefactor: description- Code refactoringdocs: description- Documentationchore: description- Maintenance tasks
Before committing:
- Run
gofmt -w . - Run tests:
go test -v ./... - Check for race conditions:
go test -race ./... - Update CHANGELOG.md under "Unreleased" section
PR Requirements:
- Clear description of changes
- Test coverage for new features
- No race conditions
- Passes all existing tests
- Updated documentation if needed
Remote Server Operations
Environment variables for remote operations are stored in .env (gitignored). Copy from .env.example if needed.
Fetch Logs
# Load environment and fetch logs
source .env
scp -r $SERVER:$REMOTE_LOGS/* $LOCAL_LOGS/
Deploy
# Build for Linux, upload, and restart
source .env
GOOS=linux GOARCH=amd64 go build -o erupe-ce
scp erupe-ce $SERVER:$REMOTE_BIN
ssh $SERVER "cd $REMOTE_DIR && sudo systemctl restart erupe"
Quick Commands
# Check server status
source .env && ssh $SERVER "systemctl status erupe"
# Tail remote logs
source .env && ssh $SERVER "tail -f $REMOTE_LOGS/erupe.log"
# View recent errors
source .env && ssh $SERVER "grep -E 'level.*(error|warn)' $REMOTE_LOGS/erupe.log | tail -50"
Discord Integration
Optional Discord bot in server/discordbot/ provides:
- Real-time server activity notifications
- Player connection/disconnection events
- Quest completions and event notifications
Configured via Discord section in config.json.
Multi-Version Support
The codebase supports multiple game client versions through:
ClientModeconfiguration setting- Client context detection
- Version-specific packet handling
- Binary file compatibility (quests/scenarios in
bin/)
Primary focus: G10-ZZ (ClientMode), with varying support for older versions.