# How to Make Race Missions

This page covers how to use the features of Quest and Mission Framework+ in Blueprints to make a race mission.

{% hint style="info" %}
I**IMPORTANT - PLEASE READ:** This example is from a large game codebase. If you want a simpler version, see the demo content that comes with the plugin. The code used here is built for scalability and commercial release, which is why I'm showing it.
{% endhint %}

## Setting up the data table:

1. Create a struct with the variables you will need for your race, in my race quest I have these variables.

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FxvYPhJMbkkehRkdOnYoJ%2Fimage.png?alt=media&#x26;token=265204af-311a-42ba-9a69-4008b72eb445" alt=""><figcaption></figcaption></figure>

2. Now, create a data table from this struct you just created and fill it out.

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2F713PRu3eNIgrdiqzSNhi%2Fimage.png?alt=media&#x26;token=ba5f8595-ca96-4f56-95c0-5af8aec116cb" alt=""><figcaption></figcaption></figure>

3. We will use this data table in various places to set rewards, maximum ring count, time remaining, description, quest name, and delegates. Your data table may look different if you need other data points.

## Setting up the manager:

Each quest should have a manager to handle its operations. Let's create one for race missions.<br>

1. Create a new folder in your content browser named "Manager". Ideally, this should be under a race quest folder.
2. Right click anywhere in the context browser and click "Blueprint Class" then select "Actor".

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2Fzd0u2SEc98miQhzl64MF%2Fimage.png?alt=media&#x26;token=1c2278e2-8894-4ffc-b41e-d6f89def0dee" alt=""><figcaption></figcaption></figure>

3. Once the new actor is made, name it something like "BP\_RaceManager" and drag it into your level, you only need one of these in your level.
4. Now open up this manager actor.
5. In my game, races consist of two main parts: the rings that track progress and the timer that determines if the quest succeeds or fails. Both of these use quest delegates. Let's create two quest delegate bindings at the start of play so they can be called later. See screenshots in sections for when these are called.

{% hint style="info" %}
Quest Delegates can be given any name you like, in my game I name them with acronyms like "CQD" for "Challenge Quest Delegate" but you can name them however you like, just make sure the name aligns with where you call them(explained later) and they are uniquely named.
{% endhint %}

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FHRZWKhnF684vHREczqBN%2Fimage.png?alt=media&#x26;token=f2cfd75e-8051-436a-9875-c245e137699e" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
I'm using an early version of the plugin, which is why it's called "Ultimate Quest Subsystem" and why some variable names are different, like Quest Name instead of Quest Delegate. Everything else should remain the same.
{% endhint %}

4. With our delegates set up, we need to bind their callbacks to functions. I am using the create event node to remotely bind them to other custom events in my manager.

### Binding the Timer Quest Delegate:

Input:

We bound a delegate at the beginning of play in our manager to start a timer. Here is the code

1. Countdown Timer Functionality

   The start countdown timer is a simple function. It uses a data table to find the corresponding row by the current active quest name. I set the initial maximum time remaining from this data table. Then, I create a timer that counts down every second, reducing the time remaining. This time is stored as a quest progress named `CQ_RaceTimer`. I then check if `CQ_RaceTimer` is less than or equal to 0; if so, I cancel the quest.<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FPsZGEKwCWYoF8R03B8oA%2Fimage.png?alt=media&#x26;token=50fbc1c5-aa79-4ba0-a876-e0444a2077e2" alt=""><figcaption><p>Click to zoom in for node details</p></figcaption></figure>

This is the cancel challenge function called when the timer reaches 0:<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FK98EiWTiUDbBPYlfSfnc%2Fimage.png?alt=media&#x26;token=a845ccbb-fb7a-4ff4-b80e-f8554a716821" alt=""><figcaption></figcaption></figure>

Here is the reset ring progress function called above:<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FK9T6w3sMIpMY6tiL29d4%2Fimage.png?alt=media&#x26;token=605dcb62-ba63-4bbd-be9c-03832be7dba0" alt=""><figcaption></figcaption></figure>

### Binding the Ring Spawn Delegate:

We also bound a delegate at the beginning of our manager's play to spawn rings. Now, we need to create the function

1. This one is very simple function, it calls a multicast blueprint event dispatcher to the ring splines(next section), and spawns a widget that says "Quest Starting".<br>

   <figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FfFTCyvuk9Mk41UIDuqHZ%2Fimage.png?alt=media&#x26;token=deed7ea1-7185-4299-bb74-66bb64dbff03" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you are wondering where the quest is set active and started, that is done on a quest giver. I will go over that in the end when we add the quest to our level.
{% endhint %}

## Setting up the Rings:

In my example, I am placing the rings along a spline, so I will be demonstrating spline math. You don't have to use splines if you don't want to make spawning easier.

1. Make two new actors, a BP\_Ring and BP\_RingSplineSpawner.

### Setting up the Ring Spline Spawner:

1. In your BP\_RingSplineSpawner or your Ring Spawner, make a function that uses the node ***get actor of class*** of your manager and binds the delegate we called for spawning rings,&#x20;

{% hint style="info" %}
NOTE: This is not a quest delegate as we need it to multicast to all splines in the level.&#x20;
{% endhint %}

2. On the event dispatcher callback from the manager, we want to get the current active quest and compare it to an instance-editable string variable that is set in the level editor when we design our race missions later.

{% hint style="info" %}
You don't need to worry about this editable string just yet; we name it later when we add it to our level.
{% endhint %}

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FGRIvGByJQnqCvbY2Yo3j%2Fimage.png?alt=media&#x26;token=7525fbd4-9287-4a50-b00a-97011bdee309" alt=""><figcaption></figcaption></figure>

