> For the complete documentation index, see [llms.txt](https://infinitypbr.gitbook.io/magic-pig-games/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://infinitypbr.gitbook.io/magic-pig-games/game-modules-4/module-documentation/quests/quest-events.md).

# 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.
