Skip to content

Buff System

Buffs are effects you can apply to players. Speed boosts, regeneration, increased shiny chance, custom particle effects — if you want to give a player a temporary (or permanent) bonus, buffs are how you do it.

Buffs can be granted as task rewards, levelable rewards, through commands, or via Molang scripts. They persist across server restarts and player disconnects.


Journey has four built-in buff types:

Modify Minecraft player attributes like movement speed, attack damage, or max health.

{
"id": "speed_boost",
"type": "attribute",
"name": "Speed Boost",
"description": "Increases movement speed by 20%",
"max_stacks": 1,
"is_debuff": false,
"hidden": false,
"attribute": "minecraft:generic.movement_speed",
"operation": "add_multiplied_base",
"value": 0.2
}

Operations:

  • add_value — Adds a flat value to the attribute
  • add_multiplied_base — Adds a percentage of the base value (0.2 = +20%)
  • add_multiplied_total — Multiplies the final total value

Apply Minecraft potion effects:

{
"id": "regeneration",
"type": "potion",
"name": "Regeneration",
"description": "Slowly restores health",
"max_stacks": 1,
"is_debuff": false,
"hidden": false,
"potion_effect": "minecraft:regeneration",
"show_particles": false,
"show_icon": true,
"ambient": false
}

Any vanilla potion effect works here (minecraft:regeneration, minecraft:speed, minecraft:strength, etc.).

Run Molang scripts when the buff is applied, while it’s active, and when it’s removed:

{
"id": "exploration_aura",
"type": "script",
"name": "Explorer's Aura",
"description": "A sparkle of adventure follows you",
"max_stacks": 1,
"is_debuff": false,
"hidden": false,
"on_apply_script": "q.player.tell_minimessage('<gold>You feel energized!')",
"on_tick_script": "q.player.tell_minimessage('<green>Sparkle!');",
"on_remove_script": "q.player.tell_minimessage('<gray>The energy fades...')",
"tick_interval": 20
}
  • on_apply_script — Runs once when the buff is first applied
  • on_tick_script — Runs every tick_interval ticks while active
  • on_remove_script — Runs once when the buff expires or is removed
  • tick_interval — Ticks between each tick script execution (default: 20 = once per second)

Increase the chance of encountering shiny Pokemon:

{
"id": "shiny_hunter",
"type": "shiny_chance",
"name": "Shiny Hunter",
"description": "Increases shiny encounter chance",
"max_stacks": 3,
"is_debuff": false,
"hidden": false,
"chance_increase": 100.0
}

Multiple shiny buffs stack additively. With max_stacks: 3 and chance_increase: 100.0, a player with 3 stacks gets +300 total shiny chance increase.


All buff types share these fields:

PropertyTypeDefaultDescription
idStringRequiredUnique identifier
typeStringRequiredattribute, potion, script, or shiny_chance
nameStringnullDisplay name shown to the player
descriptionStringnullDescription shown to the player
max_stacksNumber1Maximum simultaneous instances
is_debuffBooleanfalseWhether this is a negative effect
hiddenBooleanfalseWhether to hide from the player’s UI

Duration is in ticks (20 ticks = 1 second):

TicksTime
20010 seconds
60030 seconds
12001 minute
60005 minutes
1200010 minutes
-1Permanent

Amplifier is 0-based and affects each buff type differently:

  • Attribute buffs: Value multiplied by (amplifier + 1). Amplifier 0 = 1x, amplifier 1 = 2x
  • Potion buffs: Passed to the potion effect. Amplifier 0 = Level I, amplifier 1 = Level II
  • Script buffs: Available in scripts as query.amplifier()
  • Shiny chance buffs: Chance multiplied by (amplifier + 1)

When max_stacks is 1, applying the buff again refreshes the duration and updates the amplifier.

When max_stacks is greater than 1, multiple instances can exist simultaneously. Each has its own duration and amplifier. When the max is reached, the oldest instance is refreshed.


{
"type": "buff",
"data": {
"buff_id": "speed_boost",
"duration": 6000,
"amplifier": 0,
"source": "gym_reward"
}
}
{
"type": "buff",
"data": {
"buff_id": "shiny_hunter",
"duration": -1,
"amplifier": 1,
"source": "breeder_levelable"
}
}
q.player.apply_buff('speed_boost', 1200, 0, 'quest_reward')

The source field lets you track where buffs came from:

{
"buff_id": "speed_boost",
"duration": -1,
"source": "explorer_levelable"
}

Benefits:

  • Remove all buffs from a source: q.player.remove_buff_by_source('explorer_levelable')
  • Levelable buffs are auto-removed when the levelable is lost
  • Helps debug which system granted a buff

Naming convention:

  • Levelables: "{name}_levelable"
  • Tasks: "{name}_task"
  • Zones: "{name}_zone"

Buff definitions go in config/journey/buffs/:

config/journey/buffs/
├── speed_boost.json
├── shiny_hunter.json
├── mining_haste.json
└── regeneration.json

CommandDescription
/journey buff apply <player> <buff_id> [duration] [amplifier]Apply a buff
/journey buff remove <player> <buff_id>Remove a specific buff
/journey buff clear <player>Remove all buffs
/journey buff list <player>List active buffs
/journey buff reloadReload buff configs from disk

FunctionReturnsDescription
q.player.has_buff('buff_id')1.0 / 0.0Check if buff is active
q.player.buff_amplifier('buff_id')Number / -1.0Get amplifier level
q.player.buff_remaining_ticks('buff_id')Number / -1.0Get remaining ticks
q.player.buff_count('buff_id')NumberCount active instances
q.player.apply_buff('id', duration, amplifier, 'source')Apply a buff
q.player.remove_buff('buff_id')NumberRemove buff
q.player.remove_buff_by_source('source')Remove all from source
q.player.clear_buffs()NumberRemove all buffs