Event System
Event System
Section titled “Event System”Journey’s Event System enables dynamic, responsive content that reacts to player actions. With 28 event types covering zones, battles, items, and more, you can create sophisticated task systems and interactive experiences.
Event Architecture
Section titled “Event Architecture”How Events Work
Section titled “How Events Work”Journey’s event system uses a publisher-subscriber pattern:
- Event Sources - Game actions trigger events
- Event Listeners - Tasks subscribe to specific event types
- Event Filters - MoLang expressions determine if event matches
- Event Data - Context-specific data via
q.*namespace
{ "event": "POKEMON_CAUGHT", "event_data": {}, "filter": "q.pokemon.species.identifier == 'cobblemon:pikachu'", "target": 5}MoLang Filter Basics
Section titled “MoLang Filter Basics”Use q. prefix for all query paths. Each event provides specific data accessible through this namespace.
// No-param functions (parentheses optional)q.pokemon.levelq.pokemon.is_shinyq.battle.is_wild
// Propertiesq.zone.uuidq.item.id
// Comparisonsq.pokemon.species.identifier == 'cobblemon:pikachu'q.pokemon.level >= 25
// Compound conditionsq.pokemon.is_shiny && q.pokemon.level >= 50Zone Events
Section titled “Zone Events”ENTER_ZONE
Section titled “ENTER_ZONE”Fires when a player enters a defined zone.
Available Data:
| Path | Type | Description |
|---|---|---|
q.zone | Struct | Zone data object |
q.zone.uuid | String | Zone’s unique identifier |
q.zone.name | String | Zone’s display name |
Examples:
{ "event": "ENTER_ZONE", "filter": "q.zone.uuid == '21af4251-ed97-499c-8445-3e6152fbcbb7'", "target": 1}{ "event": "ENTER_ZONE", "filter": "q.zone.name == 'Pallet Town'", "target": 1}LEAVE_ZONE
Section titled “LEAVE_ZONE”Fires when a player exits a zone.
Available Data: Same as ENTER_ZONE
Use Cases:
- Track zone exploration completion
- Time-based challenges (left zone too early)
- Exit confirmation quests
ENTER_ZONE_AREA
Section titled “ENTER_ZONE_AREA”Fires when a player enters a specific sub-area within a zone.
Available Data:
| Path | Type | Description |
|---|---|---|
q.zone | Struct | Parent zone data |
q.area | Struct | Specific area data |
Capture & Evolution Events
Section titled “Capture & Evolution Events”POKEMON_CAUGHT
Section titled “POKEMON_CAUGHT”Fires when a player successfully catches a wild encounter.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Full caught Pokemon data |
q.pokemon.species | Struct | Species data (access identifier via q.pokemon.species.identifier) |
q.pokemon.level | Number | Current level |
q.pokemon.is_shiny | Number | 1.0 if shiny, 0.0 otherwise |
q.pokemon.nature | String | Nature name |
q.pokemon.ability | String | Ability name |
q.pokemon.ivs | Struct | IV values by stat |
q.pokemon.pokeball | String | Ball type used |
Examples:
Catch a specific species:
{ "event": "POKEMON_CAUGHT", "filter": "q.pokemon.species.identifier == 'cobblemon:magikarp'", "target": 1}Catch any shiny:
{ "event": "POKEMON_CAUGHT", "filter": "q.pokemon.is_shiny", "target": 1}Catch high-level Pokemon:
{ "event": "POKEMON_CAUGHT", "filter": "q.pokemon.level >= 50", "target": 5}Catch in a specific zone (using player functions):
{ "event": "POKEMON_CAUGHT", "filter": "q.player.is_in_zone('c106b35a-1058-4aca-809c-b9588c14ba11')", "target": 2}POKEMON_EVOLVE
Section titled “POKEMON_EVOLVE”Fires when a player’s Pokemon evolves.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | The evolved Pokemon (new form) |
q.pokemon.species | Struct | Species data (access identifier via q.pokemon.species.identifier) |
q.pokemon.is_starter | Number | 1.0 if this is the starter |
Examples:
Evolve your starter:
{ "event": "POKEMON_EVOLVE", "filter": "q.pokemon.is_starter", "target": 1}Evolve into a specific species:
{ "event": "POKEMON_EVOLVE", "filter": "q.pokemon.species.identifier == 'cobblemon:charizard'", "target": 1}POKEMON_LEVEL_UP
Section titled “POKEMON_LEVEL_UP”Fires when a Pokemon gains a level.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Pokemon that leveled up |
q.pokemon.level | Number | New level after leveling |
q.pokemon.is_starter | Number | 1.0 if starter |
Examples:
Starter reaches level 16:
{ "event": "POKEMON_LEVEL_UP", "filter": "q.pokemon.is_starter && q.pokemon.level >= 16", "target": 1}Any Pokemon reaches max level:
{ "event": "POKEMON_LEVEL_UP", "filter": "q.pokemon.level >= 100", "target": 1}HATCH_EGG
Section titled “HATCH_EGG”Fires when a Pokemon egg hatches.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | The hatched Pokemon |
q.pokemon.ivs | Struct | IV values |
Examples:
Hatch any egg:
{ "event": "HATCH_EGG", "filter": "1.0", "target": 5}Hatch a shiny:
{ "event": "HATCH_EGG", "filter": "q.pokemon.is_shiny", "target": 1}STARTER_CHOSEN
Section titled “STARTER_CHOSEN”Fires when a player selects their starter Pokemon.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Chosen starter Pokemon |
Example:
{ "event": "STARTER_CHOSEN", "filter": "1.0", "target": 1}Battle Events
Section titled “Battle Events”BATTLE_VICTORY
Section titled “BATTLE_VICTORY”Fires when a player wins a battle.
Available Data:
| Path | Type | Description |
|---|---|---|
q.battle | Struct | Battle information |
q.battle.is_wild | Number | 1.0 for wild battles |
q.battle.is_pvn | Number | 1.0 for NPC trainer battles |
q.battle.is_pvp | Number | 1.0 for player vs player |
q.battle.team | Struct | Player’s team in battle |
q.battle.team.pokemon(index) | Struct | Get team Pokemon by index (0-5) |
q.battle.team.contains_starter | Number | 1.0 if starter participated |
Examples:
Win any battle:
{ "event": "BATTLE_VICTORY", "filter": "1.0", "target": 1}Win wild battles:
{ "event": "BATTLE_VICTORY", "filter": "q.battle.is_wild", "target": 10}Win NPC trainer battles:
{ "event": "BATTLE_VICTORY", "filter": "q.battle.is_pvn", "target": 5}Win using your starter:
{ "event": "BATTLE_VICTORY", "filter": "q.battle.team.contains_starter", "target": 10}Win PvP battles:
{ "event": "BATTLE_VICTORY", "filter": "q.battle.is_pvp", "target": 3}BATTLE_FLED
Section titled “BATTLE_FLED”Fires when a player flees from battle.
Available Data: Same as BATTLE_VICTORY
Example:
{ "event": "BATTLE_FLED", "filter": "q.battle.is_wild", "target": 1}MOVE_USED
Section titled “MOVE_USED”Fires when a move is used in battle.
Available Data:
| Path | Type | Description |
|---|---|---|
q.event.move | Struct | Move data |
q.event.user | Struct | Pokemon that used the move |
q.event.battle | Struct | Battle context |
Example:
{ "event": "MOVE_USED", "filter": "1.0", "target": 50}SUPER_EFFECTIVE_MOVE_USED
Section titled “SUPER_EFFECTIVE_MOVE_USED”Fires when a super-effective move lands.
Available Data: Same as MOVE_USED
Examples:
Land any super-effective hit:
{ "event": "SUPER_EFFECTIVE_MOVE_USED", "filter": "1.0", "target": 10}POKEMON_FAINTED
Section titled “POKEMON_FAINTED”Fires when an opponent’s Pokemon faints (during your battle).
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | The fainted Pokemon |
Pokemon Interaction Events
Section titled “Pokemon Interaction Events”POKEMON_SHOULDER_MOUNTED
Section titled “POKEMON_SHOULDER_MOUNTED”Fires when a Pokemon is placed on the player’s shoulder.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Shouldered Pokemon |
POKEMON_SENT_OUT
Section titled “POKEMON_SENT_OUT”Fires when a Pokemon is sent out of its Pokeball.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Sent out Pokemon |
POKEMON_HEALED
Section titled “POKEMON_HEALED”Fires when a Pokemon is healed.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Healed Pokemon |
POKEMON_RELEASED
Section titled “POKEMON_RELEASED”Fires when a Pokemon is released into the wild.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Released Pokemon |
POKEMON_SCANNED
Section titled “POKEMON_SCANNED”Fires when a Pokemon is scanned with a Pokedex.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Scanned Pokemon |
POKEMON_NICKNAMED
Section titled “POKEMON_NICKNAMED”Fires when a Pokemon is given a nickname.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Nicknamed Pokemon |
q.nickname | String | The new nickname |
FRIENDSHIP_UPDATED
Section titled “FRIENDSHIP_UPDATED”Fires when a Pokemon’s friendship value changes.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Pokemon with updated friendship |
q.new_friendship | Number | New friendship value |
Special Mechanic Events
Section titled “Special Mechanic Events”MEGA_EVOLUTION
Section titled “MEGA_EVOLUTION”Fires when a Pokemon mega evolves in battle.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Mega evolved Pokemon |
TERASTALLIZATION
Section titled “TERASTALLIZATION”Fires when a Pokemon terastallizes in battle.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Terastallized Pokemon |
ZPOWER_USED
Section titled “ZPOWER_USED”Fires when Z-Power is activated.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Pokemon using Z-Power |
FOSSIL_REVIVED
Section titled “FOSSIL_REVIVED”Fires when a fossil is revived into a Pokemon.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Revived fossil Pokemon |
Item & Block Events
Section titled “Item & Block Events”ITEM_PICKUP
Section titled “ITEM_PICKUP”Fires when a player picks up an item from the ground.
Available Data:
| Path | Type | Description |
|---|---|---|
q.item | Struct | Picked up item |
q.item.id | String | Item registry ID |
q.item.count | Number | Stack count |
Progress Note: Progress is increased by the item count, not just 1.
Examples:
Pick up a specific item:
{ "event": "ITEM_PICKUP", "filter": "q.item.id == 'cobblemon:pokedex_green'", "target": 1}Pick up diamonds:
{ "event": "ITEM_PICKUP", "filter": "q.item.id == 'minecraft:diamond'", "target": 10}ITEM_THROW
Section titled “ITEM_THROW”Fires when a player drops/throws an item.
Available Data:
| Path | Type | Description |
|---|---|---|
q.item | Struct | Thrown item |
q.item.id | String | Item registry ID |
q.item.count | Number | Stack count |
ENTITY_INTERACT
Section titled “ENTITY_INTERACT”Fires when a player right-clicks an entity.
Available Data:
| Path | Type | Description |
|---|---|---|
q.entity | Struct | Interacted entity |
q.entity.uuid | String | Entity UUID |
q.event.hand | String | ”MAIN_HAND” or “OFF_HAND” |
q.pokemon | Struct | Pokemon data (if entity is Pokemon) |
Examples:
Interact with specific NPC:
{ "event": "ENTITY_INTERACT", "filter": "q.entity.uuid == 'bb030064-870d-4513-b49b-bba5c92b19c1'", "target": 1}Interact with NPC after completing quest:
{ "event": "ENTITY_INTERACT", "filter": "q.entity.uuid == '2de91ae9-e18e-4419-bffe-43d1b6cdbb2e' && q.player.has_completed_task('journey:evolve_starter')", "target": 1}BREAK_BLOCK
Section titled “BREAK_BLOCK”Fires when a player breaks a block.
Available Data:
| Path | Type | Description |
|---|---|---|
q.block | Struct | Broken block |
q.block.id | String | Block registry ID |
q.block.pos.x | Number | X coordinate |
q.block.pos.y | Number | Y coordinate |
q.block.pos.z | Number | Z coordinate |
Example:
{ "event": "BREAK_BLOCK", "filter": "q.block.id == 'minecraft:diamond_ore'", "target": 5}BLOCK_PLACED
Section titled “BLOCK_PLACED”Fires when a player places a block.
Available Data: Same as BREAK_BLOCK
BLOCK_USE
Section titled “BLOCK_USE”Fires when a player right-clicks a block.
Available Data: Same as BREAK_BLOCK
Resource Events
Section titled “Resource Events”EXPERIENCE_CANDY_USED
Section titled “EXPERIENCE_CANDY_USED”Fires when experience candy is fed to a Pokemon.
Available Data:
| Path | Type | Description |
|---|---|---|
q.pokemon | Struct | Pokemon that received exp |
q.experience | Number | Amount of exp gained |
APRICORN_HARVESTED
Section titled “APRICORN_HARVESTED”Fires when an apricorn is harvested from a tree.
Available Data:
| Path | Type | Description |
|---|---|---|
q.apricorn.color | String | Apricorn color name |
BERRY_HARVESTED
Section titled “BERRY_HARVESTED”Fires when a berry is harvested.
EGG_COLLECTED
Section titled “EGG_COLLECTED”Fires when an egg is collected from breeding.
Utility Events
Section titled “Utility Events”RUN_COMMAND
Section titled “RUN_COMMAND”Fires when a player runs a command.
Available Data:
| Path | Type | Description |
|---|---|---|
q.event.command | String | The full command |
q.event.matches(cmd) | Number | 1.0 if exact match |
q.event.contains(text) | Number | 1.0 if command contains text |
Examples:
Run specific command:
{ "event": "RUN_COMMAND", "filter": "q.event.matches('/spawn')", "target": 1}Run any healing command:
{ "event": "RUN_COMMAND", "filter": "q.event.contains('pokeheal')", "target": 1}KILL_ENTITY
Section titled “KILL_ENTITY”Fires when a player kills an entity.
Available Data:
| Path | Type | Description |
|---|---|---|
q.event.entity | Struct | Killed entity |
Player Functions in Filters
Section titled “Player Functions in Filters”These functions are available in any event filter for checking player state:
| Function | Description |
|---|---|
q.player.is_in_zone('zone-uuid') | Check if player is in zone |
q.player.has_task('journey:task_id') | Check if task is currently active |
q.player.has_subtask('journey:task_id', 'subtask_name') | Check if subtask is active |
q.player.has_completed_task('journey:task_id') | Check if task is completed |
q.player.has_flag('flag_name') | Check if flag is set |
q.player.level | Player’s Minecraft XP level |
q.player.levelable_level('levelable_id') | Get level for a levelable |
q.player.has_levelable('levelable_id') | Check if player has a levelable |
Examples:
Zone-restricted catching:
{ "event": "POKEMON_CAUGHT", "filter": "q.player.is_in_zone('beach-zone-uuid')", "target": 5}Quest chain progression:
{ "event": "ENTITY_INTERACT", "filter": "q.entity.uuid == 'npc-uuid' && q.player.has_completed_task('journey:intro_quest')", "target": 1}Flag-based content:
{ "event": "ENTER_ZONE", "filter": "q.zone.name == 'Elite Four' && q.player.has_flag('elite_four_access')", "target": 1}Pokemon Data Reference
Section titled “Pokemon Data Reference”When q.pokemon is available, these properties/functions are accessible (no parentheses needed for no-param calls):
| Property | Return | Description |
|---|---|---|
species | String | Species ID (e.g., cobblemon:pikachu) |
level | Number | Current level (1-100) |
is_shiny | Number | 1.0 if shiny |
is_wild | Number | 1.0 if wild |
is_in_party | Number | 1.0 if in party |
is_starter | Number | 1.0 if player’s starter |
friendship | Number | Friendship value (0-255) |
nature | String | Nature name |
ability | String | Ability name |
gender | String | MALE, FEMALE, or GENDERLESS |
pokeball | String | Ball type used |
form | String | Form name |
nickname | String | Custom nickname |
ivs | Struct | IV values per stat |
evs | Struct | EV values per stat |
tera_type | String | Tera type |
held_item | Struct | Equipped item |
has_aspect('aspect') | Number | 1.0 if has aspect (requires param) |
is_type('type') | Number | 1.0 if has type (requires param) |
can_evolve | Number | 1.0 if can evolve |
IV/EV Access:
q.pokemon.ivs.hpq.pokemon.ivs.attackq.pokemon.ivs.defenceq.pokemon.ivs.special_attackq.pokemon.ivs.special_defenceq.pokemon.ivs.speedFilter Best Practices
Section titled “Filter Best Practices”- Use
q.prefix consistently - No-param functions don’t need parentheses:
q.pokemon.levelworks - Functions with params need them:
q.player.is_in_zone('uuid') - Test with simple filter first:
"filter": "1.0" - Use
&&for AND,||for OR - Compare strings with
== - Numbers return as doubles (1.0, 0.0)
Don’ts
Section titled “Don’ts”- Don’t use
query.prefix (useq.) - Don’t add semicolons to filters
- Don’t use camelCase for functions (
has_flagnothasFlag) - Don’t assume paths exist without testing
Testing Filters
Section titled “Testing Filters”- Start simple:
"filter": "1.0" - Add one condition at a time
- Test in-game after each addition
- Check server logs for MoLang errors
Complete Event List
Section titled “Complete Event List”| Event | Category | Description |
|---|---|---|
| ENTER_ZONE | Zone | Player enters zone |
| LEAVE_ZONE | Zone | Player exits zone |
| ENTER_ZONE_AREA | Zone | Player enters sub-area |
| POKEMON_CAUGHT | Capture | Pokemon caught |
| POKEMON_EVOLVE | Evolution | Pokemon evolves |
| POKEMON_LEVEL_UP | Training | Pokemon gains level |
| HATCH_EGG | Breeding | Egg hatches |
| STARTER_CHOSEN | Starter | Starter selected |
| BATTLE_VICTORY | Battle | Battle won |
| BATTLE_FLED | Battle | Fled from battle |
| MOVE_USED | Battle | Move used |
| SUPER_EFFECTIVE_MOVE_USED | Battle | Super effective hit |
| POKEMON_FAINTED | Battle | Pokemon fainted |
| MEGA_EVOLUTION | Mechanic | Mega evolution |
| TERASTALLIZATION | Mechanic | Terastallization |
| ZPOWER_USED | Mechanic | Z-Power used |
| FOSSIL_REVIVED | Mechanic | Fossil revived |
| POKEMON_SHOULDER_MOUNTED | Interaction | Shoulder mount |
| POKEMON_SENT_OUT | Interaction | Sent from ball |
| POKEMON_HEALED | Interaction | Pokemon healed |
| POKEMON_RELEASED | Interaction | Pokemon released |
| POKEMON_SCANNED | Interaction | Pokedex scan |
| POKEMON_NICKNAMED | Interaction | Named Pokemon |
| FRIENDSHIP_UPDATED | Interaction | Friendship changed |
| ITEM_PICKUP | Item | Item picked up |
| ITEM_THROW | Item | Item dropped |
| ENTITY_INTERACT | Entity | Entity clicked |
| BREAK_BLOCK | Block | Block broken |
| BLOCK_PLACED | Block | Block placed |
| BLOCK_USE | Block | Block used |
| EXPERIENCE_CANDY_USED | Resource | Candy used |
| APRICORN_HARVESTED | Resource | Apricorn harvested |
| BERRY_HARVESTED | Resource | Berry harvested |
| EGG_COLLECTED | Resource | Egg collected |
| RUN_COMMAND | Utility | Command run |
| KILL_ENTITY | Utility | Entity killed |