# CAR-1: Quests
This specification defines a method to manage on-chain quest status for video games.
## Motivation
As the on-chain gaming space grows it is important to define a standard for handling quests that allows for easy indexing. This enables external platforms to display a game's quest progress, their completion criteria, and allowing them to then mint rewards on the completion of these quests in a permissionless manner.
## Implementation
A quest is defined when the `quest_progress` event is emitted with a unique ID field and a [metadata URI](#metadata-uri). Its status is updated via events that are emitted as a result of a player's in-game actions.
Quests can have a one-to-many relationship to other quests. Child quests need to be completed by the player first before the parent can be completed. A quest's completion criteria is defined in the [metadata](#metadata-uri).
### Interface
#### Contract
```cairo
@event
func quest_progress(
id: felt,
player: felt,
metadata_len: felt,
metadataURI: felt*
) -> ()
```
#### Metadata URI
The value of `metadataURI` should be a data URI (`data:application/json,...`) or an IPFS Content ID (`ipfs://...`) that resolves to a JSON object.
The following metadata fields are required:
```json
{
"title": "string",
"description": "string"
}
```
Supported optional fields:
```json
{
"completion": {
"all": [
{
"id": "number",
"count": "number"
}
],
"any": [
{
"id": "number",
"count": "number"
},
{
"id": "number",
"count": "number"
}
]
},
"imageURI": "string"
}
```
The `completion` object can contain arrays with the following keys:
- `all` - Contains references to quests that **all** need to be completed
- `any` - Contains references to quests where **any** one needs to be completed
The objects in the arrays have the fields:
- `id` - The `id` of the child quest we are referencing
- `count` - The number of times the child quest needs be completed per player
### Creating a quest
If a quest does not have completion criteria then `completion` can be omitted from its metadata. These are completed for the player as soon as the event is emitted.
---
**Use the zero address as the player when defining the quest**
---
1. Emit the `quest_progress` event to create a quest for any tasks that will be part of the completion criteria
1. Emit the `quest_progress` event to create the quest for the parent, including the child quests if it has any in its metadata
### Completing a quest
Any time the `quest_progress` event is emitted and it either does not have completion criteria, or the completion criteria is met, the quest is completed. quests can be completed multiple times.
quests without `completion` in its metadata will be completed for the player as soon as the event is emitted.
If it does have completion criteria:
1. Complete any child quests in the completion criteria first by emitting the `quest_progress` events for at least as many times as the criteria requires
1. Emit `quest_progress` for the parent quest when all completion criteria is satisfied to complete it
## Example
Consider the following quest:
In Hyrule, destroy
- 3 Stalchildren
- 1 Stalfo OR 5 Deku Babas
First create the quest for each task:
**Note: json() is used for brevity**
```cairo
// Note that we do not include completion
// criteria for these tasks
quest_progress.emit(
id=1,
player=0,
metadata_len=4,
metadataURI=json('{
"title": "Destroy a Stalchild",
"description": "They come out at night in Hyrule Field"
}'),
);
quest_progress.emit(
id=2,
player=0,
metadata_len=4,
metadataURI=json('{
"title": "Destroy a Stalfo",
"description": "They come out at night in Hyrule Field"
}'),
);
quest_progress.emit(
id=3,
player=0,
metadata_len=4,
metadataURI=json('{
"title": "Destroy a Deku Baba",
"description": "They can be found throughout Hyrule"
}'),
);
```
Now we can use those quests as completion criteria:
```cairo
quest_progress.emit(
id=4,
player=0,
metadata_len=7,
metadataURI=json('{
"title": "Monster Hunting",
"description": "
- Destroy 3 Stalchildren
- Destroy 1 Stalfo OR 5 Deku Babas
",
"completion": {
"all": [
{
"id": 1,
"count": 3
}
],
"any": [
{
"id": 2,
"count": 1
},
{
"id": 3,
"count": 5
}
]
}
}')
);
```
Now we have a small progress tree defined for this quest. It can easily be extended by including completion criteria that in turn has its own completion criteria.
```mermaid
flowchart TD
q4["Monster Hunting"]
q3["Destroy a Stalchild"]
subgraph ANY
q2["Destroy a Stalfo"]
q1["Destroy a Deku Baba"]
end
q4 --3--> q3
q4 --1--> q2
q4 --5--> q1
```
Before the parent quest can be completed, the player (0x123) should perform actions that will result in the following events emitted:
```cairo
// Stalchildren
quest_progress(id=1, player=0x123, ...)
quest_progress(id=1, player=0x123, ...)
quest_progress(id=1, player=0x123, ...)
// Stalfos
quest_progress(id=2, player=0x123, ...)
quest_progress(id=2, player=0x123, ...)
// OR Deku Babas
quest_progress(id=3, player=0x123, ...)
quest_progress(id=3, player=0x123, ...)
quest_progress(id=3, player=0x123, ...)
quest_progress(id=3, player=0x123, ...)
quest_progress(id=3, player=0x123, ...)
```
At this point we can emit the event with the parent quest and it will be considered completed:
```cairo
quest_progress(id=4, player=0x123, ...)
```