> For the complete documentation index, see [llms.txt](https://stellarskills.gitbook.io/stellarskills-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stellarskills.gitbook.io/stellarskills-docs/quests.md).

# quests

Quests live under `objectives:` in `objectives.yml`. They award **StellarSkills XP**, which can raise trainer levels and grant the configured level points. Retaining the old file/root names avoids breaking saved progress.

The file's root `enabled: false` disables loading the whole quest map. Individual quest `enabled` fields control just their own entries. Keep `schema-version: 1` with current packaged content.

## Quest fields

| Field                                      | Purpose                                                                                |
| ------------------------------------------ | -------------------------------------------------------------------------------------- |
| Map key                                    | Stable quest ID                                                                        |
| `title`, `description`                     | Player-readable instructions; describe qualifying actions clearly                      |
| `enabled`                                  | Include this quest in normal progress                                                  |
| `campaign`                                 | Readable story grouping in the journal; empty makes it standalone                      |
| `event`                                    | Server event ID; see the event reference below                                         |
| `target`                                   | Event units required for a completion; positive integer                                |
| `reward.xp`                                | Whole XP paid on completion; explicit zero is allowed                                  |
| `prerequisites`                            | Quest IDs that must have completed                                                     |
| `prerequisite-mode`                        | `all` requires every prerequisite; `any` supports merging branches                     |
| `conflicts`                                | Quest IDs whose acceptance/progress/completion locks this path, enforced symmetrically |
| `required-classes`                         | Required selected class IDs                                                            |
| `minimum-level`                            | Minimum StellarSkills trainer level                                                    |
| `acceptance-required`                      | Player must explicitly start the quest; exclusive branches always require a choice     |
| `filters`                                  | Qualifying attributes; conditions combine with AND                                     |
| `repeat`                                   | `once`, `repeatable`, `daily`, `weekly`, `monthly`, or `custom`                        |
| `repeat-interval-seconds`                  | Positive custom-window size when repeat is `custom`                                    |
| `maximum-completions`                      | Lifetime completion ceiling; zero is unlimited for repeatable quests                   |
| `progress-message-every`                   | Progress announcement interval                                                         |
| `announce-progress`, `announce-completion` | Enable relevant player messages                                                        |

`reward.experience` is an accepted XP alias. When neither XP field is present, old `reward.amount` migrates to amount × 100 XP. Write `reward: {xp: ...}` explicitly; old `reward.currency` no longer decides quest payout currency.

There is no separate abandon/reset button for permanently chosen story branches. Administrators can reset a quest using the supported command. Plan conflicts before publication and explain irreversible choices.

## Standalone examples

Add these entries to the existing `objectives:` map:

```yaml
first_legendary:
  title: A Legendary Encounter
  description: Capture one Legendary Pokemon.
  event: capture
  target: 1
  repeat: once
  filters: {legendary: true}
  reward: {xp: 500}
four_moltres:
  title: Wings of Flame
  description: Capture four Moltres.
  event: capture
  target: 4
  repeat: once
  filters: {species: moltres}
  reward: {xp: 2000}
fire_collector:
  title: Fire-Type Collector
  description: Capture one hundred Pokemon with Fire as either type.
  event: capture
  target: 100
  repeat: once
  filters: {types-any: [fire]}
  reward: {xp: 1000}
fire_patrol:
  title: Fire Habitat Patrol
  description: Defeat one hundred wild Fire-type Pokemon.
  event: defeat
  target: 100
  repeat: once
  filters: {types-any: [fire]}
  reward: {xp: 1000}
```

`defeat` means wild Pokemon defeated through the Pixelmon hook, not deleting an entity with `/kill`. `mob_kill` is a different event for non-player Minecraft entities.

## Linear, branching, and merging stories

```yaml
objectives:
  field_intro:
    title: Your First Field Record
    campaign: Elemental Journey
    description: Capture a Pokemon to begin your fieldwork.
    event: capture
    target: 1
    reward: {xp: 100}
  ember_route:
    title: Follow the Ember Route
    campaign: Elemental Journey
    description: Choose this route, then capture four Fire-type Pokemon.
    event: capture
    target: 4
    prerequisites: [field_intro]
    conflicts: [tide_route]
    acceptance-required: true
    filters: {types-any: [fire]}
    reward: {xp: 400}
  tide_route:
    title: Follow the Tide Route
    campaign: Elemental Journey
    description: Choose this route, then capture four Water-type Pokemon.
    event: capture
    target: 4
    prerequisites: [field_intro]
    conflicts: [ember_route]
    acceptance-required: true
    filters: {types-any: [water]}
    reward: {xp: 400}
  field_finale:
    title: A Complete Field Journal
    campaign: Elemental Journey
    description: After either route, capture a Legendary Pokemon.
    event: capture
    target: 1
    prerequisites: [ember_route, tide_route]
    prerequisite-mode: any
    filters: {legendary: true}
    reward: {xp: 1000}
```

The prerequisite snapshot is taken before each event, so the event completing a predecessor does not also advance its newly unlocked child. Prerequisites test completion history; they are not merely menu arrows. Conflicts refer to quest IDs, not class IDs or node IDs.

## Matching filters

Names and ordinary values normalize to lowercase; hyphens/spaces normalize to underscores. List/CSV alternatives mean OR within one filter. Different keys mean AND. Examples:

| Filter                                         | Meaning                                                                   |
| ---------------------------------------------- | ------------------------------------------------------------------------- |
| `species: moltres`                             | Specific species; `pokemon`, `pokemon-species`, `species-any` are aliases |
| `types-any: [fire, water]`                     | At least one matching Pokemon type                                        |
| `types-all: [fire, flying]`                    | All listed types must be present                                          |
| `types-none: [water]`                          | None of the listed types                                                  |
| `rarity: [legendary, mythical]`                | Either rarity; also supports `ordinary` and `ultra_beast`                 |
| `legendary: true`, `shiny: true`, `boss: true` | Event flags                                                               |
| `min-level: 40`, `max-level: 70`               | Pokemon/event `level`, not trainer level                                  |
| `ball: ultra_ball`                             | Ball on capture events                                                    |
| `dimension: minecraft:overworld`               | Dimension supplied by the event                                           |
| `item: minecraft:diamond`                      | Item supplied by the relevant event                                       |
| `block: minecraft:diamond_ore`                 | Block-break event                                                         |
| `entity: minecraft:zombie`                     | Mob-kill event                                                            |
| `raid-type: tera`                              | Raid kind when supplied                                                   |

`min_`/`max_` prefixes perform numeric comparisons on the corresponding event attribute. `*` and `?` wildcards and `!` exclusions work in quest matching. Namespace tails can also match, so prefer specific IDs and test modded items with similar names. A filter whose attribute is missing usually will not match; attaching `ball` to a hatch quest cannot invent ball data.

Use [event and attribute reference](file:///4985688/reference/events.md) for the complete built-in event list. Quest matching is not the same parser as effect filters; do not automatically reuse every quest filter on an effect.

## Repeat windows and reward safety

Daily, weekly, monthly, and custom windows are time buckets, not a personal cooldown starting at completion. Calendar windows use UTC. `once` does not repay after completion. `repeatable` can complete multiple times when enough units arrive, subject to lifetime limits.

Quest progress, the transaction claim, XP, level changes, and earned points commit together. Replayed event IDs cannot pay twice. Acceptance is persisted. Existing accepted/in-progress paths survive restarts. Admin resetting progress intentionally allows new progress; it does not deduct earlier XP or points.

Players use the **Quests** button or `/skills quests`, and `/skills quests start <quest_id>` without the engine. The journal shows campaigns, requirements, XP, progress, and previous/next quest links. The configured safety limit is 2048 quests.
