Skip to content
Xander Forrest edited this page Jul 22, 2024 · 10 revisions

Quests, or Objectives, are a common way to define actions such as catching a Pokemon across Roanoke Development Mods. Quests are defined using JSON.

Common Quest Attributes

Quests share various common attributes, for instance:

  • "type" - the type of Quest. For instance, a "BreakBlockQuest" pertains to tracking what blocks a Player has broken. "CatchPokemonQuest" tracks what Pokemon a Player is catching. Different Quest types have some specific values that are discussed in their section below.
  • "id" - a unique ID for the quest, this is used when saving and loading states. Everything can be changed, even after you've launched a quest on the server, except for the ID. Changing this ID would result in all previous progress being lost.
  • "name" - a MiniMessage format display name for the quest, for instance, "<light_purple>A Purple-y Quest"

Minecraft Quests

Break Block Quest

{
  "type": "BreakBlockQuest",
  "name": "<bold>Boldly Break Blocks",
  "id": "auniqueid",
  "block": "minecraft:stone",
  "taskMessage": "Mine a stack of Stone",
  "amount": 64
}

BreakBlockQuest's unique attribute is "block", which should be a string in the Minecraft Resource Identifier format. You can find these on the Minecraft Wiki, or by using /give minecraft: and tab completing. Any mod identifiers can be used, i.e. "cobblemon:" as well.

As with other quests, "amount" is an integer used to determine when the quest is complete.

"taskMessage" is used to describe the Quest quickly in places like scoreboards, titles, and item lore in GUIs.

CraftItemQuest

{
  "type": "CraftItemQuest",
  "name": "<bold>Craft Oak Logs",
  "id": "craftoaklogsuniqueid",
  "item": "minecraft:oak_logs",
  "amount": 64
}

The CraftItemQuest's "Task Message" is automatically created, and by default is: "Craft (amount)x (Item Display Name)". The "item" attribute should once again be a Minecraft Resource Identifier for an item.

Cobblemon Quests

CatchPokemonQuest

{
  "type": "CatchPokemonQuest",
  "name": "Picking Lettuce",
  "id": "pickinglettuce",
  "pokeMatch": {
    "species": "cobblemon:bulbasaur"
  },
  "taskMessage": "Catch 3x Bulbasaur",
  "amount": 3
}

The biggest difference with Pokemon related Quests is the "pokeMatch" field. A PokeMatch is a common method to identify parts of a Pokemon. For instance, a species, form, or ability. I highly recommend reading the PokeMatch section in its entirety.

The quickest and easiest way to setup the pokeMatch is by simply adding a "species" field, with the full resource identifier species name, i.e. "cobblemon:charizard". Any field can be left out or set to "" to make it accept any option. For example, to create a Quest that simply tracks catching any Pokemon, you could do this:

{
  "type": "CatchPokemonQuest",
  "name": "Catch A Pokemon!",
  "id": "catchonepokemon",
  "pokeMatch": {
    "species": "any"
  },
  "taskMessage": "Catch A Pokemon!",
  "amount": 1
}

Any Pokemon caught will count towards this Quest. You could also not put the PokeMatch field at all, which would then result in the default PokeMatch being used, which accepts any Pokemon.

As with other Quests, amount is simply the amount of Pokemon matching the PokeMatch to be caught for the Quest to be "complete".

DefeatPokemonQuest

{
  "type": "DefeatPokemonQuest",
  "name": "Bird Hunting",
  "id": "birdhunting",
  "pokeMatch": {
    "species": "cobblemon:spearow"
  },
  "taskMessage": "Defeat 3x Spearow in Battle",
  "amount": 3
}

The DefeatPokemonQuest tracks "defeats" from battles, and only Wild battles. Pokemon killed outside of battle (with swords etc) won't count towards this quest type.

ReleasePokemonQuest

