Expert guide for developing the AIMobs Minecraft Fabric mod with AI-powered voice-controlled mobs using Ports and Adapters architecture
Expert assistant for developing and maintaining the AIMobs Minecraft Fabric mod - a system that creates AI-powered voice-controlled mob entities using Ports and Adapters architecture.
Provides comprehensive guidance for working with the AIMobs codebase, including:
**AIMobs** is a Minecraft 1.20.4 Fabric mod that enables players to communicate with in-game mobs using natural language. Mobs respond through AI-generated speech and actions by integrating with external APIs (OpenAI Whisper, GPT-4, 11 Labs) via WebSocket connections on port 8080.
**Tech Stack:**
The codebase follows strict architectural layering:
**1. Root Package (`entity.ai/`)**: Service interfaces and contracts
**2. Core Package (`core/`)**: Domain primitives
**3. Application Package (`application/`)**: Business logic implementations
**4. Infrastructure Package (`infrastructure/`)**: Minecraft-specific adapters
**Key Rule**: Infrastructure → Application → Core (unidirectional only)
1. **Interface-First Development**
- Always create service interfaces in root package before implementations
- Implementations go in `application/` or `infrastructure/`
2. **Unidirectional Dependencies**
- Core knows nothing about application or infrastructure
- Application knows core but not infrastructure
- Infrastructure knows both but is never imported by them
3. **No Peer Dependencies**
- Application and Infrastructure NEVER depend on each other directly
- Both depend on shared interfaces in root package
4. **Composition Root (ServiceFactory)**
- All object construction happens in `ServiceFactory`
- Constructor injection everywhere
- No service locators or static dependencies
5. **Testability via Seam Pattern**
- Every service injectable via interface
- Fast unit tests use service interfaces
- Integration tests use `@Tag("integration")`
- Use fakes for business logic, mocks only for external APIs
```bash
./gradlew build
./gradlew test # Unit tests only
./gradlew integrationTest # Integration tests only
./gradlew runClient # Minecraft client
./gradlew runServer # Test server
./gradlew genSources # Generate Minecraft sources
./gradlew clean # Clean build artifacts
```
**To add a new AI command:**
1. Create interface extending `AICommand` in `core/` package
2. Implement in `application/` package
3. Register in `CommandProcessorService`
4. Wire up in `ServiceFactory`
5. Add unit tests for business logic
6. Add integration tests for Minecraft interactions
**To create a new service:**
1. Define interface in root package (`entity.ai/`)
2. Create implementation in `application/` package
3. Add constructor parameters for dependencies (interface types only)
4. Register in `ServiceFactory.create()`
5. Write unit tests using test doubles
6. Write integration tests if it touches Minecraft APIs
**To extend entity behavior:**
1. Add methods to `EntityActions` interface in `core/`
2. Implement in infrastructure adapter
3. Update `CommandProcessorService` to use new actions
4. Test with both unit and integration tests
**Unit Tests** (fast, no Minecraft):
**Integration Tests** (slower, uses Minecraft):
**Test Doubles:**
The mod communicates with external AI services via WebSocket:
WebSocket networking follows same layered architecture:
```java
// 1. Define interface in root package
public interface MyService {
void doSomething(Entity entity);
}
// 2. Implement in application package
public class MyServiceImpl implements MyService {
private final DependencyService dependency;
public MyServiceImpl(DependencyService dependency) {
this.dependency = dependency;
}
@Override
public void doSomething(Entity entity) {
// Business logic here
}
}
// 3. Register in ServiceFactory
public class ServiceFactory {
public static Services create() {
DependencyService dependency = new DependencyServiceImpl();
MyService myService = new MyServiceImpl(dependency);
// ... wire up other services
}
}
```
```java
class MyServiceTest {
@Test
void shouldDoSomething() {
// Arrange
DependencyService fakeDependency = new FakeDependencyService();
MyService service = new MyServiceImpl(fakeDependency);
// Act
service.doSomething(mockEntity);
// Assert
// Verify behavior
}
}
```
```java
@Tag("integration")
class MyServiceIntegrationTest {
@Test
void shouldIntegrateWithMinecraft() {
// Arrange - use real Minecraft test fixtures
Services services = ServiceFactory.create();
// Act
services.myService().doSomething(realMinecraftEntity);
// Assert
// Verify Minecraft state changes
}
}
```
1. **Never import infrastructure code into application layer**
2. **Never import application code into core layer**
3. **Always inject dependencies via constructors**
4. **Always create interfaces before implementations**
5. **Always wire dependencies in ServiceFactory only**
6. **Use Java 21 features where appropriate**
7. **Follow Fabric mod conventions for Minecraft integration**
1. **Before adding code**: Verify which architectural layer it belongs to
2. **Before creating a class**: Create its interface first (if it's a service)
3. **Before writing logic**: Consider how it will be tested in isolation
4. **Before committing**: Run both unit and integration tests
5. **Before refactoring**: Ensure changes maintain unidirectional dependencies
WebSocket URL can be configured via system property:
```bash
./gradlew runClient -Daimobs.websocket.url=ws://production-server:8080
```
**Build fails**: Run `./gradlew clean build` and ensure Java 21 is active
**Tests fail**: Check if mixing unit and integration test concerns
**Circular dependencies**: Review package structure - likely violating layer rules
**WebSocket connection issues**: Verify external AI services are running on port 8080
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/aimobs-development-assistant/raw