diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 000000000..90894ae23
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,356 @@
+# 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
+
+```bash
+# 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
+
+```bash
+# 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
+
+```bash
+# Format code (ALWAYS run before committing)
+gofmt -w .
+
+# Lint code
+golangci-lint run ./...
+
+# Fix linting issues automatically
+golangci-lint run ./... --fix
+```
+
+### Database Operations
+
+```bash
+# 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
+
+```bash
+# 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/`:
+
+```bash
+# 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:
+
+1. **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
+
+2. **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
+
+3. **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](server/channelserver/sys_session.go))
+
+- Each player connection creates a `Session` struct
+- Sessions handle packet queuing, encryption, and client state
+- Uses goroutines for send/receive loops
+- Thread-safe with mutex locks
+
+**Handler System** ([handlers_table.go](server/channelserver/handlers_table.go))
+
+- Packet handlers registered in `handlerTable` map
+- Maps `network.PacketID` to `handlerFunc`
+- Handlers organized by feature in separate files:
+ - `handlers_quest.go` - Quest system
+ - `handlers_guild.go` - Guild operations
+ - `handlers_stage.go` - Stage/room management
+ - `handlers_character.go` - Character data
+ - `handlers_*.go` - Feature-specific handlers
+
+**Stage System** ([sys_stage.go](server/channelserver/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](server/channelserver/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/](network/mhfpacket/))
+
+- Packet definitions in `msg_*.go` files
+- Each packet type implements `MHFPacket` interface
+- Packets prefixed by type: `MSG_SYS_*`, `MSG_MHF_*`, `MSG_CA_*`
+- Binary packet handling in `network/binpacket/`
+
+**Encryption** ([network/crypt_packet.go](network/crypt_packet.go))
+
+- Custom encryption layer wrapping connections
+- Different crypto for different server types
+
+**Compression** ([server/channelserver/compression/](server/channelserver/compression/))
+
+- Delta compression (`deltacomp`) for bandwidth optimization
+- Null compression (`nullcomp`) for debugging
+
+### Common Utilities
+
+**ByteFrame** ([common/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/](common/pascalstring/))
+
+- Length-prefixed string format used by game protocol
+- Different variants for different string types
+
+**Client Context** ([network/clientctx/](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:**
+
+- `DevMode` and `DevModeOptions` - Development flags and debugging
+- `GameplayOptions` - Gameplay modifiers (NP/RP caps, boost times, quest allowances)
+- `Database` - PostgreSQL connection settings
+- `Sign`, `SignV2`, `Entrance`, `Channel` - Server enable/disable and ports
+- `Discord` - Discord bot integration
+- `Logging` - File logging with rotation (uses lumberjack)
+
+## Concurrency Patterns
+
+**Critical:** This codebase heavily uses goroutines and shared state. Always:
+
+1. 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()`
+
+2. Use RWMutex for read-heavy operations:
+ - `s.server.stagesLock.RLock()` for reads
+ - `s.server.stagesLock.Lock()` for writes
+
+3. Test with race detector:
+
+ ```bash
+ go test -race ./...
+ ```
+
+4. Common concurrency scenarios:
+ - Stage access: Always lock `s.server.stagesLock` when reading/writing stage map
+ - Session broadcasts: Iterate sessions under lock
+ - Database operations: Use transactions for multi-step operations
+
+## Packet Handler Development
+
+When adding new packet handlers:
+
+1. Define packet structure in `network/mhfpacket/msg_*.go`
+2. Implement `Build()` and `Parse()` methods
+3. Add handler function in appropriate `handlers_*.go` file
+4. Register in `handlerTable` map in `handlers_table.go`
+5. Use helper functions:
+ - `doAckBufSucceed(s, ackHandle, data)` - Success response with data
+ - `doAckBufFail(s, ackHandle, data)` - Failure response
+ - `stubEnumerateNoResults(s, ackHandle)` - Empty enumerate response
+ - `stubGetNoResults(s, ackHandle)` - Empty get response
+
+Example handler pattern:
+
+```go
+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.go` files next to source files
+
+## Common Pitfalls
+
+1. **Thread Safety:** Always consider concurrent access. If unsure, add locks.
+2. **Database Queries:** Use parameterized queries (`$1`, `$2`) to prevent SQL injection
+3. **Error Handling:** Never ignore errors - log them or handle appropriately
+4. **Session State:** Be careful with session state during disconnects
+5. **Packet Ordering:** Some packets have ordering requirements - check client expectations
+6. **Binary Data:** Always use `byteframe` for binary reads/writes to ensure correct endianness
+
+## Commit and PR Guidelines
+
+**Commit message format:**
+
+- `feat: description` - New features
+- `fix: description` - Bug fixes
+- `refactor: description` - Code refactoring
+- `docs: description` - Documentation
+- `chore: description` - Maintenance tasks
+
+**Before committing:**
+
+1. Run `gofmt -w .`
+2. Run tests: `go test -v ./...`
+3. Check for race conditions: `go test -race ./...`
+4. 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
+
+## 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:
+
+- `ClientMode` configuration 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.
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..4c29a7bb4
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,249 @@
+# Erupe Configuration Documentation
+
+Comprehensive configuration documentation for Erupe, the Monster Hunter Frontier server emulator.
+
+## Quick Start
+
+1. Copy [config.example.json](../config.example.json) to `config.json`
+2. Read [Basic Settings](basic-settings.md) and [Server Configuration](server-configuration.md)
+3. Set up [Database](database.md)
+4. Adjust [Gameplay Options](gameplay-options.md) to your preference
+5. Start the server!
+
+## Documentation Index
+
+### Essential Configuration
+
+- **[Basic Settings](basic-settings.md)** - Host, language, and basic server options
+- **[Server Configuration](server-configuration.md)** - Sign, Entrance, and Channel server setup
+- **[Database](database.md)** - PostgreSQL configuration and schema management
+
+### Development
+
+- **[Development Mode](development-mode.md)** - Debug options, packet logging, and testing tools
+- **[Logging](logging.md)** - File logging, rotation, and log analysis
+
+### Gameplay & Features
+
+- **[Gameplay Options](gameplay-options.md)** - NP/RP caps, boost times, quest allowances
+- **[Courses](courses.md)** - Subscription course configuration
+- **[In-Game Commands](commands.md)** - Chat commands for players and admins
+
+### Optional Features
+
+- **[Discord Integration](discord-integration.md)** - Real-time Discord bot for server activity
+
+## Configuration File Structure
+
+The main configuration file is `config.json` with this structure:
+
+```json
+{
+ "Host": "127.0.0.1",
+ "BinPath": "bin",
+ "Language": "en",
+
+ "DevMode": false,
+ "DevModeOptions": { ... },
+
+ "GameplayOptions": { ... },
+ "Logging": { ... },
+ "Discord": { ... },
+ "Commands": [ ... ],
+ "Courses": [ ... ],
+
+ "Database": { ... },
+
+ "Sign": { ... },
+ "SignV2": { ... },
+ "Channel": { ... },
+ "Entrance": { ... }
+}
+```
+
+## Configuration Sections
+
+| Section | Documentation | Purpose |
+|---------|---------------|---------|
+| Basic Settings | [basic-settings.md](basic-settings.md) | Host, paths, language, login notices |
+| DevMode | [development-mode.md](development-mode.md) | Development and debugging options |
+| GameplayOptions | [gameplay-options.md](gameplay-options.md) | Gameplay balance and modifiers |
+| Logging | [logging.md](logging.md) | File logging and rotation |
+| Discord | [discord-integration.md](discord-integration.md) | Discord bot integration |
+| Commands | [commands.md](commands.md) | In-game chat commands |
+| Courses | [courses.md](courses.md) | Subscription courses |
+| Database | [database.md](database.md) | PostgreSQL connection |
+| Sign/SignV2 | [server-configuration.md](server-configuration.md#sign-server) | Authentication servers |
+| Channel | [server-configuration.md](server-configuration.md#channel-server) | Gameplay server |
+| Entrance | [server-configuration.md](server-configuration.md#entrance-server) | World list server |
+
+## Common Configuration Scenarios
+
+### Local Development Server
+
+Perfect for testing and development:
+
+```json
+{
+ "Host": "127.0.0.1",
+ "DevMode": true,
+ "DevModeOptions": {
+ "AutoCreateAccount": true,
+ "MaxLauncherHR": true
+ },
+ "Database": {
+ "Host": "localhost",
+ "User": "postgres",
+ "Password": "dev",
+ "Database": "erupe_dev"
+ }
+}
+```
+
+See: [development-mode.md](development-mode.md)
+
+### Production Server (Minimal)
+
+Minimal production-ready configuration:
+
+```json
+{
+ "Host": "",
+ "DevMode": false,
+ "DisableSoftCrash": true,
+ "Logging": {
+ "LogToFile": true,
+ "LogMaxBackups": 7,
+ "LogMaxAge": 30
+ },
+ "Database": {
+ "Host": "localhost",
+ "User": "erupe",
+ "Password": "SECURE_PASSWORD_HERE",
+ "Database": "erupe"
+ }
+}
+```
+
+See: [basic-settings.md](basic-settings.md), [logging.md](logging.md)
+
+### Community Server
+
+Feature-rich community server:
+
+```json
+{
+ "Host": "",
+ "DevMode": false,
+ "HideLoginNotice": false,
+ "LoginNotices": ["Welcome to our server!"],
+ "GameplayOptions": {
+ "MaximumNP": 999999,
+ "BoostTimeDuration": 240
+ },
+ "Discord": {
+ "Enabled": true,
+ "BotToken": "YOUR_TOKEN",
+ "RealtimeChannelID": "YOUR_CHANNEL_ID"
+ },
+ "Commands": [
+ {"Name": "Reload", "Enabled": true, "Prefix": "!reload"},
+ {"Name": "Course", "Enabled": true, "Prefix": "!course"}
+ ]
+}
+```
+
+See: [gameplay-options.md](gameplay-options.md), [discord-integration.md](discord-integration.md), [commands.md](commands.md)
+
+## Security Checklist
+
+Before running a public server, verify:
+
+- [ ] `DevMode: false` - Disable development mode
+- [ ] `AutoCreateAccount: false` - Require manual account creation
+- [ ] `DisableTokenCheck: false` - Enable token validation
+- [ ] `CleanDB: false` - Don't wipe database on startup
+- [ ] Strong database password set
+- [ ] `Rights` command disabled (or carefully controlled)
+- [ ] `KeyQuest` command disabled (unless intentional)
+- [ ] Firewall configured for only necessary ports
+- [ ] Database not exposed publicly
+- [ ] Logging enabled for monitoring
+
+See: [development-mode.md#security-warnings](development-mode.md#security-warnings)
+
+## Performance Tuning
+
+For large servers:
+
+1. **Increase player limits**: Adjust `MaxPlayers` in channel configuration
+2. **Add more channels**: Distribute load across multiple channel servers
+3. **Optimize database**: Use connection pooling, increase shared buffers
+4. **Increase log rotation**: Larger `LogMaxSize` and `LogMaxBackups`
+5. **Monitor resources**: Use log analyzer to track errors and performance
+
+See: [server-configuration.md](server-configuration.md), [database.md#performance-tuning](database.md#performance-tuning)
+
+## Configuration Validation
+
+Erupe validates configuration on startup. Common errors:
+
+| Error | Cause | Fix |
+|-------|-------|-----|
+| "Database password is blank" | Empty password field | Set a password in config |
+| "Invalid host address" | Malformed Host value | Use valid IP or leave empty for auto-detect |
+| "Discord failed" | Invalid Discord config | Check bot token and channel ID |
+| Port already in use | Port conflict | Change port or stop conflicting service |
+
+## Environment-Specific Configuration
+
+### Docker
+
+When running in Docker, use service names for hosts:
+
+```json
+{
+ "Database": {
+ "Host": "db",
+ "Port": 5432
+ }
+}
+```
+
+See: [database.md#docker-setup](database.md#docker-setup)
+
+### Cloud Hosting
+
+For cloud deployments:
+
+- Use environment variables for secrets (requires code modification)
+- Enable `DisableSoftCrash: true` for auto-restart
+- Use absolute paths for logs (`/var/log/erupe/erupe.log`)
+- Consider external database (RDS, Cloud SQL)
+
+## Additional Resources
+
+- [CLAUDE.md](../CLAUDE.md) - Development guide and architecture
+- [config.example.json](../config.example.json) - Full example configuration
+- [Log Analyzer](../tools/loganalyzer/) - Log analysis tools
+- [GitHub Issues](https://github.com/Andoryuuta/Erupe/issues) - Report bugs and request features
+
+## Getting Help
+
+If you need help with configuration:
+
+1. Check the relevant documentation page above
+2. Review [config.example.json](../config.example.json) for examples
+3. Check server logs for specific errors
+4. Search [GitHub Issues](https://github.com/Andoryuuta/Erupe/issues)
+5. Ask in the Erupe Discord community
+
+## Contributing
+
+Found an error or want to improve these docs?
+
+1. Fork the repository
+2. Edit the documentation in `docs/`
+3. Submit a pull request
+
+See [CLAUDE.md](../CLAUDE.md#commit-and-pr-guidelines) for contribution guidelines.
diff --git a/docs/basic-settings.md b/docs/basic-settings.md
new file mode 100644
index 000000000..e5ec5878d
--- /dev/null
+++ b/docs/basic-settings.md
@@ -0,0 +1,89 @@
+# Basic Server Settings
+
+Basic configuration options for Erupe server hosting.
+
+## Configuration
+
+```json
+{
+ "Host": "127.0.0.1",
+ "BinPath": "bin",
+ "Language": "en",
+ "DisableSoftCrash": false,
+ "HideLoginNotice": true,
+ "LoginNotices": [
+ "
Welcome to Erupe!"
+ ],
+ "PatchServerManifest": "",
+ "PatchServerFile": "",
+ "ScreenshotAPIURL": "",
+ "DeleteOnSaveCorruption": false
+}
+```
+
+## Settings Reference
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `Host` | string | auto-detect | Server IP address. Leave empty to auto-detect. Use `"127.0.0.1"` for local hosting |
+| `BinPath` | string | `"bin"` | Path to binary game data (quests, scenarios, etc.) |
+| `Language` | string | `"en"` | Server language. `"en"` for English, `"jp"` for Japanese |
+| `DisableSoftCrash` | boolean | `false` | When `true`, server exits immediately on crash (useful for auto-restart scripts) |
+| `HideLoginNotice` | boolean | `true` | Hide the Erupe welcome notice on login |
+| `LoginNotices` | array | `[]` | Custom MHFML-formatted login notices to display to players |
+| `PatchServerManifest` | string | `""` | Override URL for patch manifest server (optional) |
+| `PatchServerFile` | string | `""` | Override URL for patch file server (optional) |
+| `ScreenshotAPIURL` | string | `""` | Destination URL for screenshots uploaded to BBS (optional) |
+| `DeleteOnSaveCorruption` | boolean | `false` | If `true`, corrupted save data will be flagged for deletion |
+
+## Login Notices
+
+Login notices use MHFML (Monster Hunter Frontier Markup Language) formatting:
+
+```text
+Large Centered Red Text
+Normal Left-Aligned Yellow Text
+White Text
+```
+
+**Common MHFML Tags:**
+
+- `` - Start new line
+- `
` - Line break
+- ``, ``, `` - Text alignment
+- ``, `` - Text size
+- `` (Red), `` (Yellow), `` (White) - Text color
+
+## Examples
+
+### Local Development Server
+
+```json
+{
+ "Host": "127.0.0.1",
+ "BinPath": "bin",
+ "Language": "en",
+ "DisableSoftCrash": false,
+ "HideLoginNotice": false
+}
+```
+
+### Production Server with Auto-Restart
+
+```json
+{
+ "Host": "",
+ "BinPath": "bin",
+ "Language": "en",
+ "DisableSoftCrash": true,
+ "HideLoginNotice": false,
+ "LoginNotices": [
+ "Welcome to Our Server!
Join our Discord: discord.gg/example"
+ ]
+}
+```
+
+## Related Documentation
+
+- [Server Configuration](server-configuration.md) - Server types and ports
+- [Configuration Overview](README.md) - All configuration options
diff --git a/docs/commands.md b/docs/commands.md
new file mode 100644
index 000000000..ebbf44f22
--- /dev/null
+++ b/docs/commands.md
@@ -0,0 +1,335 @@
+# In-Game Commands
+
+In-game chat commands for players and administrators.
+
+## Configuration
+
+```json
+{
+ "Commands": [
+ {
+ "Name": "Rights",
+ "Enabled": false,
+ "Prefix": "!rights"
+ },
+ {
+ "Name": "Raviente",
+ "Enabled": true,
+ "Prefix": "!ravi"
+ },
+ {
+ "Name": "Teleport",
+ "Enabled": false,
+ "Prefix": "!tele"
+ },
+ {
+ "Name": "Reload",
+ "Enabled": true,
+ "Prefix": "!reload"
+ },
+ {
+ "Name": "KeyQuest",
+ "Enabled": false,
+ "Prefix": "!kqf"
+ },
+ {
+ "Name": "Course",
+ "Enabled": true,
+ "Prefix": "!course"
+ }
+ ]
+}
+```
+
+## How Commands Work
+
+1. **Player Types Command**: Player sends a chat message starting with the command prefix
+2. **Command Parser**: Server checks if message matches any enabled command prefix
+3. **Command Handler**: Executes the command logic
+4. **Response**: Server sends feedback message to the player
+
+Commands are parsed in [handlers_cast_binary.go:90](../server/channelserver/handlers_cast_binary.go#L90).
+
+## Available Commands
+
+### Reload
+
+**Prefix:** `!reload`
+**Recommended:** Enabled
+**Usage:** `!reload`
+
+Reloads all players and objects in the current stage:
+
+1. Removes all other players/objects from view
+2. Waits 500ms
+3. Re-adds all players/objects with updated data
+
+**Use Cases:**
+
+- Visual glitches (players appearing in wrong positions)
+- Objects not displaying correctly
+- Stage synchronization issues
+
+**Example:**
+
+```text
+Player types: !reload
+Server: "Reloading all players and objects..."
+[View refreshes]
+```
+
+### Raviente
+
+**Prefix:** `!ravi`
+**Recommended:** Enabled
+**Usage:** `!ravi `
+
+Control Raviente raid event.
+
+**Subcommands:**
+
+- `!ravi start` - Start the Raviente event
+- `!ravi cm` or `!ravi checkmultiplier` - Check current damage multiplier
+
+**Examples:**
+
+```text
+Player types: !ravi start
+Server: "Raviente event started!"
+
+Player types: !ravi cm
+Server: "Current Raviente multiplier: 2.5x"
+```
+
+### Course
+
+**Prefix:** `!course`
+**Recommended:** Enabled
+**Usage:** `!course `
+
+Enable or disable subscription courses for your character.
+
+**Course Names:**
+
+- `hunterlife` or `hl` - Hunter Life Course
+- `extra` or `ex` - Extra Course
+- `premium` - Premium Course
+- `assist` - Assist Course
+- `n` - N Course
+- `hiden` - Hiden Course
+- `huntersupport` or `hs` - Hunter Support Course
+- `nboost` - N Boost Course
+- `netcafe` or `nc` - NetCafe Course
+- `hlrenewing` - Hunter Life Renewing Course
+- `exrenewing` - Extra Renewing Course
+
+**Note:** Only courses with `Enabled: true` in the [Courses](courses.md) configuration can be toggled.
+
+**Examples:**
+
+```text
+Player types: !course premium
+Server: "Premium Course enabled!"
+[Player's account rights updated]
+
+Player types: !course premium
+Server: "Premium Course disabled!"
+[Toggled off]
+
+Player types: !course hiden
+Server: "Hiden Course is locked on this server"
+[Course not enabled in config]
+```
+
+### KeyQuest (KQF)
+
+**Prefix:** `!kqf`
+**Recommended:** Disabled (unless intentional)
+**Usage:** `!kqf get` or `!kqf set `
+
+Get or set Key Quest flags (unlocks).
+
+**Subcommands:**
+
+- `!kqf get` - Display current KQF value
+- `!kqf set <16-char hex>` - Set KQF value
+
+**Examples:**
+
+```text
+Player types: !kqf get
+Server: "Your KQF is: 0123456789ABCDEF"
+
+Player types: !kqf set 0000000000000000
+Server: "KQF set successfully!"
+[Quest unlocks updated]
+
+Player types: !kqf set invalid
+Server: "Usage: !kqf set <16 hex characters>"
+```
+
+**Warning:** This allows players to unlock content. Disable unless you want players to have this power.
+
+### Rights
+
+**Prefix:** `!rights`
+**Recommended:** Disabled
+**Usage:** `!rights `
+
+Modify account rights/permissions (bitfield of enabled courses and permissions).
+
+**Example:**
+
+```text
+Player types: !rights 255
+Server: "Account rights set to: 255"
+[All courses/permissions enabled]
+
+Player types: !rights abc
+Server: "Usage: !rights "
+```
+
+**⚠️ SECURITY WARNING:** This allows players to grant themselves admin privileges and all courses. **Only enable in development or for trusted administrators.**
+
+### Teleport
+
+**Prefix:** `!tele`
+**Recommended:** Disabled (not yet implemented)
+**Usage:** `!tele `
+
+Teleport to specific locations.
+
+**Status:** Command structure exists but handler not fully implemented in the codebase.
+
+## Command Configuration
+
+Each command has three properties:
+
+```json
+{
+ "Name": "CommandName",
+ "Enabled": true,
+ "Prefix": "!prefix"
+}
+```
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `Name` | string | Command identifier (must match internal name) |
+| `Enabled` | boolean | Whether the command is active |
+| `Prefix` | string | Chat prefix that triggers the command |
+
+### Customizing Prefixes
+
+You can change command prefixes:
+
+```json
+{
+ "Name": "Reload",
+ "Enabled": true,
+ "Prefix": "/reload"
+}
+```
+
+Now players would type `/reload` instead of `!reload`.
+
+### Disabling Commands
+
+Set `Enabled: false` to disable:
+
+```json
+{
+ "Name": "Rights",
+ "Enabled": false,
+ "Prefix": "!rights"
+}
+```
+
+When disabled, typing the command returns:
+
+```text
+Server: "The Rights command is disabled on this server"
+```
+
+## Security Considerations
+
+### High-Risk Commands (Disable in Production)
+
+- **Rights**: Grants admin privileges and all courses
+- **KeyQuest**: Unlocks restricted content
+
+### Medium-Risk Commands (Use with Caution)
+
+- **Course**: Allows players to toggle courses without payment
+ - Mitigate by limiting which courses are `Enabled` in [Courses](courses.md)
+
+### Safe Commands
+
+- **Reload**: Only affects visual state, no persistent changes
+- **Raviente**: Only affects raid event, no account changes
+
+## Implementation Details
+
+Commands are initialized on server startup from the config:
+
+```go
+// handlers_cast_binary.go:40
+func init() {
+ commands = make(map[string]config.Command)
+
+ for _, cmd := range config.ErupeConfig.Commands {
+ commands[cmd.Name] = cmd
+ if cmd.Enabled {
+ logger.Info(fmt.Sprintf("Command %s: Enabled, prefix: %s", cmd.Name, cmd.Prefix))
+ }
+ }
+}
+```
+
+Each command handler checks if the command is enabled before executing.
+
+## Examples
+
+### Minimal Safe Configuration
+
+```json
+{
+ "Commands": [
+ {"Name": "Reload", "Enabled": true, "Prefix": "!reload"},
+ {"Name": "Raviente", "Enabled": true, "Prefix": "!ravi"}
+ ]
+}
+```
+
+### Full Development Configuration
+
+```json
+{
+ "Commands": [
+ {"Name": "Rights", "Enabled": true, "Prefix": "!rights"},
+ {"Name": "Raviente", "Enabled": true, "Prefix": "!ravi"},
+ {"Name": "Teleport", "Enabled": true, "Prefix": "!tele"},
+ {"Name": "Reload", "Enabled": true, "Prefix": "!reload"},
+ {"Name": "KeyQuest", "Enabled": true, "Prefix": "!kqf"},
+ {"Name": "Course", "Enabled": true, "Prefix": "!course"}
+ ]
+}
+```
+
+### Custom Prefixes
+
+```json
+{
+ "Commands": [
+ {"Name": "Reload", "Enabled": true, "Prefix": "/refresh"},
+ {"Name": "Raviente", "Enabled": true, "Prefix": "/ravi"},
+ {"Name": "Course", "Enabled": true, "Prefix": "/sub"}
+ ]
+}
+```
+
+## Related Documentation
+
+- [Courses](courses.md) - Course configuration for the `!course` command
+- [Discord Integration](discord-integration.md) - Commands may post to Discord
+- [Gameplay Options](gameplay-options.md) - Gameplay balance settings
diff --git a/docs/configuration.md b/docs/configuration.md
new file mode 100644
index 000000000..b116ad2b1
--- /dev/null
+++ b/docs/configuration.md
@@ -0,0 +1,610 @@
+# Erupe Configuration Guide
+
+This guide explains the important configuration sections in `config.json`. Use [config.example.json](../config.example.json) as a template.
+
+## Table of Contents
+
+- [Basic Settings](#basic-settings)
+- [Development Mode](#development-mode)
+- [Gameplay Options](#gameplay-options)
+- [Logging](#logging)
+- [Discord Integration](#discord-integration)
+- [In-Game Commands](#in-game-commands)
+- [Courses](#courses)
+- [Database](#database)
+- [Server Configuration](#server-configuration)
+
+---
+
+## Basic Settings
+
+```json
+{
+ "Host": "127.0.0.1",
+ "BinPath": "bin",
+ "Language": "en",
+ "DisableSoftCrash": false,
+ "HideLoginNotice": true
+}
+```
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Host` | string | Server IP address. Leave empty to auto-detect. Use `"127.0.0.1"` for local hosting |
+| `BinPath` | string | Path to binary game data (quests, scenarios, etc.) |
+| `Language` | string | Server language. `"en"` for English, `"jp"` for Japanese |
+| `DisableSoftCrash` | boolean | When `true`, server exits immediately on crash (useful for auto-restart scripts) |
+| `HideLoginNotice` | boolean | Hide the Erupe welcome notice on login |
+| `LoginNotices` | array | Custom MHFML-formatted login notices to display |
+
+### Additional Settings
+
+- **`PatchServerManifest`**: Override URL for patch manifest server
+- **`PatchServerFile`**: Override URL for patch file server
+- **`ScreenshotAPIURL`**: Destination for screenshots uploaded to BBS
+- **`DeleteOnSaveCorruption`**: If `true`, corrupted save data will be flagged for deletion
+
+---
+
+## Development Mode
+
+```json
+{
+ "DevMode": true,
+ "DevModeOptions": {
+ "AutoCreateAccount": true,
+ "CleanDB": false,
+ "MaxLauncherHR": false,
+ "LogInboundMessages": false,
+ "LogOutboundMessages": false,
+ "MaxHexdumpLength": 256,
+ "DivaEvent": 0,
+ "FestaEvent": -1,
+ "TournamentEvent": 0,
+ "MezFesEvent": true,
+ "MezFesAlt": false,
+ "DisableTokenCheck": false,
+ "QuestDebugTools": false,
+ "SaveDumps": {
+ "Enabled": true,
+ "OutputDir": "savedata"
+ }
+ }
+}
+```
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `DevMode` | boolean | Enables development mode (more verbose logging, development logger format) |
+| `AutoCreateAccount` | boolean | **⚠️ SECURITY RISK**: Auto-create accounts on login (disable in production) |
+| `CleanDB` | boolean | **⚠️ DESTRUCTIVE**: Wipes database on server start |
+| `MaxLauncherHR` | boolean | Sets launcher HR to HR7 to join non-beginner worlds |
+| `LogInboundMessages` | boolean | Log all packets received from clients (very verbose) |
+| `LogOutboundMessages` | boolean | Log all packets sent to clients (very verbose) |
+| `MaxHexdumpLength` | number | Maximum bytes to display in packet hexdumps |
+| `DivaEvent` | number | Diva Defense event status (0 = off, higher = active) |
+| `FestaEvent` | number | Hunter's Festa event status (-1 = off, higher = active) |
+| `TournamentEvent` | number | VS Tournament event status (0 = off, higher = active) |
+| `MezFesEvent` | boolean | Enable/disable MezFes event |
+| `MezFesAlt` | boolean | Swap Volpakkun for Tokotoko in MezFes |
+| `DisableTokenCheck` | boolean | **⚠️ SECURITY RISK**: Skip login token validation |
+| `QuestDebugTools` | boolean | Enable quest debugging logs |
+| `SaveDumps.Enabled` | boolean | Enable saving character data dumps |
+| `SaveDumps.OutputDir` | string | Directory for save data dumps |
+
+---
+
+## Gameplay Options
+
+```json
+{
+ "GameplayOptions": {
+ "FeaturedWeapons": 1,
+ "MaximumNP": 100000,
+ "MaximumRP": 50000,
+ "DisableLoginBoost": false,
+ "DisableBoostTime": false,
+ "BoostTimeDuration": 120,
+ "GuildMealDuration": 60,
+ "BonusQuestAllowance": 3,
+ "DailyQuestAllowance": 1
+ }
+}
+```
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `FeaturedWeapons` | number | Number of Active Feature weapons generated daily |
+| `MaximumNP` | number | Maximum Network Points (NP) a player can hold |
+| `MaximumRP` | number | Maximum Road Points (RP) a player can hold |
+| `DisableLoginBoost` | boolean | Disable login boost system |
+| `DisableBoostTime` | boolean | Disable daily NetCafe boost time |
+| `BoostTimeDuration` | number | NetCafe boost time duration in minutes (default: 120) |
+| `GuildMealDuration` | number | Guild meal activation duration in minutes (default: 60) |
+| `BonusQuestAllowance` | number | Daily Bonus Point Quest allowance |
+| `DailyQuestAllowance` | number | Daily Quest allowance |
+
+---
+
+## Logging
+
+```json
+{
+ "Logging": {
+ "LogToFile": true,
+ "LogFilePath": "logs/erupe.log",
+ "LogMaxSize": 100,
+ "LogMaxBackups": 3,
+ "LogMaxAge": 28,
+ "LogCompress": true
+ }
+}
+```
+
+Erupe uses [lumberjack](https://github.com/natefinch/lumberjack) for automatic log rotation and compression.
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `LogToFile` | boolean | Enable file logging (logs to both console and file) |
+| `LogFilePath` | string | Path to log file (directory will be created automatically) |
+| `LogMaxSize` | number | Maximum log file size in MB before rotation (default: 100) |
+| `LogMaxBackups` | number | Number of old log files to keep (default: 3) |
+| `LogMaxAge` | number | Maximum days to retain old logs (default: 28) |
+| `LogCompress` | boolean | Compress rotated log files with gzip |
+
+**Log Format:**
+
+- When `DevMode: true`: Console format (human-readable)
+- When `DevMode: false`: JSON format (production)
+
+**Log Analysis:**
+Use the built-in log analyzer tool to analyze logs. See [Log Analysis Guide](../tools/loganalyzer/README.md) or [CLAUDE.md](../CLAUDE.md#log-analysis).
+
+---
+
+## Discord Integration
+
+```json
+{
+ "Discord": {
+ "Enabled": false,
+ "BotToken": "",
+ "RealtimeChannelID": ""
+ }
+}
+```
+
+Erupe includes an optional Discord bot that posts real-time server activity to a Discord channel.
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable Discord integration |
+| `BotToken` | string | Discord bot token from Discord Developer Portal |
+| `RealtimeChannelID` | string | Discord channel ID where activity messages will be posted |
+
+### How Discord Integration Works
+
+When enabled, the Discord bot:
+
+1. **Connects on Server Startup**: The bot authenticates using the provided bot token
+2. **Monitors Game Activity**: Listens for in-game chat messages and events
+3. **Posts to Discord**: Sends formatted messages to the specified channel
+
+**What Gets Posted:**
+
+- Player chat messages (when sent to world/server chat)
+- Player connection/disconnection events
+- Quest completions
+- Special event notifications
+
+### Setup Instructions
+
+1. **Create a Discord Bot:**
+ - Go to [Discord Developer Portal](https://discord.com/developers/applications)
+ - Create a new application
+ - Go to the "Bot" section and create a bot
+ - Copy the bot token
+
+2. **Get Channel ID:**
+ - Enable Developer Mode in Discord (User Settings → Advanced → Developer Mode)
+ - Right-click the channel you want to use
+ - Click "Copy ID"
+
+3. **Add Bot to Server:**
+ - Go to OAuth2 → URL Generator in the Developer Portal
+ - Select scopes: `bot`
+ - Select permissions: `Send Messages`, `Read Message History`
+ - Use the generated URL to invite the bot to your server
+
+4. **Configure Erupe:**
+
+ ```json
+ {
+ "Discord": {
+ "Enabled": true,
+ "BotToken": "YOUR_BOT_TOKEN_HERE",
+ "RealtimeChannelID": "YOUR_CHANNEL_ID_HERE"
+ }
+ }
+ ```
+
+**Implementation Details:**
+
+- Bot code: [server/discordbot/discord_bot.go](../server/discordbot/discord_bot.go)
+- Uses [discordgo](https://github.com/bwmarrin/discordgo) library
+- Message normalization for Discord mentions and emojis
+- Non-blocking message sending (errors are logged but don't crash the server)
+
+---
+
+## In-Game Commands
+
+```json
+{
+ "Commands": [
+ {
+ "Name": "Rights",
+ "Enabled": false,
+ "Prefix": "!rights"
+ },
+ {
+ "Name": "Raviente",
+ "Enabled": true,
+ "Prefix": "!ravi"
+ },
+ {
+ "Name": "Teleport",
+ "Enabled": false,
+ "Prefix": "!tele"
+ },
+ {
+ "Name": "Reload",
+ "Enabled": true,
+ "Prefix": "!reload"
+ },
+ {
+ "Name": "KeyQuest",
+ "Enabled": false,
+ "Prefix": "!kqf"
+ },
+ {
+ "Name": "Course",
+ "Enabled": true,
+ "Prefix": "!course"
+ }
+ ]
+}
+```
+
+In-game chat commands allow players to perform various actions by typing commands in the chat.
+
+### Available Commands
+
+| Command | Prefix | Description | Usage |
+|---------|--------|-------------|-------|
+| **Rights** | `!rights` | Modify account rights/permissions | `!rights ` |
+| **Raviente** | `!ravi` | Control Raviente event | `!ravi start`, `!ravi cm` (check multiplier) |
+| **Teleport** | `!tele` | Teleport to locations | `!tele ` |
+| **Reload** | `!reload` | Reload all players and objects in current stage | `!reload` |
+| **KeyQuest** | `!kqf` | Get/set Key Quest flags | `!kqf get`, `!kqf set ` |
+| **Course** | `!course` | Enable/disable subscription courses | `!course ` |
+
+### How Commands Work
+
+1. **Player Types Command**: Player sends a chat message starting with the command prefix
+2. **Command Parser**: Server checks if message matches any enabled command prefix
+3. **Command Handler**: Executes the command logic
+4. **Response**: Server sends feedback message to the player
+
+**Implementation Details:**
+
+- Commands are parsed in [handlers_cast_binary.go:90](../server/channelserver/handlers_cast_binary.go#L90)
+- Command map is initialized from config on server startup
+- Each command has its own handler function
+- Disabled commands return a "command disabled" message
+
+### Example Command Usage
+
+**Reload Command:**
+
+```text
+Player types: !reload
+Server: "Reloading all players and objects..."
+Server: Removes all other players/objects from view
+Server: Re-adds all players/objects with updated data
+```
+
+**Course Command:**
+
+```text
+Player types: !course premium
+Server: "Premium Course enabled!"
+Server: Updates player's account rights in database
+Server: Updates player's rights in current session
+```
+
+**KeyQuest Command:**
+
+```text
+Player types: !kqf get
+Server: "Your KQF is: 0123456789ABCDEF"
+
+Player types: !kqf set 0000000000000000
+Server: "KQF set successfully!"
+```
+
+### Security Considerations
+
+- **Rights Command**: Can grant admin privileges - disable in production
+- **KeyQuest Command**: Can unlock content - disable if not desired
+- Commands are per-server configuration (can be different per channel server)
+
+---
+
+## Courses
+
+```json
+{
+ "Courses": [
+ {"Name": "HunterLife", "Enabled": true},
+ {"Name": "Extra", "Enabled": true},
+ {"Name": "Premium", "Enabled": true},
+ {"Name": "Assist", "Enabled": false},
+ {"Name": "N", "Enabled": false},
+ {"Name": "Hiden", "Enabled": false},
+ {"Name": "HunterSupport", "Enabled": false},
+ {"Name": "NBoost", "Enabled": false},
+ {"Name": "NetCafe", "Enabled": true},
+ {"Name": "HLRenewing", "Enabled": true},
+ {"Name": "EXRenewing", "Enabled": true}
+ ]
+}
+```
+
+Courses are subscription-based features in Monster Hunter Frontier (similar to premium subscriptions).
+
+| Course | Description |
+|--------|-------------|
+| `HunterLife` | Hunter Life Course - Basic subscription benefits |
+| `Extra` | Extra Course - Additional benefits |
+| `Premium` | Premium Course - Premium features |
+| `Assist` | Assist Course - Helper features |
+| `N` | N Course |
+| `Hiden` | Hiden Course - Secret/hidden features |
+| `HunterSupport` | Hunter Support Course |
+| `NBoost` | N Boost Course |
+| `NetCafe` | NetCafe Course - Internet cafe benefits |
+| `HLRenewing` | Hunter Life Renewing Course |
+| `EXRenewing` | Extra Renewing Course |
+
+**Note:** When `Enabled: true`, players can toggle the course on/off using the `!course` command (if enabled). When `Enabled: false`, the course is completely locked and cannot be activated.
+
+---
+
+## Database
+
+```json
+{
+ "Database": {
+ "Host": "localhost",
+ "Port": 5432,
+ "User": "postgres",
+ "Password": "",
+ "Database": "erupe"
+ }
+}
+```
+
+PostgreSQL database configuration.
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Host` | string | Database host (default: `localhost`) |
+| `Port` | number | Database port (default: `5432`) |
+| `User` | string | Database user |
+| `Password` | string | Database password (**required**, must not be empty) |
+| `Database` | string | Database name |
+
+**Setup:**
+
+1. Install PostgreSQL
+2. Create database: `createdb erupe`
+3. Apply schema: `psql -U postgres -d erupe -f schema.sql`
+4. Apply patches in order: `psql -U postgres -d erupe -f patch-schema/01_patch.sql`
+
+See [CLAUDE.md](../CLAUDE.md#database-operations) for more details.
+
+---
+
+## Server Configuration
+
+### Sign Server (Authentication)
+
+```json
+{
+ "Sign": {
+ "Enabled": true,
+ "Port": 53312
+ }
+}
+```
+
+Legacy sign server for authentication and account management.
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable the sign server |
+| `Port` | number | Port number (default: 53312) |
+
+### SignV2 Server (Modern Authentication)
+
+```json
+{
+ "SignV2": {
+ "Enabled": false,
+ "Port": 8080
+ }
+}
+```
+
+Modern HTTP-based sign server (alternative to legacy sign server).
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable the modern sign server |
+| `Port` | number | Port number (default: 8080) |
+
+**Note:** Only enable one sign server at a time (Sign OR SignV2, not both).
+
+### Channel Server
+
+```json
+{
+ "Channel": {
+ "Enabled": true
+ }
+}
+```
+
+Channel servers handle actual gameplay sessions, quests, and player interactions.
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable channel servers (required for gameplay) |
+
+### Entrance Server
+
+```json
+{
+ "Entrance": {
+ "Enabled": true,
+ "Port": 53310,
+ "Entries": [
+ {
+ "Name": "Newbie",
+ "Description": "",
+ "IP": "",
+ "Type": 3,
+ "Recommended": 2,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 100 },
+ { "Port": 54002, "MaxPlayers": 100 }
+ ]
+ }
+ ]
+ }
+}
+```
+
+Entrance server manages world/server selection and character lists.
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable entrance server (required) |
+| `Port` | number | Entrance server port (default: 53310) |
+
+#### Entrance Entries
+
+Each entry represents a "world" in the server list.
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `Name` | string | World name displayed to players |
+| `Description` | string | World description (optional) |
+| `IP` | string | Override IP (leave empty to use Host setting) |
+| `Type` | number | World type: `1`=Normal, `2`=Cities, `3`=Newbie, `4`=Tavern, `5`=Return, `6`=MezFes |
+| `Recommended` | number | Recommendation status: `0`=None, `2`=Recommended, `6`=Special |
+| `AllowedClientFlags` | number | Client version flags (0 = all allowed) |
+| `Channels` | array | List of channel servers in this world |
+
+#### Channel Configuration
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `Port` | number | Channel server port (must be unique) |
+| `MaxPlayers` | number | Maximum players per channel |
+| `CurrentPlayers` | number | Current player count (auto-updated, can be set to 0) |
+
+**World Types Explained:**
+
+- **Newbie (Type 3)**: For new players, typically recommended
+- **Normal (Type 1)**: Standard gameplay world
+- **Cities (Type 2)**: Social/town areas
+- **Tavern (Type 4)**: Bar/tavern areas
+- **Return (Type 5)**: For returning players
+- **MezFes (Type 6)**: MezFes event world
+
+---
+
+## Complete Example
+
+Here's a minimal production-ready configuration:
+
+```json
+{
+ "Host": "",
+ "BinPath": "bin",
+ "Language": "en",
+ "DisableSoftCrash": true,
+ "HideLoginNotice": false,
+ "DevMode": false,
+ "DevModeOptions": {
+ "AutoCreateAccount": false
+ },
+ "GameplayOptions": {
+ "MaximumNP": 100000,
+ "MaximumRP": 50000
+ },
+ "Logging": {
+ "LogToFile": true,
+ "LogFilePath": "logs/erupe.log",
+ "LogMaxSize": 100,
+ "LogMaxBackups": 7,
+ "LogMaxAge": 30,
+ "LogCompress": true
+ },
+ "Discord": {
+ "Enabled": false
+ },
+ "Commands": [
+ {"Name": "Reload", "Enabled": true, "Prefix": "!reload"},
+ {"Name": "Course", "Enabled": true, "Prefix": "!course"}
+ ],
+ "Database": {
+ "Host": "localhost",
+ "Port": 5432,
+ "User": "erupe",
+ "Password": "CHANGE_ME",
+ "Database": "erupe"
+ },
+ "Sign": {
+ "Enabled": true,
+ "Port": 53312
+ },
+ "Channel": {
+ "Enabled": true
+ },
+ "Entrance": {
+ "Enabled": true,
+ "Port": 53310,
+ "Entries": [
+ {
+ "Name": "Main",
+ "Type": 1,
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 100 }
+ ]
+ }
+ ]
+ }
+}
+```
+
+---
+
+## Additional Resources
+
+- [CLAUDE.md](../CLAUDE.md) - Development guide
+- [config.example.json](../config.example.json) - Full example configuration
+- [Log Analyzer Tool](../tools/loganalyzer/) - Log analysis utilities
diff --git a/docs/courses.md b/docs/courses.md
new file mode 100644
index 000000000..30d781b3c
--- /dev/null
+++ b/docs/courses.md
@@ -0,0 +1,219 @@
+# Courses
+
+Subscription course configuration for Monster Hunter Frontier.
+
+## Configuration
+
+```json
+{
+ "Courses": [
+ {"Name": "HunterLife", "Enabled": true},
+ {"Name": "Extra", "Enabled": true},
+ {"Name": "Premium", "Enabled": true},
+ {"Name": "Assist", "Enabled": false},
+ {"Name": "N", "Enabled": false},
+ {"Name": "Hiden", "Enabled": false},
+ {"Name": "HunterSupport", "Enabled": false},
+ {"Name": "NBoost", "Enabled": false},
+ {"Name": "NetCafe", "Enabled": true},
+ {"Name": "HLRenewing", "Enabled": true},
+ {"Name": "EXRenewing", "Enabled": true}
+ ]
+}
+```
+
+## What Are Courses?
+
+Courses are subscription-based premium features in Monster Hunter Frontier, similar to premium subscriptions or season passes. Each course grants different benefits, bonuses, and access to content.
+
+## Course List
+
+| Course | Name | Description |
+|--------|------|-------------|
+| `HunterLife` | Hunter Life Course | Basic subscription with fundamental benefits |
+| `Extra` | Extra Course | Additional premium features and bonuses |
+| `Premium` | Premium Course | Premium-tier benefits and exclusive content |
+| `Assist` | Assist Course | Helper features for newer players |
+| `N` | N Course | Special N-series benefits |
+| `Hiden` | Hiden Course | Secret/hidden features and content |
+| `HunterSupport` | Hunter Support Course | Support features for hunters |
+| `NBoost` | N Boost Course | N-series boost benefits |
+| `NetCafe` | NetCafe Course | Internet cafe benefits (bonus rewards, boost time) |
+| `HLRenewing` | Hunter Life Renewing | Renewed Hunter Life benefits |
+| `EXRenewing` | Extra Renewing | Renewed Extra Course benefits |
+
+## How Courses Work
+
+### Enabled vs Disabled
+
+- **`Enabled: true`**: Players can toggle the course on/off using the `!course` command
+- **`Enabled: false`**: Course is locked and cannot be activated by players
+
+### Account Rights
+
+Courses are stored as a bitfield in the database (`users.rights` column). Each course has a unique bit position:
+
+```text
+Rights Bitfield:
+Bit 0: HunterLife
+Bit 1: Extra
+Bit 2: Premium
+... (and so on)
+```
+
+### Using the !course Command
+
+When the [!course command](commands.md#course) is enabled, players can toggle courses:
+
+```text
+Player types: !course premium
+Server: "Premium Course enabled!"
+
+Player types: !course premium
+Server: "Premium Course disabled!"
+```
+
+**Important:** Players can only toggle courses that are `Enabled: true` in the configuration.
+
+## Configuration Examples
+
+### Open Server (All Courses Available)
+
+```json
+{
+ "Courses": [
+ {"Name": "HunterLife", "Enabled": true},
+ {"Name": "Extra", "Enabled": true},
+ {"Name": "Premium", "Enabled": true},
+ {"Name": "Assist", "Enabled": true},
+ {"Name": "N", "Enabled": true},
+ {"Name": "Hiden", "Enabled": true},
+ {"Name": "HunterSupport", "Enabled": true},
+ {"Name": "NBoost", "Enabled": true},
+ {"Name": "NetCafe", "Enabled": true},
+ {"Name": "HLRenewing", "Enabled": true},
+ {"Name": "EXRenewing", "Enabled": true}
+ ]
+}
+```
+
+### Restricted Server (Core Courses Only)
+
+```json
+{
+ "Courses": [
+ {"Name": "HunterLife", "Enabled": true},
+ {"Name": "Extra", "Enabled": true},
+ {"Name": "Premium", "Enabled": false},
+ {"Name": "Assist", "Enabled": false},
+ {"Name": "N", "Enabled": false},
+ {"Name": "Hiden", "Enabled": false},
+ {"Name": "HunterSupport", "Enabled": false},
+ {"Name": "NBoost", "Enabled": false},
+ {"Name": "NetCafe", "Enabled": true},
+ {"Name": "HLRenewing", "Enabled": false},
+ {"Name": "EXRenewing", "Enabled": false}
+ ]
+}
+```
+
+### Free-to-Play Server (NetCafe Only)
+
+```json
+{
+ "Courses": [
+ {"Name": "HunterLife", "Enabled": false},
+ {"Name": "Extra", "Enabled": false},
+ {"Name": "Premium", "Enabled": false},
+ {"Name": "Assist", "Enabled": false},
+ {"Name": "N", "Enabled": false},
+ {"Name": "Hiden", "Enabled": false},
+ {"Name": "HunterSupport", "Enabled": false},
+ {"Name": "NBoost", "Enabled": false},
+ {"Name": "NetCafe", "Enabled": true},
+ {"Name": "HLRenewing", "Enabled": false},
+ {"Name": "EXRenewing", "Enabled": false}
+ ]
+}
+```
+
+## Course Benefits
+
+While Erupe emulates the course system, the exact benefits depend on game client implementation. Common benefits include:
+
+### HunterLife
+
+- Increased reward multipliers
+- Extra item box space
+- Access to HunterLife-exclusive quests
+
+### Extra
+
+- Additional bonus rewards
+- Extra carve/gather attempts
+- Special decorations and items
+
+### Premium
+
+- All HunterLife + Extra benefits
+- Premium-exclusive content
+- Enhanced reward rates
+
+### NetCafe
+
+- Boost time periods (see [Gameplay Options](gameplay-options.md))
+- Increased reward rates
+- NetCafe-exclusive bonuses
+
+## Setting Courses Manually
+
+### Via Database
+
+Directly modify the `users.rights` column:
+
+```sql
+-- Enable all courses for a user
+UPDATE users SET rights = 2047 WHERE username = 'player';
+
+-- Enable only HunterLife (bit 0 = 2^0 = 1)
+UPDATE users SET rights = 1 WHERE username = 'player';
+
+-- Enable HunterLife + Extra + NetCafe (bits 0, 1, 8 = 1 + 2 + 256 = 259)
+UPDATE users SET rights = 259 WHERE username = 'player';
+```
+
+### Via !rights Command
+
+If the [!rights command](commands.md#rights) is enabled:
+
+```text
+!rights 2047
+```
+
+Enables all courses (2047 = all 11 bits set).
+
+**Bitfield Calculator:**
+
+- HunterLife: 2^0 = 1
+- Extra: 2^1 = 2
+- Premium: 2^2 = 4
+- NetCafe: 2^8 = 256
+- Total: Add the values together
+
+## Implementation Details
+
+Course checking is implemented throughout the codebase:
+
+```go
+// Check if player has a specific course
+if mhfcourse.CourseExists(courseID, session.courses) {
+ // Grant course benefits
+}
+```
+
+Course data is loaded from the database on character login and cached in the session.
+
+## Related Documentation
+
+- [In-Game Commands](commands.md) - Using `!course` command
+- [Gameplay Options](gameplay-options.md) - NetCafe boost time configuration
diff --git a/docs/database.md b/docs/database.md
new file mode 100644
index 000000000..73ee0682c
--- /dev/null
+++ b/docs/database.md
@@ -0,0 +1,409 @@
+# Database Configuration
+
+PostgreSQL database configuration and setup for Erupe.
+
+## Configuration
+
+```json
+{
+ "Database": {
+ "Host": "localhost",
+ "Port": 5432,
+ "User": "postgres",
+ "Password": "",
+ "Database": "erupe"
+ }
+}
+```
+
+## Settings Reference
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `Host` | string | `"localhost"` | Database host address |
+| `Port` | number | `5432` | PostgreSQL port |
+| `User` | string | `"postgres"` | Database user |
+| `Password` | string | *required* | Database password (must not be empty) |
+| `Database` | string | `"erupe"` | Database name |
+
+**Important:** The `Password` field must not be empty. The server will refuse to start if the password is blank.
+
+## Initial Setup
+
+### 1. Install PostgreSQL
+
+**Ubuntu/Debian:**
+
+```bash
+sudo apt update
+sudo apt install postgresql postgresql-contrib
+```
+
+**macOS (Homebrew):**
+
+```bash
+brew install postgresql
+brew services start postgresql
+```
+
+**Windows:**
+Download and install from [postgresql.org](https://www.postgresql.org/download/windows/)
+
+### 2. Create Database User
+
+```bash
+# Switch to postgres user
+sudo -u postgres psql
+
+# Create user with password
+CREATE USER erupe WITH PASSWORD 'your_secure_password';
+
+# Grant privileges
+ALTER USER erupe CREATEDB;
+
+# Exit psql
+\q
+```
+
+### 3. Create Database
+
+```bash
+# Create database
+createdb -U erupe erupe
+
+# Or via psql
+psql -U postgres
+CREATE DATABASE erupe OWNER erupe;
+\q
+```
+
+### 4. Apply Schema
+
+From the Erupe root directory:
+
+```bash
+# Apply initial schema (bootstraps to version 9.1.0)
+psql -U erupe -d erupe -f schemas/schema.sql
+```
+
+### 5. Apply Patches (Development Branch)
+
+If using the development branch, apply patch schemas in order:
+
+```bash
+# Apply patches sequentially
+psql -U erupe -d erupe -f patch-schema/01_patch.sql
+psql -U erupe -d erupe -f patch-schema/02_patch.sql
+# ... continue in order
+```
+
+**Note:** Patch schemas are development updates and may change. They get consolidated into update schemas on release.
+
+### 6. (Optional) Load Bundled Data
+
+Load demo data for shops, events, and gacha:
+
+```bash
+psql -U erupe -d erupe -f schemas/bundled-schema/shops.sql
+psql -U erupe -d erupe -f schemas/bundled-schema/events.sql
+psql -U erupe -d erupe -f schemas/bundled-schema/gacha.sql
+```
+
+## Schema Management
+
+Erupe uses a multi-tiered schema system:
+
+### Schema Types
+
+1. **Initialization Schema** (`schemas/schema.sql`)
+ - Bootstraps database to version 9.1.0
+ - Creates all tables, indexes, and base data
+ - Use for fresh installations
+
+2. **Patch Schemas** (`patch-schema/*.sql`)
+ - Development-time updates
+ - Numbered sequentially (01, 02, 03...)
+ - Applied in order during active development
+ - **May change during development cycle**
+
+3. **Update Schemas** (for releases)
+ - Production-ready consolidated updates
+ - Stable and tested
+ - Created when patches are finalized for release
+
+4. **Bundled Schemas** (`schemas/bundled-schema/*.sql`)
+ - Optional demo/template data
+ - Shops, events, gacha pools
+ - Not required but helpful for testing
+
+### Applying Schemas
+
+**Fresh Installation:**
+
+```bash
+psql -U erupe -d erupe -f schemas/schema.sql
+```
+
+**Development (with patches):**
+
+```bash
+# First apply base schema
+psql -U erupe -d erupe -f schemas/schema.sql
+
+# Then apply patches in order
+for patch in patch-schema/*.sql; do
+ psql -U erupe -d erupe -f "$patch"
+done
+```
+
+**With Password:**
+
+```bash
+PGPASSWORD='your_password' psql -U erupe -d erupe -f schema.sql
+```
+
+## Configuration Examples
+
+### Local Development
+
+```json
+{
+ "Database": {
+ "Host": "localhost",
+ "Port": 5432,
+ "User": "postgres",
+ "Password": "dev_password",
+ "Database": "erupe_dev"
+ }
+}
+```
+
+### Production (Dedicated Database Server)
+
+```json
+{
+ "Database": {
+ "Host": "db.example.com",
+ "Port": 5432,
+ "User": "erupe",
+ "Password": "very_secure_password_here",
+ "Database": "erupe_production"
+ }
+}
+```
+
+### Docker Container
+
+```json
+{
+ "Database": {
+ "Host": "db",
+ "Port": 5432,
+ "User": "postgres",
+ "Password": "docker_password",
+ "Database": "erupe"
+ }
+}
+```
+
+The `Host: "db"` refers to the Docker Compose service name.
+
+## Docker Setup
+
+Using Docker Compose (see `docker-compose.yml`):
+
+```yaml
+services:
+ db:
+ image: postgres:13
+ environment:
+ POSTGRES_PASSWORD: test
+ POSTGRES_DB: erupe
+ ports:
+ - "5432:5432"
+ volumes:
+ - pgdata:/var/lib/postgresql/data
+```
+
+Start database:
+
+```bash
+docker compose up db
+```
+
+Apply schema to Docker database:
+
+```bash
+docker compose exec db psql -U postgres -d erupe -f /path/to/schema.sql
+```
+
+## Database Maintenance
+
+### Backup Database
+
+```bash
+# Full backup
+pg_dump -U erupe erupe > erupe_backup.sql
+
+# Compressed backup
+pg_dump -U erupe erupe | gzip > erupe_backup.sql.gz
+
+# With password
+PGPASSWORD='password' pg_dump -U erupe erupe > backup.sql
+```
+
+### Restore Database
+
+```bash
+# Drop and recreate database
+dropdb -U erupe erupe
+createdb -U erupe erupe
+
+# Restore from backup
+psql -U erupe -d erupe -f erupe_backup.sql
+
+# From compressed backup
+gunzip -c erupe_backup.sql.gz | psql -U erupe -d erupe
+```
+
+### Clean Database (Development)
+
+```bash
+# Connect to database
+psql -U erupe -d erupe
+
+-- Delete all user data
+DELETE FROM guild_characters;
+DELETE FROM guilds;
+DELETE FROM characters;
+DELETE FROM sign_sessions;
+DELETE FROM users;
+
+-- Exit
+\q
+```
+
+Or use `CleanDB: true` in [Development Mode](development-mode.md) (⚠️ destructive!).
+
+### Check Database Size
+
+```bash
+psql -U erupe -d erupe -c "SELECT pg_size_pretty(pg_database_size('erupe'));"
+```
+
+### Vacuum Database
+
+Reclaim space and optimize:
+
+```bash
+psql -U erupe -d erupe -c "VACUUM ANALYZE;"
+```
+
+## Troubleshooting
+
+### Connection Refused
+
+**Error:** `could not connect to server: Connection refused`
+
+**Solutions:**
+
+- Verify PostgreSQL is running: `sudo systemctl status postgresql`
+- Check port is correct: `5432` (default)
+- Verify host is accessible
+- Check firewall rules
+
+### Authentication Failed
+
+**Error:** `password authentication failed for user "erupe"`
+
+**Solutions:**
+
+- Verify password is correct in config
+- Check `pg_hba.conf` authentication method
+- Ensure user exists: `psql -U postgres -c "\du"`
+
+### Database Does Not Exist
+
+**Error:** `database "erupe" does not exist`
+
+**Solutions:**
+
+- Create database: `createdb -U erupe erupe`
+- Verify database name matches config
+
+### Permission Denied
+
+**Error:** `permission denied for table users`
+
+**Solutions:**
+
+```sql
+-- Grant all privileges on database
+GRANT ALL PRIVILEGES ON DATABASE erupe TO erupe;
+
+-- Grant all privileges on all tables
+GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO erupe;
+```
+
+### Schema Version Mismatch
+
+**Error:** Server starts but data doesn't load properly
+
+**Solutions:**
+
+- Check if all patches were applied in order
+- Verify schema version in database
+- Re-apply missing patches
+
+## Security Best Practices
+
+1. **Use Strong Passwords**: Never use default or weak passwords
+2. **Limit Network Access**: Use firewall rules to restrict database access
+3. **Don't Expose PostgreSQL Publicly**: Only allow connections from Erupe server
+4. **Use SSL/TLS**: Enable SSL for production databases
+5. **Regular Backups**: Automate daily backups
+6. **Separate Users**: Don't use `postgres` superuser for Erupe
+
+## Performance Tuning
+
+For larger servers, optimize PostgreSQL:
+
+### Connection Pooling
+
+Consider using PgBouncer for connection pooling:
+
+```bash
+sudo apt install pgbouncer
+```
+
+### PostgreSQL Configuration
+
+Edit `/etc/postgresql/13/main/postgresql.conf`:
+
+```conf
+# Increase shared buffers (25% of RAM)
+shared_buffers = 2GB
+
+# Increase work memory
+work_mem = 16MB
+
+# Increase maintenance work memory
+maintenance_work_mem = 512MB
+
+# Enable query logging (development)
+log_statement = 'all'
+log_duration = on
+```
+
+Restart PostgreSQL:
+
+```bash
+sudo systemctl restart postgresql
+```
+
+## Related Documentation
+
+- [Basic Settings](basic-settings.md) - Basic server configuration
+- [Development Mode](development-mode.md) - CleanDB option
+- [Server Configuration](server-configuration.md) - Server setup
+- [CLAUDE.md](../CLAUDE.md#database-operations) - Database operations guide
diff --git a/docs/development-mode.md b/docs/development-mode.md
new file mode 100644
index 000000000..ea0469787
--- /dev/null
+++ b/docs/development-mode.md
@@ -0,0 +1,166 @@
+# Development Mode
+
+Development mode configuration for testing and debugging Erupe.
+
+## Configuration
+
+```json
+{
+ "DevMode": true,
+ "DevModeOptions": {
+ "AutoCreateAccount": true,
+ "CleanDB": false,
+ "MaxLauncherHR": false,
+ "LogInboundMessages": false,
+ "LogOutboundMessages": false,
+ "MaxHexdumpLength": 256,
+ "DivaEvent": 0,
+ "FestaEvent": -1,
+ "TournamentEvent": 0,
+ "MezFesEvent": true,
+ "MezFesAlt": false,
+ "DisableTokenCheck": false,
+ "QuestDebugTools": false,
+ "SaveDumps": {
+ "Enabled": true,
+ "OutputDir": "savedata"
+ }
+ }
+}
+```
+
+## Settings Reference
+
+### DevMode
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `DevMode` | boolean | `false` | Enables development mode (more verbose logging, development logger format) |
+
+When `DevMode` is enabled:
+
+- Logging uses console format (human-readable) instead of JSON
+- More detailed stack traces on errors
+- Development-friendly output
+
+### DevModeOptions
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `AutoCreateAccount` | boolean | `false` | **⚠️ SECURITY RISK**: Auto-create accounts on login (disable in production) |
+| `CleanDB` | boolean | `false` | **⚠️ DESTRUCTIVE**: Wipes database on server start (deletes all users, characters, guilds) |
+| `MaxLauncherHR` | boolean | `false` | Sets launcher HR to HR7 to join non-beginner worlds |
+| `LogInboundMessages` | boolean | `false` | Log all packets received from clients (very verbose) |
+| `LogOutboundMessages` | boolean | `false` | Log all packets sent to clients (very verbose) |
+| `MaxHexdumpLength` | number | `256` | Maximum bytes to display in packet hexdumps |
+| `DivaEvent` | number | `0` | Diva Defense event status (0 = off, higher = active) |
+| `FestaEvent` | number | `-1` | Hunter's Festa event status (-1 = off, higher = active) |
+| `TournamentEvent` | number | `0` | VS Tournament event status (0 = off, higher = active) |
+| `MezFesEvent` | boolean | `false` | Enable/disable MezFes event |
+| `MezFesAlt` | boolean | `false` | Swap Volpakkun for Tokotoko in MezFes |
+| `DisableTokenCheck` | boolean | `false` | **⚠️ SECURITY RISK**: Skip login token validation |
+| `QuestDebugTools` | boolean | `false` | Enable quest debugging logs |
+
+### Save Dumps
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `SaveDumps.Enabled` | boolean | `false` | Enable saving character data dumps for analysis |
+| `SaveDumps.OutputDir` | string | `"savedata"` | Directory for save data dumps |
+
+## Security Warnings
+
+### AutoCreateAccount
+
+**Never enable in production!** This setting allows anyone to create an account by simply trying to log in with any username. This is convenient for development but a major security risk for public servers.
+
+### CleanDB
+
+**Extremely destructive!** This setting wipes all user data from the database on every server restart. Only use for rapid testing cycles in isolated development environments.
+
+### DisableTokenCheck
+
+**Security vulnerability!** Bypasses login token validation, allowing unauthorized access. Only use in isolated development environments.
+
+## Packet Logging
+
+When debugging network issues, enable packet logging:
+
+```json
+{
+ "DevModeOptions": {
+ "LogInboundMessages": true,
+ "LogOutboundMessages": true,
+ "MaxHexdumpLength": 512
+ }
+}
+```
+
+**Warning:** This generates **massive** log files very quickly. Only enable when actively debugging specific packet issues.
+
+## Event Testing
+
+Test special events by enabling them:
+
+```json
+{
+ "DevModeOptions": {
+ "DivaEvent": 1,
+ "FestaEvent": 0,
+ "TournamentEvent": 1,
+ "MezFesEvent": true,
+ "MezFesAlt": false
+ }
+}
+```
+
+## Examples
+
+### Safe Development Configuration
+
+```json
+{
+ "DevMode": true,
+ "DevModeOptions": {
+ "AutoCreateAccount": true,
+ "CleanDB": false,
+ "MaxLauncherHR": true,
+ "QuestDebugTools": true,
+ "SaveDumps": {
+ "Enabled": true,
+ "OutputDir": "savedata"
+ }
+ }
+}
+```
+
+### Production Configuration
+
+```json
+{
+ "DevMode": false,
+ "DevModeOptions": {
+ "AutoCreateAccount": false,
+ "CleanDB": false,
+ "DisableTokenCheck": false
+ }
+}
+```
+
+### Packet Debugging Configuration
+
+```json
+{
+ "DevMode": true,
+ "DevModeOptions": {
+ "LogInboundMessages": true,
+ "LogOutboundMessages": true,
+ "MaxHexdumpLength": 1024
+ }
+}
+```
+
+## Related Documentation
+
+- [Logging](logging.md) - Logging configuration
+- [Basic Settings](basic-settings.md) - Basic server settings
diff --git a/docs/discord-integration.md b/docs/discord-integration.md
new file mode 100644
index 000000000..d26d80807
--- /dev/null
+++ b/docs/discord-integration.md
@@ -0,0 +1,199 @@
+# Discord Integration
+
+Real-time Discord bot integration for posting server activity to Discord channels.
+
+## Configuration
+
+```json
+{
+ "Discord": {
+ "Enabled": false,
+ "BotToken": "",
+ "RealtimeChannelID": ""
+ }
+}
+```
+
+## Settings Reference
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable Discord integration |
+| `BotToken` | string | Discord bot token from Discord Developer Portal |
+| `RealtimeChannelID` | string | Discord channel ID where activity messages will be posted |
+
+## How It Works
+
+When enabled, the Discord bot:
+
+1. **Connects on Server Startup**: The bot authenticates using the provided bot token
+2. **Monitors Game Activity**: Listens for in-game chat messages and events
+3. **Posts to Discord**: Sends formatted messages to the specified channel
+
+### What Gets Posted
+
+- Player chat messages (when sent to world/server chat)
+- Player connection/disconnection events
+- Quest completions
+- Special event notifications
+
+### Message Format
+
+Messages are posted in this format:
+
+```text
+**PlayerName**: Hello everyone!
+```
+
+Discord mentions and emojis in messages are normalized for proper display.
+
+## Setup Instructions
+
+### 1. Create a Discord Bot
+
+1. Go to [Discord Developer Portal](https://discord.com/developers/applications)
+2. Click "New Application"
+3. Give your application a name (e.g., "Erupe Server Bot")
+4. Go to the "Bot" section in the left sidebar
+5. Click "Add Bot"
+6. Under the bot's username, click "Reset Token" to reveal your bot token
+7. **Copy this token** - you'll need it for the config
+
+**Important:** Keep your bot token secret! Anyone with this token can control your bot.
+
+### 2. Get Channel ID
+
+1. Enable Developer Mode in Discord:
+ - User Settings → Advanced → Developer Mode (toggle on)
+2. Right-click the channel where you want bot messages
+3. Click "Copy ID"
+4. This is your `RealtimeChannelID`
+
+### 3. Add Bot to Your Server
+
+1. In Discord Developer Portal, go to OAuth2 → URL Generator
+2. Select scopes:
+ - `bot`
+3. Select bot permissions:
+ - `Send Messages`
+ - `Read Message History`
+4. Copy the generated URL at the bottom
+5. Paste the URL in your browser and select your Discord server
+6. Click "Authorize"
+
+### 4. Configure Erupe
+
+Edit your `config.json`:
+
+```json
+{
+ "Discord": {
+ "Enabled": true,
+ "BotToken": "YOUR_BOT_TOKEN_HERE",
+ "RealtimeChannelID": "YOUR_CHANNEL_ID_HERE"
+ }
+}
+```
+
+### 5. Start Erupe
+
+The bot will connect automatically on server startup. You should see:
+
+```text
+INFO Discord bot connected successfully
+```
+
+## Example Configuration
+
+```json
+{
+ "Discord": {
+ "Enabled": true,
+ "BotToken": "MTIzNDU2Nzg5MDEyMzQ1Njc4OQ.AbCdEf.GhIjKlMnOpQrStUvWxYz123456789",
+ "RealtimeChannelID": "987654321098765432"
+ }
+}
+```
+
+## Implementation Details
+
+- **Bot Code**: [server/discordbot/discord_bot.go](../server/discordbot/discord_bot.go)
+- **Library**: Uses [discordgo](https://github.com/bwmarrin/discordgo)
+- **Message Normalization**: Discord mentions (`<@123456>`) and emojis (`:emoji:`) are normalized
+- **Error Handling**: Non-blocking - errors are logged but don't crash the server
+- **Threading**: Bot runs in a separate goroutine
+
+## Troubleshooting
+
+### Bot doesn't connect
+
+**Error:** `Discord failed to create realtimeChannel`
+
+**Solutions:**
+
+- Verify the `RealtimeChannelID` is correct
+- Ensure the bot has been added to your server
+- Check that the bot has permission to read the channel
+
+### Bot connects but doesn't post messages
+
+**Solutions:**
+
+- Verify the bot has `Send Messages` permission in the channel
+- Check channel permissions - the bot's role must have access
+- Look for error messages in server logs
+
+### Invalid token error
+
+**Error:** `Discord failed: authentication failed`
+
+**Solutions:**
+
+- Regenerate the bot token in Discord Developer Portal
+- Copy the entire token, including any special characters
+- Ensure no extra spaces in the config file
+
+### Bot posts but messages are blank
+
+**Issue:** Message normalization may be failing
+
+**Solution:**
+
+- Check server logs for Discord-related errors
+- Verify game chat is being sent to world/server chat, not private chat
+
+## Security Considerations
+
+1. **Never commit your bot token** - Add `config.json` to `.gitignore`
+2. **Regenerate compromised tokens** - If your token is exposed, regenerate immediately
+3. **Limit bot permissions** - Only grant necessary permissions
+4. **Monitor bot activity** - Check for unusual posting patterns
+
+## Advanced Usage
+
+### Multiple Channels
+
+Currently, Erupe supports posting to a single channel. To post to multiple channels, you would need to modify the bot code.
+
+### Custom Message Formatting
+
+To customize message formatting, edit [sys_channel_server.go:354](../server/channelserver/sys_channel_server.go#L354):
+
+```go
+func (s *Server) DiscordChannelSend(charName string, content string) {
+ if s.erupeConfig.Discord.Enabled && s.discordBot != nil {
+ // Customize this format
+ message := fmt.Sprintf("**%s**: %s", charName, content)
+ s.discordBot.RealtimeChannelSend(message)
+ }
+}
+```
+
+### Webhook Alternative
+
+For simpler one-way messaging, consider using Discord webhooks instead of a full bot. This would require code modifications but wouldn't need bot creation/permissions.
+
+## Related Documentation
+
+- [In-Game Commands](commands.md) - Chat commands that may trigger Discord posts
+- [Logging](logging.md) - Server logging configuration
diff --git a/docs/gameplay-options.md b/docs/gameplay-options.md
new file mode 100644
index 000000000..c7bd2951c
--- /dev/null
+++ b/docs/gameplay-options.md
@@ -0,0 +1,161 @@
+# Gameplay Options
+
+Gameplay modifiers and balance settings for Erupe.
+
+## Configuration
+
+```json
+{
+ "GameplayOptions": {
+ "FeaturedWeapons": 1,
+ "MaximumNP": 100000,
+ "MaximumRP": 50000,
+ "DisableLoginBoost": false,
+ "DisableBoostTime": false,
+ "BoostTimeDuration": 120,
+ "GuildMealDuration": 60,
+ "BonusQuestAllowance": 3,
+ "DailyQuestAllowance": 1
+ }
+}
+```
+
+## Settings Reference
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `FeaturedWeapons` | number | `1` | Number of Active Feature weapons generated daily |
+| `MaximumNP` | number | `100000` | Maximum Network Points (NP) a player can hold |
+| `MaximumRP` | number | `50000` | Maximum Road Points (RP) a player can hold |
+| `DisableLoginBoost` | boolean | `false` | Disable login boost system entirely |
+| `DisableBoostTime` | boolean | `false` | Disable daily NetCafe boost time |
+| `BoostTimeDuration` | number | `120` | NetCafe boost time duration in minutes |
+| `GuildMealDuration` | number | `60` | Guild meal activation duration in minutes |
+| `BonusQuestAllowance` | number | `3` | Daily Bonus Point Quest allowance |
+| `DailyQuestAllowance` | number | `1` | Daily Quest allowance |
+
+## Detailed Explanations
+
+### Featured Weapons
+
+Featured/Active Feature weapons are special weapon variants with unique properties. This setting controls how many are generated and available each day.
+
+- Set to `0` to disable featured weapons
+- Set to `1`-`3` for normal operation
+- Higher values generate more variety
+
+### Network Points (NP) and Road Points (RP)
+
+NP and RP are in-game currencies/points used for various purchases and progression:
+
+- **Network Points (NP)**: Used for purchasing items, materials, and services
+- **Road Points (RP)**: Used for unlocking road/progression rewards
+
+**Default Caps:**
+
+- NP: `100,000`
+- RP: `50,000`
+
+You can increase these caps for more relaxed gameplay or decrease them to maintain balance.
+
+### Boost Systems
+
+Monster Hunter Frontier has several boost systems that increase rewards and experience:
+
+#### Login Boost
+
+Automatically granted when logging in. Disable with `DisableLoginBoost: true`.
+
+#### NetCafe Boost Time
+
+Daily time-limited boost that simulates NetCafe benefits:
+
+```json
+{
+ "DisableBoostTime": false,
+ "BoostTimeDuration": 120
+}
+```
+
+- `DisableBoostTime: false` - Boost time is active
+- `BoostTimeDuration: 120` - Lasts 120 minutes (2 hours)
+
+### Guild Meals
+
+Guild meals are buffs that guild members can activate:
+
+```json
+{
+ "GuildMealDuration": 60
+}
+```
+
+Duration in minutes after cooking before the meal expires.
+
+### Quest Allowances
+
+Daily limits for special quest types:
+
+- **BonusQuestAllowance**: Number of Bonus Point Quests per day
+- **DailyQuestAllowance**: Number of Daily Quests per day
+
+Set to `0` to disable limits entirely.
+
+## Examples
+
+### Casual/Relaxed Server
+
+```json
+{
+ "GameplayOptions": {
+ "FeaturedWeapons": 3,
+ "MaximumNP": 999999,
+ "MaximumRP": 999999,
+ "DisableLoginBoost": false,
+ "DisableBoostTime": false,
+ "BoostTimeDuration": 240,
+ "GuildMealDuration": 120,
+ "BonusQuestAllowance": 10,
+ "DailyQuestAllowance": 5
+ }
+}
+```
+
+### Balanced Server (Default)
+
+```json
+{
+ "GameplayOptions": {
+ "FeaturedWeapons": 1,
+ "MaximumNP": 100000,
+ "MaximumRP": 50000,
+ "DisableLoginBoost": false,
+ "DisableBoostTime": false,
+ "BoostTimeDuration": 120,
+ "GuildMealDuration": 60,
+ "BonusQuestAllowance": 3,
+ "DailyQuestAllowance": 1
+ }
+}
+```
+
+### Hardcore/Challenge Server
+
+```json
+{
+ "GameplayOptions": {
+ "FeaturedWeapons": 0,
+ "MaximumNP": 50000,
+ "MaximumRP": 25000,
+ "DisableLoginBoost": true,
+ "DisableBoostTime": true,
+ "BonusQuestAllowance": 1,
+ "DailyQuestAllowance": 1
+ }
+}
+```
+
+## Related Documentation
+
+- [Courses](courses.md) - Subscription course configuration
+- [In-Game Commands](commands.md) - Player commands
diff --git a/docs/logging.md b/docs/logging.md
new file mode 100644
index 000000000..7126a5a7f
--- /dev/null
+++ b/docs/logging.md
@@ -0,0 +1,201 @@
+# Logging Configuration
+
+File logging and log rotation configuration for Erupe.
+
+## Configuration
+
+```json
+{
+ "Logging": {
+ "LogToFile": true,
+ "LogFilePath": "logs/erupe.log",
+ "LogMaxSize": 100,
+ "LogMaxBackups": 3,
+ "LogMaxAge": 28,
+ "LogCompress": true
+ }
+}
+```
+
+## Settings Reference
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `LogToFile` | boolean | `true` | Enable file logging (logs to both console and file) |
+| `LogFilePath` | string | `"logs/erupe.log"` | Path to log file (directory will be created automatically) |
+| `LogMaxSize` | number | `100` | Maximum log file size in MB before rotation |
+| `LogMaxBackups` | number | `3` | Number of old log files to keep |
+| `LogMaxAge` | number | `28` | Maximum days to retain old logs |
+| `LogCompress` | boolean | `true` | Compress rotated log files with gzip |
+
+## How It Works
+
+Erupe uses [lumberjack](https://github.com/natefinch/lumberjack) for automatic log rotation and compression.
+
+### Log Rotation
+
+When the current log file reaches `LogMaxSize` MB:
+
+1. Current log is closed and renamed to `erupe.log.YYYY-MM-DD-HH-MM-SS`
+2. If `LogCompress: true`, the old log is compressed to `.gz` format
+3. A new `erupe.log` file is created
+4. Old logs beyond `LogMaxBackups` count are deleted
+5. Logs older than `LogMaxAge` days are deleted
+
+### Example Log Files
+
+```text
+logs/
+├── erupe.log (current, 45 MB)
+├── erupe.log.2025-11-17-14-23-45.gz (100 MB compressed)
+├── erupe.log.2025-11-16-08-15-32.gz (100 MB compressed)
+└── erupe.log.2025-11-15-19-42-18.gz (100 MB compressed)
+```
+
+## Log Format
+
+Log format depends on `DevMode` setting:
+
+### Development Mode (DevMode: true)
+
+Console format (human-readable):
+
+```text
+2025-11-18T10:30:45.123Z INFO channelserver Player connected {"charID": 12345, "ip": "127.0.0.1"}
+2025-11-18T10:30:46.456Z ERROR channelserver Failed to load data {"error": "database timeout"}
+```
+
+### Production Mode (DevMode: false)
+
+JSON format (machine-parsable):
+
+```json
+{"level":"info","ts":"2025-11-18T10:30:45.123Z","logger":"channelserver","msg":"Player connected","charID":12345,"ip":"127.0.0.1"}
+{"level":"error","ts":"2025-11-18T10:30:46.456Z","logger":"channelserver","msg":"Failed to load data","error":"database timeout"}
+```
+
+## Log Analysis
+
+Erupe includes a built-in log analyzer tool in `tools/loganalyzer/`:
+
+```bash
+# Filter by log 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 monitoring
+./loganalyzer tail -f ../../logs/erupe.log -level error
+
+# Generate statistics
+./loganalyzer stats -f ../../logs/erupe.log -detailed
+```
+
+See [CLAUDE.md](../CLAUDE.md#log-analysis) for more details.
+
+## Examples
+
+### Minimal Logging (Development)
+
+```json
+{
+ "Logging": {
+ "LogToFile": false
+ }
+}
+```
+
+Only logs to console, no file logging.
+
+### Standard Production Logging
+
+```json
+{
+ "Logging": {
+ "LogToFile": true,
+ "LogFilePath": "logs/erupe.log",
+ "LogMaxSize": 100,
+ "LogMaxBackups": 7,
+ "LogMaxAge": 30,
+ "LogCompress": true
+ }
+}
+```
+
+Keeps up to 7 log files, 30 days maximum, compressed.
+
+### High-Volume Server
+
+```json
+{
+ "Logging": {
+ "LogToFile": true,
+ "LogFilePath": "/var/log/erupe/erupe.log",
+ "LogMaxSize": 500,
+ "LogMaxBackups": 14,
+ "LogMaxAge": 60,
+ "LogCompress": true
+ }
+}
+```
+
+Larger log files (500 MB), more backups (14), longer retention (60 days).
+
+### Debug/Testing (No Rotation)
+
+```json
+{
+ "Logging": {
+ "LogToFile": true,
+ "LogFilePath": "logs/debug.log",
+ "LogMaxSize": 1000,
+ "LogMaxBackups": 0,
+ "LogMaxAge": 0,
+ "LogCompress": false
+ }
+}
+```
+
+Single large log file, no rotation, no compression. Useful for debugging sessions.
+
+## Disk Space Considerations
+
+Calculate approximate disk usage:
+
+```text
+Total Disk Usage = (LogMaxSize × LogMaxBackups) × CompressionRatio
+```
+
+**Compression ratios:**
+
+- Text logs: ~10:1 (100 MB → 10 MB compressed)
+- JSON logs: ~8:1 (100 MB → 12.5 MB compressed)
+
+**Example:**
+
+```text
+LogMaxSize: 100 MB
+LogMaxBackups: 7
+Compression: enabled (~10:1 ratio)
+
+Total: (100 MB × 7) / 10 = 70 MB (approximately)
+```
+
+## Best Practices
+
+1. **Enable compression** - Saves significant disk space
+2. **Set reasonable MaxSize** - 100-200 MB works well for most servers
+3. **Adjust retention** - Keep logs for at least 7 days, preferably 30
+4. **Use absolute paths in production** - `/var/log/erupe/erupe.log` instead of `logs/erupe.log`
+5. **Monitor disk space** - Set up alerts if disk usage exceeds 80%
+6. **Use JSON format in production** - Easier to parse with log analysis tools
+
+## Related Documentation
+
+- [Development Mode](development-mode.md) - DevMode affects log format
+- [Basic Settings](basic-settings.md) - Basic server configuration
+- [CLAUDE.md](../CLAUDE.md#log-analysis) - Log analyzer tool usage
diff --git a/docs/server-configuration.md b/docs/server-configuration.md
new file mode 100644
index 000000000..d18bf124f
--- /dev/null
+++ b/docs/server-configuration.md
@@ -0,0 +1,445 @@
+# Server Configuration
+
+Configuration for Erupe's three-server architecture: Sign, Entrance, and Channel servers.
+
+## Three-Server Architecture
+
+Erupe uses a multi-server architecture that mirrors the original Monster Hunter Frontier server design:
+
+```
+Client → Sign Server (Auth) → Entrance Server (World List) → Channel Server (Gameplay)
+```
+
+1. **Sign Server**: Authentication and account management
+2. **Entrance Server**: World/server selection and character list
+3. **Channel Servers**: Actual gameplay sessions, quests, and player interactions
+
+## Sign Server
+
+Handles authentication and account management.
+
+### Configuration
+
+```json
+{
+ "Sign": {
+ "Enabled": true,
+ "Port": 53312
+ }
+}
+```
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `Enabled` | boolean | `true` | Enable the legacy sign server |
+| `Port` | number | `53312` | Port for sign server (client default: 53312) |
+
+### Details
+
+- Located in [server/signserver/](../server/signserver/)
+- Creates sign sessions with tokens for channel server authentication
+- Legacy TCP-based protocol
+- Required unless using SignV2
+
+## SignV2 Server
+
+Modern HTTP-based sign server (alternative to legacy sign server).
+
+### Configuration
+
+```json
+{
+ "SignV2": {
+ "Enabled": false,
+ "Port": 8080
+ }
+}
+```
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `Enabled` | boolean | `false` | Enable the modern HTTP-based sign server |
+| `Port` | number | `8080` | Port for SignV2 server |
+
+### Details
+
+- Located in [server/signv2server/](../server/signv2server/)
+- HTTP-based authentication (easier to proxy/load balance)
+- Alternative to legacy sign server
+- **Only enable one sign server at a time** (Sign OR SignV2, not both)
+
+## Channel Server
+
+Handles actual gameplay sessions, quests, and player interactions.
+
+### Configuration
+
+```json
+{
+ "Channel": {
+ "Enabled": true
+ }
+}
+```
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `Enabled` | boolean | `true` | Enable channel servers (required for gameplay) |
+
+### Details
+
+- Located in [server/channelserver/](../server/channelserver/)
+- Most complex component - handles all gameplay logic
+- Multiple instances can run simultaneously
+- Ports configured in Entrance server entries
+- Features:
+ - Session management
+ - Packet handling
+ - Stage/room system
+ - Quest system
+ - Guild operations
+ - Special events (Raviente, Diva Defense, etc.)
+
+See [CLAUDE.md](../CLAUDE.md#channel-server-internal-architecture) for detailed architecture.
+
+## Entrance Server
+
+Manages world/server selection and character lists.
+
+### Configuration
+
+```json
+{
+ "Entrance": {
+ "Enabled": true,
+ "Port": 53310,
+ "Entries": [
+ {
+ "Name": "Newbie",
+ "Description": "",
+ "IP": "",
+ "Type": 3,
+ "Recommended": 2,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 100 },
+ { "Port": 54002, "MaxPlayers": 100 }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Settings Reference
+
+| Setting | Type | Description |
+|---------|------|-------------|
+| `Enabled` | boolean | Enable entrance server (required for server list) |
+| `Port` | number | Entrance server port (default: 53310) |
+| `Entries` | array | List of worlds/servers shown to players |
+
+### Entrance Entries
+
+Each entry represents a "world" in the server list.
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `Name` | string | World name displayed to players (e.g., "Newbie", "Normal") |
+| `Description` | string | World description (optional, usually empty) |
+| `IP` | string | Override IP address (leave empty to use global `Host` setting) |
+| `Type` | number | World type (see below) |
+| `Recommended` | number | Recommendation badge: `0`=None, `2`=Recommended, `6`=Special |
+| `AllowedClientFlags` | number | Client version flags (0 = all versions allowed) |
+| `Channels` | array | List of channel servers in this world |
+
+### World Types
+
+| Type | Name | Purpose |
+|------|------|---------|
+| `1` | Normal | Standard gameplay world |
+| `2` | Cities | Social/town areas |
+| `3` | Newbie | For new players (typically recommended) |
+| `4` | Tavern | Bar/tavern areas |
+| `5` | Return | For returning players |
+| `6` | MezFes | MezFes event world |
+
+### Channel Configuration
+
+Each world has multiple channels (like "servers" within a "world"):
+
+```json
+{
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 100 },
+ { "Port": 54002, "MaxPlayers": 100 }
+ ]
+}
+```
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `Port` | number | Channel server port (must be unique across all channels) |
+| `MaxPlayers` | number | Maximum players allowed in this channel |
+| `CurrentPlayers` | number | Current player count (auto-updated at runtime) |
+
+## Complete Server Configurations
+
+### Minimal Setup (Single World, Single Channel)
+
+```json
+{
+ "Sign": {
+ "Enabled": true,
+ "Port": 53312
+ },
+ "SignV2": {
+ "Enabled": false
+ },
+ "Channel": {
+ "Enabled": true
+ },
+ "Entrance": {
+ "Enabled": true,
+ "Port": 53310,
+ "Entries": [
+ {
+ "Name": "Main",
+ "Type": 1,
+ "Recommended": 0,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 100 }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Standard Setup (Multiple Worlds)
+
+```json
+{
+ "Sign": {
+ "Enabled": true,
+ "Port": 53312
+ },
+ "Channel": {
+ "Enabled": true
+ },
+ "Entrance": {
+ "Enabled": true,
+ "Port": 53310,
+ "Entries": [
+ {
+ "Name": "Newbie",
+ "Description": "",
+ "IP": "",
+ "Type": 3,
+ "Recommended": 2,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 100 },
+ { "Port": 54002, "MaxPlayers": 100 }
+ ]
+ },
+ {
+ "Name": "Normal",
+ "Description": "",
+ "IP": "",
+ "Type": 1,
+ "Recommended": 0,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54003, "MaxPlayers": 100 },
+ { "Port": 54004, "MaxPlayers": 100 }
+ ]
+ },
+ {
+ "Name": "Cities",
+ "Description": "",
+ "IP": "",
+ "Type": 2,
+ "Recommended": 0,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54005, "MaxPlayers": 100 }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Large-Scale Setup
+
+```json
+{
+ "Sign": {
+ "Enabled": true,
+ "Port": 53312
+ },
+ "Channel": {
+ "Enabled": true
+ },
+ "Entrance": {
+ "Enabled": true,
+ "Port": 53310,
+ "Entries": [
+ {
+ "Name": "Newbie",
+ "Type": 3,
+ "Recommended": 2,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54001, "MaxPlayers": 150 },
+ { "Port": 54002, "MaxPlayers": 150 },
+ { "Port": 54003, "MaxPlayers": 150 }
+ ]
+ },
+ {
+ "Name": "Normal",
+ "Type": 1,
+ "Recommended": 0,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54004, "MaxPlayers": 200 },
+ { "Port": 54005, "MaxPlayers": 200 },
+ { "Port": 54006, "MaxPlayers": 200 },
+ { "Port": 54007, "MaxPlayers": 200 }
+ ]
+ },
+ {
+ "Name": "Cities",
+ "Type": 2,
+ "Recommended": 0,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54008, "MaxPlayers": 100 },
+ { "Port": 54009, "MaxPlayers": 100 }
+ ]
+ },
+ {
+ "Name": "MezFes",
+ "Type": 6,
+ "Recommended": 6,
+ "AllowedClientFlags": 0,
+ "Channels": [
+ { "Port": 54010, "MaxPlayers": 100 }
+ ]
+ }
+ ]
+ }
+}
+```
+
+## Port Allocation
+
+Default port assignments:
+
+| Server | Port | Configurable |
+|--------|------|--------------|
+| Sign | 53312 | Yes |
+| SignV2 | 8080 | Yes |
+| Entrance | 53310 | Yes |
+| Channels | 54001+ | Yes (per-channel) |
+
+**Important:**
+
+- All ports must be unique
+- Firewall must allow inbound connections on these ports
+- Client expects Sign on 53312 and Entrance on 53310 by default
+
+## Firewall Configuration
+
+### Linux (ufw)
+
+```bash
+# Allow sign server
+sudo ufw allow 53312/tcp
+
+# Allow entrance server
+sudo ufw allow 53310/tcp
+
+# Allow channel servers (range)
+sudo ufw allow 54001:54010/tcp
+```
+
+### Linux (iptables)
+
+```bash
+# Sign server
+sudo iptables -A INPUT -p tcp --dport 53312 -j ACCEPT
+
+# Entrance server
+sudo iptables -A INPUT -p tcp --dport 53310 -j ACCEPT
+
+# Channel servers (range)
+sudo iptables -A INPUT -p tcp --dport 54001:54010 -j ACCEPT
+```
+
+### Windows Firewall
+
+```powershell
+# Allow specific ports
+New-NetFirewallRule -DisplayName "Erupe Sign" -Direction Inbound -Protocol TCP -LocalPort 53312 -Action Allow
+New-NetFirewallRule -DisplayName "Erupe Entrance" -Direction Inbound -Protocol TCP -LocalPort 53310 -Action Allow
+New-NetFirewallRule -DisplayName "Erupe Channels" -Direction Inbound -Protocol TCP -LocalPort 54001-54010 -Action Allow
+```
+
+## Load Balancing
+
+For high-traffic servers, consider:
+
+1. **Multiple Entrance Servers**: Run multiple entrance server instances behind a load balancer
+2. **Distributed Channels**: Spread channel servers across multiple physical servers
+3. **Database Connection Pooling**: Use PgBouncer for database connections
+4. **SignV2 with Reverse Proxy**: Use nginx/HAProxy with SignV2 for better scaling
+
+## Monitoring
+
+Monitor server health:
+
+```bash
+# Check if servers are listening
+netstat -tlnp | grep erupe
+
+# Check open ports
+ss -tlnp | grep -E '(53312|53310|54001)'
+
+# Monitor connections per channel
+watch -n 1 'netstat -an | grep ESTABLISHED | grep 54001 | wc -l'
+```
+
+## Troubleshooting
+
+### Can't Connect to Sign Server
+
+- Verify Sign server is enabled
+- Check port 53312 is open
+- Verify client is configured for correct IP/port
+
+### World List Empty
+
+- Verify Entrance server is enabled
+- Check Entrance server port (53310)
+- Ensure at least one Entry is configured
+
+### Can't Enter World
+
+- Verify Channel server is enabled
+- Check channel ports are open
+- Verify channel ports in Entrance entries match actual running servers
+
+### Server Crashes on Startup
+
+- Check all ports are unique
+- Verify database connection (password not empty)
+- Check logs for specific errors
+
+## Related Documentation
+
+- [Database](database.md) - Database configuration
+- [Basic Settings](basic-settings.md) - Host and network settings
+- [CLAUDE.md](../CLAUDE.md#architecture) - Detailed architecture overview