{
  "type": "ReleasePokemonQuest",
  "name": "Throwing Lettuce",
  "id": "throwinglettuce",
  "pokeMatch": {
    "species": "cobblemon:bulbasaur"
  },
  "taskMessage": "Release a Bulbasaur into the wild!",
  "amount": 1
}

Imagine the CatchPokemonQuest, but for releasing.

HarvestApricornQuest

{
    "type": "HarvestApricornQuest",
    "id": "harvestblueapricorns",
    "apricorn": "blue",
    "amount": 3
}

The "apricorn" field represents the Apricorn colour the Quest involves. This could be "black", "blue", "green", "pink", "red", "white", or "yellow".

The Task Message is automatically made, in the format "Harvest (amount)x (Colour) Apricorns".

As with other quests, "amount" is just the amount of Apricorns to be harvested for the quest to be complete.

NicknamePokemonQuest

{
  "type": "NicknamePokemonQuest",
  "name": "Nickname Time",
  "id": "uniqueunickname",
  "pokeMatch": {
    "species": "cobblemon:pikachu"
  },
  "regex": ".*",
  "taskMessage": "Nickname a Pikachu, call it anything!",
  "amount": 1
}

"pokeMatch" is optional, without it, any Pokemon being nicknamed will trigger the Quest to progress. You can use Regex to only accept certain nicknames. The "regex" field is also optional, accepting any name. The default Regex pattern is ".*" which accepts any amount of characters, including none.

TradePokemonQuest

{
  "type": "TradePokemonQuest",
  "name": "Getting a new Bird",
  "id": "uniquetradepokemonid",
  "sentPokemon": {
    "species": "cobblemon:spearow"
  },
  "recievedPokemon": {
    "species": "cobblemon:murkrow"
  },
  "taskMessage": "Trade a Spearow for a Murkrow",
  "amount": 1
}

"sentPokemon" is a PokeMatch the checks the Pokemon the player is sending. "recievedPokemon" is the same but for the recieved Pokemon. Crazy!

Both fields are optional, making this just a check for any trade event.

EvolvePokemonQuest

{
  "type": "EvolvePokemonQuest",
  "name": "Fire Time",
  "id": "evolutionquestunique",
  "preEvolution": {
    "species": "cobblemon:charmander"
  },
  "postEvolution": {
    "species": "cobblemon:charmeleon"
  },
  "taskMessage": "Evolve a Charmander into a Charmeleon",
  "amount": 1
}

Both "preEvolution" and "postEvolution" are optional PokeMatchs. For instance, you could create an EvolvePokemonQuest that simply looks for any Pokemon evolving into an Alolan Pokemon.

More features can and will be added to this, such as checking for certain moves being learned, or whether an item was used to trigger the evolution.

Placeholder Quests

Placeholder Quests provide a quick and powerful way to integrate mods using our Quest system with other 3rd party mods - with no code!

IntPlaceholderQuest

    {
      "type": "IntPlaceholderQuest",
      "name": "<red><bold>Pokemon Trainer",
      "id": "pokemontrainer80",
      "amount": 80,
      "item": {
        "id": "cobblemon:poke_ball"
      },
      "taskMessage": "Catch 80x Different Pokemon",
      "placeholder": "%pokedex:caught%"
    }

The IntPlaceholderQuests parses the "placeholder" field as an integer whole number. Currently, it only supports checking if that number is greater than or equal to the "amount" field. If it is, the Quest is marked as complete.

Other Quests

HasPermissionQuest

    {
      "type": "HasPermissionQuest",
      "name": "<red><bold>Pokemon Battler",
      "id": "defeatatrainer",
      "permission": "trainer.defeat.permission.node"
      "taskMessage": "Defeat an NPC Trainer"
    }

HasPermissionQuest checks if a player has a certain permission (using the LuckPerms API), and if they do, the Quest is marked as complete.

This is a very powerful tool for combining sidemods together without code. For example, when a player defeats an NPC trainer, that player can be given a permission node that is then detected by this Quest.