> For the complete documentation index, see [llms.txt](https://malbersanimations.gitbook.io/animal-controller/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malbersanimations.gitbook.io/animal-controller/malbers-questforge/quest-system/rewards.md).

# Rewards

The system gives you a base class to inherit from and two clean ways to connect a reward to your own game systems.

Rewards are granted automatically when a quest is completed. You do not need to call anything manually.

### How It Works

The **Quest** asset holds a list of `QuestRewardBase` assets in its **Rewards** field. When `QuestManager` completes a quest it:

1. Calls `CanGrantReward()` on each reward — skips any that return `false`
2. Calls `GrantReward()` on each reward that passes validation
3. Fires the `OnRewardGranted` UnityEvent on `QuestManager` for each one granted

All the reward logic — what gets given and how — lives inside your reward asset. QuestManager never needs to know about your inventory, currency, or experience systems.

### Creating a Custom Reward

#### Step 1 — Copy the template

Open `ExampleReward.cs` (located in `Scripts/QuestSystem/Rewards/`). Copy the file and rename both the file and the class to match your reward type — for example `GoldReward`, `ExperienceReward`, or `ItemReward`.

#### Step 2 — Set the create menu path

At the top of your new class, update the `CreateAssetMenu` attribute:

```csharp
[CreateAssetMenu(menuName = "Malbers Quest Forge/Rewards/Gold Reward")]
public class GoldReward : QuestRewardBase
{
```

#### Step 3 — Add your reward-specific fields

Below the fields inherited from `QuestRewardBase`, declare whatever your reward needs:

```csharp
[Header("Reward Settings")]
[SerializeField] private int goldAmount = 100;

[Header("Reward Events")]
[SerializeField] private IntEvent OnGoldGranted;
```

#### Step 4 — Implement `GrantReward`

This is the only method you **must** implement. It is called automatically when the quest completes. There are two recommended approaches:

**Option A — Events (recommended)**

Fire a Malbers event and wire it to your game system in the Inspector. This keeps your reward asset decoupled from your game code:

```csharp
public override void GrantReward(QuestInstance questInstance, QuestManager manager)
{
    if (!CanGrantReward(questInstance, manager))
    {
        InvokeFailureEvent("Validation failed");
        return;
    }

    OnGoldGranted?.Invoke(goldAmount);
    InvokeSuccessEvent(goldAmount.ToString());
}
```

In the Inspector, connect `OnGoldGranted` to whichever method on your `CurrencyManager`, `PlayerStats`, or equivalent system that adds gold.

**Option B — Direct reference (alternative)**

Call your game systems directly from code:

```csharp
public override void GrantReward(QuestInstance questInstance, QuestManager manager)
{
    CurrencyManager.Instance.AddGold(goldAmount);
    InvokeSuccessEvent(goldAmount.ToString());
}
```

#### Step 5 — Implement `GetPreviewText`

This is also required. It returns the short text shown in the quest UI before the player accepts the quest — e.g. the reward summary line:

```csharp
public override string GetPreviewText()
{
    return $"+{goldAmount} Gold";
}
```

### Optional Overrides

#### `CanGrantReward` — Validation

Override this to prevent a reward from being granted under certain conditions. Return `false` to block it:

```csharp
public override bool CanGrantReward(QuestInstance questInstance, QuestManager manager)
{
    // Example: only grant if inventory has space
    if (!InventoryManager.Instance.HasSpace()) return false;
    return base.CanGrantReward(questInstance, manager);
}
```

If `CanGrantReward` returns `false`, the reward is skipped silently. QuestManager will not fire `OnRewardGranted` for that reward.

#### `RevokeReward` — Abandonment / Failure

Override this only if your game design requires rewards to be taken back when a quest is abandoned or failed. The base implementation does nothing:

```csharp
public override void RevokeReward(QuestInstance questInstance, QuestManager manager)
{
    OnGoldGranted?.Invoke(-goldAmount); // deduct the gold
}
```

### What QuestRewardBase Provides

Every reward asset automatically has these fields and helpers from the base class — you do not need to re-declare them:

| Field / Method               | Type     | Description                                        |
| ---------------------------- | -------- | -------------------------------------------------- |
| `rewardName`                 | `string` | Display name shown in the quest UI                 |
| `description`                | `string` | Tooltip or detail text                             |
| `icon`                       | `Sprite` | Icon shown in the rewards UI                       |
| `OnRewardGranted`            | `MEvent` | Fired automatically on success — wire to sound/VFX |
| `OnRewardFailed`             | `MEvent` | Fired automatically on failure                     |
| `InvokeSuccessEvent(data)`   | Helper   | Call this at the end of `GrantReward`              |
| `InvokeFailureEvent(reason)` | Helper   | Call this when validation fails                    |

### Creating the Reward Asset

Once your script compiles:

1. In the **Project** window, right-click → **Create → Malbers Quest Forge → Rewards → \[Your Reward Name]**
2. Name it descriptively (e.g. `Reward_100Gold`)
3. Configure its fields in the Inspector — reward name, icon, amount, and any event connections to your game systems

***

### Linking Rewards to a Quest

1. Select your **Quest** asset in the Project window
2. Find the **Rewards** list in the Inspector
3. Click **+** and drag in your reward asset (e.g. `Reward_100Gold`)
4. Add as many reward assets as needed — they all grant in sequence on completion

The rewards are displayed to the player in the quest journal and in the **New Quest** panel when the quest is first accepted, using the `GetDisplayName()`, `GetIcon()`, and `GetPreviewText()` values from each asset.

***

### Examples - Common Reward Types to Build

| Reward Type                      | Approach                                                                                            |
| -------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Currency** (gold, gems)        | Fire `IntEvent` → CurrencyManager                                                                   |
| **Experience / Leveling**        | Fire `IntEvent` → PlayerStats                                                                       |
| **Item Grant**                   | Fire `MEvent` → InventoryManager, or use direct reference with an `ItemData` ScriptableObject field |
| **Unlock** (area, skill, recipe) | Fire `MEvent` → your unlock system                                                                  |
| **Reputation / Faction**         | Fire `IntEvent` → FactionManager                                                                    |
| **Stat Boost**                   | Direct reference to PlayerStats, or `MEvent`                                                        |
