Expert guide for developing economic systems in Minecraft Dragonfly servers with Go. Handles multi-RDBMS support, async commands, domain-driven architecture, and GORM ORM integration.
Expert skill for developing economic systems in Minecraft Dragonfly servers using Go. Specializes in command implementation, multi-RDBMS support, domain-driven design, and asynchronous database operations.
This skill helps you build and maintain economic systems for df-mc/dragonfly Minecraft servers. It covers the complete architecture stack from domain models to commands, with focus on clean architecture, GORM ORM, and async operations.
Dragonfly is an asynchronous Minecraft: Bedrock Edition server written in Go with:
When working with DF Economy projects, follow this layered architecture:
1. **Domain Layer**: Clean domain models (e.g., `EconomyEntry`) representing core business objects
2. **Service Layer**: Business logic, validation, and configuration management (`EconomyService`)
3. **Database Layer**: Interface-based design with GORM ORM supporting multiple RDBMSs
4. **Command Layer**: Dragonfly commands with async execution patterns
```
df-economy/
├── dragonfly/commands/ # Command implementations
│ ├── base.go # BaseCommand with shared utilities
│ ├── register.go # Command registration
│ └── [commands].go # Individual command files
├── economy/ # Domain and business logic
│ ├── domain.go # Domain models
│ ├── config/ # Configuration management
│ └── service/ # Service layer with validation
├── internal/db/ # Database abstraction
│ ├── db.go # DB interface
│ ├── factory.go # Multi-RDBMS factory
│ ├── gorm.go # GORM implementation
│ └── model.go # Database models
└── cmd/demo/ # Demo server implementation
```
All commands must:
1. Implement the `cmd.Runnable` interface
2. Use struct fields for command parameters
3. Handle async execution with timeout (5 seconds)
4. Provide immediate user feedback
```go
type MyCommand struct {
BaseCommand
Target cmd.Optional[string] // Optional parameter
Amount int // Required parameter
}
func (c MyCommand) Run(src cmd.Source, output *cmd.Output) {
player := c.GetPlayer(src, output)
if player == nil {
return
}
// Provide immediate feedback
player.Message("§aProcessing...")
// Execute async with timeout
c.ExecuteWithTimeout(player, func(ctx context.Context) error {
// Your async logic here
return nil
})
}
```
The system supports three database backends via GORM:
```go
// Configuration
config := &config.Config{
DBType: "sqlite", // or "mysql", "postgres"
DBDSN: "economy.db", // connection string
DefaultBalance: "1000",
EnableSetCmd: "false",
}
// Create database instance
database, err := db.NewDB(config)
```
```go
type Config struct {
DBType string // "sqlite", "mysql", "postgres"
DBDSN string // Connection string or file path
DefaultBalance string // Initial balance for new users
EnableSetCmd string // "true" or "false" - enable /economy set
}
```
1. **Database Errors** (`internal/db/errors.go`): Connection, query failures
2. **Service Errors** (`economy/service/errors.go`): Business logic validation
3. **Command Errors**: User-facing messages with Minecraft color codes
```go
// Success: §a (green)
player.Message("§aBalance updated successfully!")
// Error: §c (red)
player.Message("§cInsufficient balance!")
```
All database operations must be async:
1. Validate player immediately
2. Send immediate feedback message
3. Execute database operation in goroutine with 5-second timeout
4. Handle context cancellation
5. Send result message to player
```go
type EconomyService struct {
db db.DB
config *config.Config
}
// Business logic with validation
func (s *EconomyService) Transfer(from, to string, amount int64) error {
// Validation
if amount <= 0 {
return ErrInvalidAmount
}
if from == to {
return ErrSelfTransfer
}
// Execute with transaction
return s.db.Transfer(ctx, from, to, amount)
}
```
```go
func RegisterCommands(service *service.EconomyService, config *config.Config) {
// Always register
cmd.Register(cmd.New[commands.EconomyCommand](...))
cmd.Register(cmd.New[commands.BalanceCommand](...))
// Conditional registration
if config.EnableSetCmd == "true" {
cmd.Register(cmd.New[commands.SetCommand](...))
}
}
```
When implementing new features:
1. **Define Domain Model**: Create clean domain structs in `economy/domain.go`
2. **Add Database Interface**: Define method in `internal/db/db.go`
3. **Implement GORM Logic**: Add implementation in `internal/db/gorm.go`
4. **Add Service Method**: Business logic in `economy/service/service.go`
5. **Create Command**: Implement in `dragonfly/commands/`
6. **Register Command**: Add to `dragonfly/commands/register.go`
7. **Update Configuration**: Add config fields if needed
For detailed Dragonfly framework information, use DeepwikiMCP server:
```go
type ParentCommand struct {
Sub cmd.SubCommand `cmd:"sub1|sub2"`
}
```
```go
type Command struct {
OptionalTarget cmd.Optional[string]
}
```
1. **Always use async execution** for database operations
2. **Validate inputs** at the service layer
3. **Separate domain models** from database models
4. **Use factory pattern** for multi-RDBMS support
5. **Provide immediate feedback** before async processing
6. **Handle timeouts** with context (5-second default)
7. **Use color codes** for user messages (§a success, §c error)
8. **Keep commands thin** - logic belongs in service layer
9. **Use string-based config** for external library compatibility
10. **Default to secure settings** (e.g., EnableSetCmd = "false")
```go
// 1. Define command struct
type NewCommand struct {
BaseCommand
Amount int
}
// 2. Implement Run method
func (c NewCommand) Run(src cmd.Source, output *cmd.Output) {
player := c.GetPlayer(src, output)
if player == nil {
return
}
player.Message("§aProcessing...")
c.ExecuteWithTimeout(player, func(ctx context.Context) error {
// Call service layer
err := c.service.YourMethod(ctx, player.XUID(), c.Amount)
if err != nil {
player.Message(fmt.Sprintf("§cError: %v", err))
return err
}
player.Message("§aSuccess!")
return nil
})
}
// 3. Register in register.go
cmd.Register(cmd.New[commands.NewCommand]("commandname", "Description", nil))
```
This skill provides comprehensive guidance for developing robust, maintainable economic systems in Dragonfly Minecraft servers with clean architecture and modern Go practices.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/df-economy-development/raw