4. if the quest we want is active then we want to spawn the ring along the spline, here is my code for it.<br>

First half of the logic:<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FMDluBPFSioTLX3JqAbXW%2Fimage.png?alt=media&#x26;token=cd9147f7-74d0-41e9-8d4b-02f7225ec77c" alt=""><figcaption></figcaption></figure>

Second Half of the logic:

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2Ff3eOGhzvqkhlSTxUpwKy%2Fimage.png?alt=media&#x26;token=45365d40-e156-40be-9467-7882e6f58876" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Note: The maximum ring count will be set from the data table. We are also passing the quest name to our rings that we spawn so they can track progress.
{% endhint %}

### Setting up the rings to track progress:

{% hint style="info" %}
Since we already made this actor in step 1 of the Setting up the Ring Spline Spawner, we dont need to create it here.
{% endhint %}

1. You will want to add a shape and a box collider to this actor to begin. I used a torus from blender and a hologram material to make this.

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FHlSQQa6HCJuiy6rDlQQY%2Fimage.png?alt=media&#x26;token=8b4f1c53-d24d-4dcd-983f-0019e77e3770" alt=""><figcaption></figcaption></figure>

2. #### Event Overlap Handling for Box Collider

   Upon event overlap of the box collider, execute this code. It checks if the quest name we passed to the spline spawner is active. If active, it increments the quest progress of the sub-quest that tracks ring progress. If the progress reaches the maximum amount from the data table, retrieve the quest manager and mark the quest completed through its complete function.

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FZoTwniqL9lLVoYn4fghe%2Fimage.png?alt=media&#x26;token=16df394b-a56b-4875-9f18-25dbf7d696fa" alt=""><figcaption><p>Click to zoom in</p></figcaption></figure>

Here is the ***Get race challenge data*** pure function I am using for reference:<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FjbJJy8kcEhPeZwajA8EL%2Fimage.png?alt=media&#x26;token=b1c452f2-cc03-4b7f-8459-b3479368db51" alt=""><figcaption></figcaption></figure>

3. For the most part, we are finished. We just need to set up the quest giver/activator and integrate it into our level.

## Setting up the Quest Giver/Activator:

{% hint style="info" %}
NOTE: I am using an actor for my quest giver since my quest givers don't need to move, but you can make them into characters that can follow you and such if needed.
{% endhint %}

1. Make an actor or character that has a mesh and a box collider to trigger things.
2. On your box collider overlap event, create a widget with accept, decline, and description UI elements added to it.

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FHT7H2Z2SHazrzRvsYhFr%2Fimage.png?alt=media&#x26;token=53bfa428-e8a8-4e17-95af-e9bdadbab647" alt=""><figcaption></figcaption></figure>

3. To pass the Quest Name variable, which should be instance-editable, from your quest giver/activator to the quest acceptance widget, you can do this by making the quest name variable instance-editable and setting it to expose on spawn in your widget.

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FS9lSTZPCUZvpAv5kjOyF%2Fimage.png?alt=media&#x26;token=51cbe0ea-86e4-4c92-9b16-48929a5dc3a9" alt=""><figcaption></figcaption></figure>

4. In your widget blueprint, use these nodes on the accept button with the quest name you passed from your quest giver.<br>

   <figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FiO28JgjWoWrN3vSXoC2E%2Fimage.png?alt=media&#x26;token=f9b39d7d-1154-4647-aafa-f3d7beda5f6c" alt=""><figcaption></figcaption></figure>
5. Once you click "Accept," your quest will start, and the rings will spawn. We still need to add these actors to our level, so let's do that.

## Adding everything to our level:

1. Place the Quest Giver/Activator, the Quest Manager(only one manager per level), and the BP\_RingSplineSpawner into your level where you want them.
2. Go to each one and fill out their instance editable variables to align with the data table, for example the Quest name should align with the row in the data table.<br>

My Race Giver details panel:&#x20;

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FRKJ9z3a8ynGOGTzh4xjL%2Fimage.png?alt=media&#x26;token=2a729221-3a79-4610-9aae-14e5865bc3c5" alt=""><figcaption></figcaption></figure>

My BP\_RingSplineSpawner Details panel:

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2F9VsMzLp10smAa9M61HMJ%2Fimage.png?alt=media&#x26;token=1914abd9-bf60-47d7-8c22-e67d16cd54dc" alt=""><figcaption></figcaption></figure>

My data table where this race data is defined:<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FivyzVqFYXu3jXkDoX06X%2Fimage.png?alt=media&#x26;token=1b320391-bbee-42d9-9bf2-4157e1b0ef57" alt=""><figcaption></figcaption></figure>

My level where the giver and spline spawner are placed:<br>

<figure><img src="https://4273820272-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCuPO9OIF5oTPhPpoqmae%2Fuploads%2FoOoT6LTMmeuHT5Vak9z5%2Fimage.png?alt=media&#x26;token=76605ee9-18e1-4d56-b757-dd5338bf5f65" alt=""><figcaption></figcaption></figure>

## How to quickly make more races:

Now that we built our race mission to be scalable, we can quickly add more races to our game. Here's how to do that:

1. Make a new data table entry for a new race, make sure you fill out its details to be unique from the others, and ensure its row name matches its quest name like the one above, "CQ\_GroundRace\_1".
2. Add another quest giver and spline spawner to your level and assign them the new quest name found in the data table row.
3. Thats it, the new quest should now work because we built this to be scalable.

## Need support or have questions:

Join our discord and I will be happy to help you out with any questions or setting up different types of quests. <https://discord.gg/GXZ7c74sTm>
