EntityAI is a proof-of-concept library designed to solve a specific problem: writing Artificial Intelligence logic in Minecraft’s native Java API is verbose, fragile, and difficult to maintain.
This project is the result of “over-engineering” a university assignment.
The task was simple: implement basic character behaviors using a provided (and quite limited) AI library for Unity. Instead of following the easy path, my team and I decided to build a Minecraft Mod.
Since we couldn’t use the provided Unity tools (and Minecraft’s internal AI system is notoriously verbose and fragile), I had to architect my own solution. I engineered a high-level Kotlin DSL (Domain Specific Language) that replaces the spaghetti code of native Minecraft development with a clean, declarative syntax for Behavior Trees and State Machines.
The Kotlin DSL
The core innovation is the use of Kotlin Type-Safe Builders and Higher-Order Functions to create a readable syntax for AI logic. Instead of chaining objects manually, the API allows defining behavior hierarchies naturally.
ai.activities += TreeActivity("default", ai, rootLoopUnconditional {
runAndWait {
or {
and {
findNearestLivingEntities()
or {
// Find enemy in a distance of 32 blocks.
findAttackTargetIfNotFound(32.0f) { it is EnderVillager }
findAttackTargetIfNotFound(32.0f) {
it is PlayerEntity && !it.isCreative && !it.isSpectator
}
}
// walkToEntity is a macro: generates more nodes under the hood.
walkToEntity(MemoryTypes.ATTACK_TARGET, 1.5f, 1.0f, 32.0f)
succeeder { attack() }
}
and {
findRandomWalkTarget(1.0f)
timed(40, 60) { walkToTarget() } // 40-60 ticks. 1 tick = 0.05s
}
}
}
})
Architecture: The “Activity” System
The library introduces an architecture based on Activities. Unlike standard Minecraft entities that run a single flat list of goals, EntityAI entities run a Hierarchical State Machine.
:: Behavior Tree Implementation
A robust implementation of standard AI nodes: Composites (Sequence, Selector), Decorators (Inverter, Timed, Loop), and Leafs (Action, Condition).
:: Memory & Blackboard
Implemented a strongly-typed Blackboard System (MemoryTypes). Nodes can share data like ATTACK_TARGET or HOME_POS without coupling, resolving references at runtime.
:: Hybrid State Machines
Entities can switch between entire Behavior Trees based on high-level states (e.g., “Working”, “Sleeping”, “Fleeing”). This Activity Manager prevents giant, unmanageable trees.
:: NMS Abstraction Layer
Wraps Minecraft’s obfuscated internal methods (NMS) into stable Kotlin interfaces. This decoupling allowed the mod to survive game updates with minimal refactoring.
Use Case: Magic End
The library was validated by building Magic End, a mod that introduces a new ecosystem to the End dimension.
- Complex Societies: Implemented as Endervilles, villages where entities have professions (Farmer, Guardian, Shaman) and interact socially (sharing food, calling for help).
- Evolution Mechanics: The Void Worm entity uses the State Machine to track its “kill count” and physically evolves into a Void Snake boss after consuming enough enemies.
Technical Challenges
Navigating the Spaghetti
Minecraft’s internal pathfinding engine is notoriously unpredictable and undocumented. Complex entities often got stuck or spun in circles when calculating paths in the floating islands of the End.
I reverse-engineered the pathfinding code and re-implemented a Path Debugger left unfinished by Mojang devs. By visualizing the navigation mesh and node weights in real-time, I was able to tune the A* heuristic to handle verticality and void gaps correctly.
Kotlin Interoperability
The goal was to make the API feel “Native Kotlin” while running inside Minecraft.
I used Inline Functions and Reified Type Parameters to eliminate Java boilerplate. For example, looking up a component becomes entity.get<MyComponent>() instead of entity.getComponent(MyComponent.class), reducing verbosity and improving runtime safety.