# Libgdx Gdx Ai

> Use when writing libGDX Java/Kotlin code involving gdx-ai — steering behaviors (Steerable, Arrive, Seek, Flee, Wander, Pursue, Evade, BlendedSteering, PrioritySteering), A* pathfinding (IndexedAStarPathFinder, Graph, Heuristic), behavior trees (BehaviorTree, LeafTask, Sequence, Selector, .tree text format, BehaviorTreeParser), finite state machines (State, DefaultStateMachine, StackStateMachine,…

- **Type:** Skill
- **Install:** `agentstack add skill-kyu-n-gdx-claude-skills-libgdx-gdx-ai`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [kyu-n](https://agentstack.voostack.com/s/kyu-n)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [kyu-n](https://github.com/kyu-n)
- **Source:** https://github.com/kyu-n/gdx-claude-skills/tree/master/skills/libgdx-gdx-ai

## Install

```sh
agentstack add skill-kyu-n-gdx-claude-skills-libgdx-gdx-ai
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# libGDX gdx-ai Extension

Reference for steering behaviors, A* pathfinding, behavior trees, finite state machines, and scheduling in the gdx-ai extension.

## Dependency

```gradle
// In core module only — pure Java, no native dependencies
implementation "com.badlogicgames.gdx:gdx-ai:$aiVersion"
```

Works on all backends including headless. No platform-specific jars needed.

## Steering Behaviors

### Steerable Interface

`Steerable>` extends `Location` and `Limiter`. Your entity implements it, providing: `getPosition()`, `getOrientation()`, `setOrientation()`, `newLocation()`, `vectorToAngle()`, `angleToVector()`, `getLinearVelocity()`, `getAngularVelocity()`, `getBoundingRadius()`, `isTagged()`/`setTagged()`, and all Limiter getters/setters for max linear/angular speed/acceleration.

**`vectorToAngle`/`angleToVector` convention:** `vectorToAngle(v)` = `atan2(-v.x, v.y)`, `angleToVector(out, a)` sets `out.x = -sin(a)`, `out.y = cos(a)`. Getting this wrong causes steering to point in the wrong direction.

### SteeringAcceleration — The Output Container

`SteeringAcceleration` has public fields `T linear` and `float angular`. Create ONE per entity, reuse each frame: `new SteeringAcceleration<>(new Vector2())`.

**`calculateSteering()` only fills the output container — it does NOT move the entity.** You must apply the acceleration to velocity and position yourself each frame.

### Common Setup Pattern

```java
// 1. Create behavior — target via constructor or setter
Arrive arrive = new Arrive<>(steerable, targetLocation)
    .setArrivalTolerance(0.5f)        // stop within this distance
    .setDecelerationRadius(3f)        // start slowing here
    .setTimeToTarget(0.1f);           // response speed (lower = snappier)
// Or set target separately:
// Arrive arrive = new Arrive<>(steerable)
//     .setTarget(targetLocation)
//     ...;

// 2. Each frame — calculate then apply
arrive.calculateSteering(steeringOutput);
linearVelocity.mulAdd(steeringOutput.linear, deltaTime);
if (linearVelocity.len2() > maxLinearSpeed * maxLinearSpeed)
    linearVelocity.setLength(maxLinearSpeed);
position.mulAdd(linearVelocity, deltaTime);
```

**Target is `Location`, not `Steerable`.** Any `Location` implementation works. Passing another `Steerable` works because `Steerable` extends `Location`.

### Individual Behaviors

Most-used: `Seek` (move toward target), `Flee` (move away), `Arrive` (decelerate to stop at target), `Wander` (random-looking movement), `Pursue`/`Evade` (predict moving target's future position).

Also available: `Face`, `LookWhereYouGoing`, `ReachOrientation`, `FollowPath`, `FollowFlowField`, `RaycastObstacleAvoidance`, `Hide` (extends `Arrive` — uses `Proximity` to find obstacles but is an individual behavior).

### Group Behaviors

Require a `Proximity` to detect nearby agents: `Separation`, `Alignment`, `Cohesion`, `CollisionAvoidance`.

### PrioritySteering and BlendedSteering

**PrioritySteering** — try behaviors in order, use first that produces non-zero output:

```java
PrioritySteering priority = new PrioritySteering<>(steerable, 0.001f);
//                                                          epsilon ↑ threshold
// below this magnitude, output considered "zero" → try next behavior
priority.add(obstacleAvoidance);  // highest priority
priority.add(arrive);             // fallback
```

**BlendedSteering** — weighted sum of multiple behaviors:

```java
BlendedSteering blended = new BlendedSteering<>(steerable);
blended.add(arrive, 0.7f);         // 70% arrive
blended.add(separation, 0.3f);     // 30% separation
```

### Limiter Interface

`Steerable` extends `Limiter` (caps linear/angular speed/acceleration). Behaviors read limits from the owner. Override per-behavior via `behavior.setLimiter(customLimiter)`.

## Pathfinding

### Graph Setup

Implement `IndexedGraph` with three methods: `getConnections(node)` returns `Array>`, `getIndex(node)` returns a unique `int` index, `getNodeCount()` returns total node count.

`Connection` has three methods: `getCost()`, `getFromNode()`, `getToNode()`. For simple weighted edges, use `DefaultConnection`.

### Heuristic and Pathfinding

```java
Heuristic heuristic = (node, end) ->                       // Manhattan for 4-dir
    Math.abs(end.x - node.x) + Math.abs(end.y - node.y);
IndexedAStarPathFinder pathFinder = new IndexedAStarPathFinder<>(graph);
DefaultGraphPath outPath = new DefaultGraphPath<>();
boolean found = pathFinder.searchNodePath(startNode, endNode, heuristic, outPath);
outPath.clear();                                                      // MUST clear before reuse
```

`HierarchicalPathFinder` — for large maps; searches at multiple abstraction levels. Use when standard A* is too slow.

### NavMesh

**NavMesh is NOT included in gdx-ai.** Use a third-party library or build your own graph from a nav mesh. gdx-ai pathfinding works with any graph you implement — tile grids, waypoint graphs, or nav mesh triangulations — but provides no mesh generation or triangle-based nav classes.

## Behavior Trees

### BehaviorTree and Task

`BehaviorTree` is the root container. `E` is the blackboard type (your data object shared by all tasks). Call `tree.step()` each frame.

```java
BehaviorTree tree = parser.parse(Gdx.files.internal("ai/enemy.tree"), enemy);
// In render/update:
tree.step();
```

**No GL context needed.** BehaviorTree is pure logic — works in headless, server, or testing environments.

### LeafTask

Extend `LeafTask` for custom logic. Override `execute()` returning `Status`:

```java
public class IsEnemyVisible extends LeafTask {
    @Override
    public Status execute() {
        Enemy e = getObject();  // blackboard access
        return e.canSeePlayer() ? Status.SUCCEEDED : Status.FAILED;
    }

    @Override
    protected Task copyTo(Task task) { return task; }
}
```

**Status values:** `RUNNING` (continue next frame), `SUCCEEDED`, `FAILED`.

### Branch Tasks

**Sequence = AND** (run children in order, fail on first failure). **Selector = OR** (run children in order, succeed on first success). Also: `Parallel` (run all simultaneously), `RandomSelector`, `RandomSequence`.

### Decorator Tasks

`AlwaysFail`, `AlwaysSucceed`, `Invert` (flip SUCCEEDED/FAILED), `Repeat` (N times or indefinitely), `UntilFail`, `UntilSuccess`, `SemaphoreGuard` (limits concurrent subtree access).

**Note:** The class is `SemaphoreGuard`, not `Semaphore`. Also available: `Wait` (leaf — pauses for a duration) and `Include` (decorator — includes an external subtree).

### Text Format (.tree files)

`BehaviorTreeParser` loads `.tree` files. Indentation defines hierarchy. Without `import`, task names must be fully-qualified. With `import com.mygame.ai.tasks.*`, unqualified names work.

```
import com.mygame.ai.tasks.*
selector
  sequence
    isEnemyVisible
    attack damage:20
  wander
```

Task attributes use `@TaskAttribute` annotation on fields. Set in .tree as `taskName attrName:value`.

```java
BehaviorTreeParser parser = new BehaviorTreeParser<>();
BehaviorTree tree = parser.parse(Gdx.files.internal("ai/enemy.tree"), enemy);
```

### Blackboard Pattern

`E` is your blackboard — all tasks access it via `getObject()`. Can be the entity itself (`BehaviorTree`) or a dedicated data object (`BehaviorTree`).

## Finite State Machines

### State Interface

`State` has four methods: `enter(E)`, `update(E)`, `exit(E)`, `onMessage(E, Telegram)`. Idiomatic pattern: implement as an **enum** (`enum EnemyState implements State`).

### DefaultStateMachine vs StackStateMachine

`DefaultStateMachine` — single active state, `changeState()` replaces it. `StackStateMachine` — each `changeState()` pushes current state onto stack; `revertToPreviousState()` pops. Arbitrary depth — use for interruptible states (stun, cutscene, pause).

```java
DefaultStateMachine fsm = new DefaultStateMachine<>(entity, EnemyState.IDLE);
// or StackStateMachine fsm = new StackStateMachine<>(entity, EnemyState.IDLE);
```

**Update each frame:** `fsm.update();`

### MessageManager

Inter-entity communication with optional delay. Entities implement `Telegraph` with `handleMessage(Telegram)` (typically delegates to `fsm.handleMessage(telegram)`).

**Sending messages — Telegraph references, NOT integer IDs:**

```java
MessageManager dispatcher = MessageManager.getInstance();
dispatcher.dispatchMessage(sender, receiver, MSG_SPOTTED);         // immediate
dispatcher.dispatchMessage(sender, receiver, MSG_DAMAGE, 25f);     // with extra data
dispatcher.dispatchMessage(2.0f, sender, receiver, MSG_BACKUP);    // delayed 2s
dispatcher.addListener(receiver, MSG_SPOTTED);                     // register for type
```

**You MUST update each frame** for delayed messages: `GdxAI.getTimepiece().update(deltaTime);` then `MessageManager.getInstance().update();`

## Scheduling

`LoadBalancingScheduler` distributes AI updates across frames. Entities implement `Schedulable` (method `run(long nanoTimeToRun)`). Add via `scheduler.addWithAutomaticPhasing(entity, framesPerRun)`. Call `scheduler.run(nanoBudget)` each frame.

## Common Mistakes

1. **Forgetting to set a target on Arrive/Seek** — Set via constructor `new Arrive<>(steerable, targetLocation)` or via `.setTarget(location)`. Without a target, `calculateSteering()` throws `NullPointerException`.
2. **Claiming NavMesh is built-in** — gdx-ai has NO NavMesh classes. Build your own graph from a nav mesh.
3. **Confusing Sequence and Selector** — Sequence = AND (all must succeed). Selector = OR (first success wins).
4. **Using `Semaphore` instead of `SemaphoreGuard`** — The decorator class is `SemaphoreGuard`.
5. **Not calling `tree.step()` each frame** — Behavior trees don't update automatically.
6. **Dispatching messages with integer IDs** — `MessageManager.dispatchMessage()` takes `Telegraph` object references as sender/receiver, not integer IDs.
7. **Not updating GdxAI timepiece** — Call `GdxAI.getTimepiece().update(deltaTime)` each frame, or delayed messages and scheduling won't work.
8. **Mixing Vector2/Vector3 generics** — All steering types for one entity must use the same vector type consistently.
9. **Thinking BehaviorTree needs GL** — BT, FSM, pathfinding, and scheduling are all pure logic. They work in headless environments.
10. **Forgetting `copyTo()` in LeafTask** — Required for tree cloning. Minimal implementation: `return task;`
11. **Calling `calculateSteering()` without applying the result** — Behaviors only compute acceleration. You must integrate it into velocity and position yourself each frame.
12. **Reusing `DefaultGraphPath` without calling `clear()`** — Old path nodes accumulate alongside new ones. Always call `outPath.clear()` before a new `searchNodePath` call.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [kyu-n](https://github.com/kyu-n)
- **Source:** [kyu-n/gdx-claude-skills](https://github.com/kyu-n/gdx-claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-kyu-n-gdx-claude-skills-libgdx-gdx-ai
- Seller: https://agentstack.voostack.com/s/kyu-n
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
