Buff System
Buff System
Section titled “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.
Buff Types
Section titled “Buff Types”Journey has four built-in buff types:
Attribute Buffs
Section titled “Attribute Buffs”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 attributeadd_multiplied_base— Adds a percentage of the base value (0.2 = +20%)add_multiplied_total— Multiplies the final total value
Potion Buffs
Section titled “Potion Buffs”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.).
Script Buffs
Section titled “Script Buffs”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 appliedon_tick_script— Runs everytick_intervalticks while activeon_remove_script— Runs once when the buff expires or is removedtick_interval— Ticks between each tick script execution (default: 20 = once per second)
Shiny Chance Buffs
Section titled “Shiny Chance Buffs”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.
Common Properties
Section titled “Common Properties”All buff types share these fields:
| Property | Type | Default | Description |
|---|---|---|---|
id | String | Required | Unique identifier |
type | String | Required | attribute, potion, script, or shiny_chance |
name | String | null | Display name shown to the player |
description | String | null | Description shown to the player |
max_stacks | Number | 1 | Maximum simultaneous instances |
is_debuff | Boolean | false | Whether this is a negative effect |
hidden | Boolean | false | Whether to hide from the player’s UI |
Duration & Amplifier
Section titled “Duration & Amplifier”Duration
Section titled “Duration”Duration is in ticks (20 ticks = 1 second):
| Ticks | Time |
|---|---|
200 | 10 seconds |
600 | 30 seconds |
1200 | 1 minute |
6000 | 5 minutes |
12000 | 10 minutes |
-1 | Permanent |
Amplifier
Section titled “Amplifier”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)
Stacking
Section titled “Stacking”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.
Using Buffs as Rewards
Section titled “Using Buffs as Rewards”Task Reward
Section titled “Task Reward”{ "type": "buff", "data": { "buff_id": "speed_boost", "duration": 6000, "amplifier": 0, "source": "gym_reward" }}Levelable Reward
Section titled “Levelable Reward”{ "type": "buff", "data": { "buff_id": "shiny_hunter", "duration": -1, "amplifier": 1, "source": "breeder_levelable" }}Via Molang
Section titled “Via Molang”q.player.apply_buff('speed_boost', 1200, 0, 'quest_reward')Source Tracking
Section titled “Source Tracking”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"
File Location
Section titled “File Location”Buff definitions go in config/journey/buffs/:
config/journey/buffs/├── speed_boost.json├── shiny_hunter.json├── mining_haste.json└── regeneration.jsonCommands
Section titled “Commands”| Command | Description |
|---|---|
/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 reload | Reload buff configs from disk |
Molang Functions
Section titled “Molang Functions”| Function | Returns | Description |
|---|---|---|
q.player.has_buff('buff_id') | 1.0 / 0.0 | Check if buff is active |
q.player.buff_amplifier('buff_id') | Number / -1.0 | Get amplifier level |
q.player.buff_remaining_ticks('buff_id') | Number / -1.0 | Get remaining ticks |
q.player.buff_count('buff_id') | Number | Count active instances |
q.player.apply_buff('id', duration, amplifier, 'source') | — | Apply a buff |
q.player.remove_buff('buff_id') | Number | Remove buff |
q.player.remove_buff_by_source('source') | — | Remove all from source |
q.player.clear_buffs() | Number | Remove all buffs |