---
title: NPC Objectives
type: docs
weight: 3
---

The NPC objectives system extends the base objective system with combat-related tasks.

**Package:** `com.hypixel.hytale.builtin.adventure.npcobjectives`

## Architecture

```
NPCObjectivesPlugin
├── Task Types
│   ├── KillSpawnBeaconObjectiveTask - Kill NPCs from spawn beacons
│   ├── KillSpawnMarkerObjectiveTask - Kill NPCs from spawn markers
│   ├── BountyObjectiveTask - Hunt specific NPC targets
│   └── KillNPCObjectiveTask - Kill NPCs by type/group
├── Resources
│   └── KillTrackerResource - Tracks kill counts
├── Systems
│   ├── KillTrackerSystem - Monitors NPC deaths
│   └── SpawnBeaconCheckRemovalSystem - Cleanup spawn beacons
└── NPC Actions
    ├── BuilderActionCompleteTask - Complete task on NPC
    ├── BuilderActionStartObjective - Start objective from NPC
    └── BuilderSensorHasTask - Check if player has task
```

## Task Types

### KillTask Interface

All kill-based tasks implement this interface:

```java
public interface KillTask {
    void checkKilledEntity(
        Store<EntityStore> store,
        Ref<EntityStore> npcRef,
        Objective objective,
        NPCEntity npc,
        Damage damageInfo
    );
}
```

### Registered Task Types

| Type | Task Asset Class | Description |
|------|------------------|-------------|
| `KillSpawnBeacon` | `KillSpawnBeaconObjectiveTaskAsset` | Kill NPCs from beacons |
| `KillSpawnMarker` | `KillSpawnMarkerObjectiveTaskAsset` | Kill NPCs from markers |
| `Bounty` | `BountyObjectiveTaskAsset` | Hunt specific target |
| `KillNPC` | `KillObjectiveTaskAsset` | Kill NPCs by group |

### Bounty Task

Spawns a specific NPC and marks it as a bounty target:

```java
public class BountyObjectiveTask extends ObjectiveTask implements KillTask {
    boolean completed;
    UUID entityUuid;  // Target NPC UUID

    // Spawns NPC at position and adds map marker
    protected TransactionRecord[] setup0(Objective objective, World world, Store<EntityStore> store) {
        // Get spawn position from asset configuration
        Vector3i spawnPosition = getAsset().getWorldLocationProvider()
            .runCondition(world, objectivePosition);

        // Spawn the bounty NPC
        Pair<Ref<EntityStore>, INonPlayerCharacter> npcPair =
            NPCPlugin.get().spawnNPC(store, getAsset().getNpcId(), null, spawnPosition, Vector3f.ZERO);

        // Add map marker for bounty
        addMarker(new MapMarker(
            getBountyMarkerIDFromUUID(npcUuid),
            "Bounty Target",
            "Home.png",
            transform
        ));

        // Register kill tracker
        store.getResource(KillTrackerResource.getResourceType()).watch(transaction);

        return transactionRecords;
    }

    @Override
    public void checkKilledEntity(Store<EntityStore> store, Ref<EntityStore> npcRef,
                                   Objective objective, NPCEntity npc, Damage damageInfo) {
        if (!this.entityUuid.equals(uuid)) return;
        this.completed = true;
        this.complete(objective, store);
        objective.checkTaskSetCompletion(store);
        this.removeMarker(getBountyMarkerIDFromUUID(uuid));
    }
}
```

### Asset Configuration

```yaml
# Objectives/bounty_quest.json
{
  "Id": "bounty_quest",
  "TaskSets": [
    {
      "Tasks": [
        {
          "Type": "Bounty",
          "NpcId": "bandit_leader",
          "WorldLocationProvider": {
            "Type": "LocationRadius",
            "Radius": 50
          }
        }
      ]
    }
  ]
}
```

## Kill Tracker

### KillTrackerResource

World resource that tracks NPC kills:

```java
ResourceType<EntityStore, KillTrackerResource> type =
    NPCObjectivesPlugin.get().getKillTrackerResourceType();
```

### KillTrackerSystem

ECS system that monitors NPC deaths and notifies watching tasks:

```java
// Register transaction to watch for kills
KillTaskTransaction transaction = new KillTaskTransaction(task, objective, store);
store.getResource(KillTrackerResource.getResourceType()).watch(transaction);
```

## NPC Actions

Registered as NPC core component types for AI integration:

### CompleteTask Action

```java
// Completes a task when NPC interaction occurs
NPCPlugin.get().registerCoreComponentType("CompleteTask", BuilderActionCompleteTask::new);
```

### StartObjective Action

```java
// Starts an objective from NPC dialogue/interaction
NPCPlugin.get().registerCoreComponentType("StartObjective", BuilderActionStartObjective::new);
```

### HasTask Sensor

```java
// Sensor that checks if player has a specific task
NPCPlugin.get().registerCoreComponentType("HasTask", BuilderSensorHasTask::new);
```

## API Usage

### Check if Player Has Task

```java
boolean hasTask = NPCObjectivesPlugin.hasTask(playerUUID, npcId, "taskId");
```

### Update Task Completion

```java
String animationId = NPCObjectivesPlugin.updateTaskCompletion(
    store, ref, playerRef, npcId, "taskId"
);
```

### Start Objective from NPC

```java
NPCObjectivesPlugin.startObjective(playerReference, "quest_id", store);
```

## Asset Loading Order

The plugin ensures proper asset loading order:

```java
AssetRegistry.getAssetStore(ObjectiveAsset.class).injectLoadsAfter(SpawnMarker.class);
AssetRegistry.getAssetStore(ObjectiveAsset.class).injectLoadsAfter(BeaconNPCSpawn.class);
AssetRegistry.getAssetStore(ObjectiveAsset.class).injectLoadsAfter(NPCGroup.class);
```
