# Quest Events

The Quest system can automatically send events to followers who implement `IFollowQuests`.  The **QuestEventBoard** can automatically send out events as the status changes on **Quest** and **QuestStep** objects. Your scripts can utilize the data to drive in game actions and behaviors.

{% hint style="warning" %}
The **Blackboard** module has similar functionality, where it can send out *Events*. **QuestEvent** objects are not entirely the same thing, as they are specifically intended to be used with the **Quest** system, while the **Blackboard** events are very flexible and agnostic to how they are used.

One notable difference, the **QuestEvent** value for status is specific to `QuestStep.QuestStepStatus` values, while the **BlackboardEvent** value for status is a `string`, with the intention that you will populate it as you see fit for your project.
{% endhint %}

{% hint style="success" %}
**QuestEvents** and the **Blackboard** can be used together.&#x20;

There could be times where you want to keep track of data with Blackboard, even if the quest that data relates to has not yet been activated.
{% endhint %}

## Quest Event Board

The **Quest Event Board** is a prefab in the [**Repositories**](/magic-pig-games/game-modules-4/v4-migration-tips/repositories.md), and should be added to your scene. Any object that wishes to follow the Quest Event Board should implement `IFollowQuests`.

## `QuestEvent` Object

The `QuestEvent` object is sent to followers via the `ReceiveQuestEvent` method, required with the `IFollowQuests` interface. The object will have information followers can use to decide whether they care about this event, and if so, what to do.

<pre class="language-csharp"><code class="lang-csharp">// Create a QuestEvent -- Generally this is not something you'd do manually!
public static QuestEvent Create(GameQuest gameQuest
        , QuestStep.QuestStepStatus status, QuestStep questStep = null) 
        => new QuestEvent {
                questGameId = gameQuest.GameId(), 
                status = status,
                gameQuest = gameQuest,
<strong>                questStep = questStep
</strong>};
</code></pre>

### Quest Game Id

This is the GameId of the GameQuest sending this event.

### Status

This is a `QuestStep.QuestStepStatus` value, which can be `Started`, `InProgress`, `Succeeded`, or `Failed`.

{% hint style="info" %}
`Started` is only the status for one frame. After that, the status is set to `InProgress`. It will never revert back to the "Started" state, so if you want to do something when a quest starts, such as play an audio clip, listen for:

<pre class="language-csharp"><code class="lang-csharp"><strong> status == QuestStep.QuestStepStatus.Started
</strong></code></pre>

{% endhint %}

### Game Quest

This is the `GameQuest` object that is being referenced.

### Quest Step

This is the `QuestStep` object that is being referenced.

{% hint style="warning" %}
If the `QuestStep` value is `null`, it means the `Quest` itself sent the event!

Your followers of `QuestEventBoard` may be listening for various things. The value of `QuestStep` will determine which step sent the event or whether the Quest sent the event.

If the value is `null`, and `status == QuestStep.QuestStepStatus.Failed`, it means the Quest has failed!
{% endhint %}

{% hint style="info" %}
`QuestStep.QuestStepStatus.Started` will never be sent by a `QuestStep`.
{% endhint %}

## Example

Your scripts which implement `IFollowQuests` will need a `ReceiveQuestEvent` method. What each object cares about is entirely up to you.

```csharp
// This example is from Puppy.cs in the Party Based RPG demo game

public string questName = "Rescue the Puppy";

public override void ReceiveQuestEvent(QuestEvent questEvent)
{
    base.ReceiveQuestEvent(questEvent); // Does nothing in this context.

    // Check to see if the event is that the quest has started
    if (questEvent.gameQuest.objectName != questName
        || questEvent.status != QuestStep.QuestStepStatus.Started) 
    return;

    SetTimeOfDeath();
    StartCoroutine(CheckForDeath());
}
```

In the example above, the "Puppy" is listening for a specific quest to start. If a `QuestEvent` is received and the value of `objectName` is not the `questName` the script cares about, nothing happens.

Similarly, it also only cares when the `status` is "Started", otherwise it will do nothing even if the `objectName` is correct.

When the `objectName` and value we are listening for match, and the status is `Started`, we call two methods.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://infinitypbr.gitbook.io/magic-pig-games/game-modules-4/module-documentation/quests/quest-events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
