Skip to content

Molang Scripting

Journey extends Cobblemon’s powerful Molang scripting system with custom functions for creating dynamic, conditional logic in tasks, zones, timelines, and other systems. This guide covers the proper Molang language syntax and all available Journey-specific functions.

  1. Molang Language Fundamentals
  2. Journey Player Functions
  3. Journey NPC Functions
  4. Cobblemon Core Functions
  5. Advanced Molang Techniques

Molang is a simple expression-based language designed for fast, data-driven calculation of values at run-time. It uses C-family syntax and is case-insensitive (except for strings).

Reference: Bedrock Dev Molang Documentation

# Function calls
math.sin(query.life_time * 180.0)
math.random(0, 100)
# Conditional expressions (ternary operator)
query.health > 10 ? 1.0 : 0.0
# Boolean logic
query.health > 50 && query.is_on_ground
# Comparison operators
query.health >= query.max_health
query.life_time != 0
# All numbers are treated as floating-point
42
3.14159
-25.5
0.0
# Booleans are converted to numbers: false = 0.0, true = 1.0
true # becomes 1.0
false # becomes 0.0
# Boolean expressions
query.health > 0 # evaluates to 1.0 or 0.0
query.is_baby == false # evaluates to 1.0 or 0.0
# Strings are case-sensitive and enclosed in single quotes
'Hello World'
'minecraft:diamond'
'task_complete'
10 + 5 # Addition: 15
10 - 5 # Subtraction: 5
10 * 5 # Multiplication: 50
10 / 5 # Division: 2
10 < 5 # Less than: 0.0 (false)
10 <= 10 # Less than or equal: 1.0 (true)
10 > 5 # Greater than: 1.0 (true)
10 >= 10 # Greater than or equal: 1.0 (true)
10 == 10 # Equal: 1.0 (true)
10 != 5 # Not equal: 1.0 (true)
true && false # Logical AND: 0.0 (false)
true || false # Logical OR: 1.0 (true)
!true # Logical NOT: 0.0 (false)
# Ternary operator: condition ? value_if_true : value_if_false
query.health > 10 ? 'healthy' : 'injured'
query.is_baby ? 0.5 : 1.0

These functions are available when the context includes a player (e.g., in task filters, rewards, timeline conditions). All functions are called on the player object in Molang scripts.

# Check if a player has an active task
q.player.has_task('namespace:task_id') # Returns 1.0 if task is active, 0.0 if not
# Check if a player has an active subtask
q.player.has_subtask('namespace:task_id', 'subtask_name') # Returns 1.0 if subtask exists, 0.0 if not
# Check if a player has completed a specific task
q.player.has_completed_task('namespace:task_id') # Returns 1.0 if completed, 0.0 if not
# Check if a player has completed a specific subtask
q.player.has_completed_subtask('namespace:task_id', 'subtask_name') # Returns 1.0 if completed, 0.0 if not
# Start a new task for the player
q.player.start_task('namespace:task_id') # Returns 1.0 on success, 0.0 on failure
# Get the player's Minecraft XP level
q.player.level # Returns XP level as number (e.g., 30.0)
# Check if player has an item (with optional count)
q.player.has_item('minecraft:diamond') # Returns 1.0 if has at least 1
q.player.has_item('minecraft:diamond', 5) # Returns 1.0 if has at least 5
# Remove items from player's inventory
q.player.remove_item('minecraft:diamond', 1) # Removes 1 diamond
# Get player's Pokédex data structure
q.player.pokedex() # Returns pokedex struct
# Get player's starter Pokémon data
q.player.starter_pokemon() # Returns starter pokemon struct or 0.0
# Check if player has a Pokémon matching specific criteria
q.player.has_party_pokemon_matching('species=pikachu') # Returns 1.0 if found, 0.0 if not
# Remove a Pokémon from player's party by slot index
q.player.remove_party_pokemon(0) # Removes Pokémon in slot 0 (first slot)
# Find party slot for a Pokémon matching criteria
q.player.party_slot_for_pokemon('species=pikachu') # Returns slot index (0-5) or -1.0 if not found
# Check if player is in a specific zone
q.player.is_in_zone('zone_uuid_here') # Returns 1.0 if in zone, 0.0 if not
# Check if player has a flag set
q.player.has_flag('flag_name') # Returns 1.0 if flag exists, 0.0 if not
# Add a flag to the player
q.player.add_flag('flag_name')
# Remove a flag from the player
q.player.remove_flag('flag_name')

Note: Flags are boolean only. There is no support for numeric flags, expiry times, or flag values in the current implementation.

# Get the current level of a levelable skill
q.player.levelable_level('levelable_id') # Returns current level as number
# Get the current experience points of a levelable skill
q.player.levelable_experience('levelable_id') # Returns current XP as number
# Check if player has a specific levelable skill unlocked
q.player.has_levelable('levelable_id') # Returns 1.0 if unlocked, 0.0 if not
# Give a player access to a levelable skill
q.player.give_levelable('levelable_id')
# Add experience to a levelable skill
q.player.progress_levelable('levelable_id', 100) # Adds 100 XP, returns 1.0 on success
# Remove a levelable skill from the player
q.player.remove_levelable('levelable_id')
# Make player start seeing a specific entity
q.player.start_watching_entity('entity_uuid')
# Make player stop seeing a specific entity
q.player.stop_watching_entity('entity_uuid')
# Spawn a snowstorm particle at a position for the player
q.player.snowstorm_particle('particle_id', x, y, z)
# Play an animation on an entity that only this player can see
q.player.play_per_player_entity_animation('entity_uuid', 'animation_name') # Returns 1.0 on success
# Apply a force push to the player
q.player.push(x, y, z, force) # x, y, z = direction vector, force = strength
# Send a formatted message to the player using MiniMessage formatting
q.player.tell_minimessage('<red>Warning!</red> <gold>Something happened</gold>')
# Execute a server command, replacing {player} with the player's name
q.player.execute_command('give {player} minecraft:diamond 1')
# Launch a timeline sequence for the player
q.player.launch_timeline('timeline_name')
# Force the player to exit their current battle
q.player.stop_battle() # Returns 1.0 on success
# Toggle path visualization on/off
q.player.toggle_path_visualization() # Returns 1.0 if enabled, 0.0 if disabled
# Show or hide path visualization
q.player.show_path_visualization(1.0) # 1.0 to show, 0.0 to hide
q.player.show_path_visualization(0.0)
# Preview a specific path
q.player.preview_path('path_id') # Returns 1.0 on success, 0.0 if path not found

The quest backpack is a separate inventory for quest-related items that persists across sessions.

# Add an item to the backpack
q.player.backpack_add_item('minecraft:diamond') # Adds 1 item, returns 1.0 on success
q.player.backpack_add_item('minecraft:diamond', 5) # Adds 5 items
# Check if backpack has an item
q.player.backpack_has_item('minecraft:diamond') # Returns 1.0 if has at least 1
q.player.backpack_has_item('minecraft:diamond', 5) # Returns 1.0 if has at least 5
# Remove items from backpack
q.player.backpack_remove_item('minecraft:diamond', 1) # Removes 1, returns count removed
# Count items in backpack
q.player.backpack_count_item('minecraft:diamond') # Returns count as number
# Check free slots
q.player.backpack_free_slots() # Returns number of empty slots
# Clear all items
q.player.backpack_clear() # Returns 1.0
# Open backpack GUI for player
q.player.backpack_open() # Returns 1.0
# Configured item functions (use item IDs from config)
q.player.backpack_give_configured('quest_key', 1) # Give configured item
q.player.backpack_has_configured('quest_key', 1) # Check for configured item
q.player.backpack_remove_configured('quest_key', 1) # Remove configured item

Apply and manage temporary buffs on players.

# Check if player has a specific buff
q.player.has_buff('speed_boost') # Returns 1.0 if buff active
# Get buff details
q.player.buff_amplifier('speed_boost') # Returns amplifier level or -1.0
q.player.buff_remaining_ticks('speed_boost') # Returns remaining ticks or -1.0
q.player.buff_count('speed_boost') # Returns count of this buff type
# Apply a buff (duration in ticks, -1 for infinite)
q.player.apply_buff('speed_boost') # Default duration, amplifier 0
q.player.apply_buff('speed_boost', 1200) # 1 minute (1200 ticks)
q.player.apply_buff('speed_boost', 1200, 2) # Duration with amplifier 2
q.player.apply_buff('speed_boost', 1200, 2, 'quest') # With source tag
# Remove buffs
q.player.remove_buff('speed_boost') # Remove by ID, returns count removed
q.player.remove_buff_by_source('quest') # Remove all buffs from source
q.player.clear_buffs() # Remove all buffs, returns count

Control cinematic cutscene playback.

# Play a cutscene for the player
q.player.play_cutscene('intro_cutscene') # Returns 1.0 on success
# Stop current cutscene
q.player.stop_cutscene() # Returns 1.0
# Check cutscene state
q.player.in_cutscene() # Returns 1.0 if in cutscene
q.player.cutscene_progress() # Returns 0.0-1.0 progress

Access party information for the player.

# Get party struct (returns struct with party functions)
q.player.player_party()
# Party struct functions:
q.player.player_party().exists() # 1.0 if in a party
q.player.player_party().size() # Number of members
q.player.player_party().is_leader() # 1.0 if player is leader
q.player.player_party().has_member('PlayerName') # 1.0 if member exists
q.player.player_party().leader_name() # Leader's name string
q.player.player_party().name() # Party name string
q.player.player_party().max_members() # Max allowed members
q.player.player_party().is_public() # 1.0 if party is public
# Get the currently active levelable
q.player.active_levelable() # Returns levelable ID or 'none'
# Check if a levelable is currently active
q.player.is_levelable_active('trainer_rank') # Returns 1.0 if active
# Switch the active levelable (for SINGLE_ACTIVE mode)
q.player.switch_active_levelable('trainer_rank') # Returns 1.0 on success
# Get the current levelable mode
q.player.levelable_mode() # Returns 'exclusive', 'single_active', or 'multi_active'

These functions are available in NPC contexts (Cobblemon NPC dialogues, interactions). All functions are called on the npc object.

# Play an animation on the NPC
npc.play_animation('animation_name') # Show to all nearby players
npc.play_animation('animation_name', 'player_uuid') # Show to specific player only
# Spawn a particle effect attached to the NPC
npc.snowstorm_entity_particle('particle_id', 'locator') # All players
npc.snowstorm_entity_particle('particle_id', 'locator', 'player_uuid') # Specific player
# Spawn a particle effect at a position relative to the NPC
npc.snowstorm_particle('particle_id', x, y, z) # All players
npc.snowstorm_particle('particle_id', x, y, z, 'player_uuid') # Specific player
# Make the NPC say a message
npc.say('Hello! I am %npc%!') # %npc% is replaced with NPC name
npc.say('Hello, player!', 'player_uuid') # Send to specific player only
# Get distance between NPC and a specific player
npc.distance_to_player('player_uuid') # Returns distance in blocks
# Start walking a path
npc.walk_path('path_id') # Returns 1.0 on success, 0.0 on failure
# Stop walking current path
npc.stop_walking() # Returns 1.0 on success, 0.0 on failure
# Pause path walking
npc.pause_walking() # Returns 1.0 on success, 0.0 on failure
# Resume path walking
npc.resume_walking() # Returns 1.0 on success, 0.0 on failure
# Check if NPC is currently walking a path
npc.is_walking_path() # Returns 1.0 if walking, 0.0 if not
# Get walking progress percentage
npc.walking_progress() # Returns 0.0-100.0 percentage
# Assign a path to the NPC
npc.assign_path('path_id') # Auto-start enabled by default
npc.assign_path('path_id', 0.0) # Auto-start disabled (0.0 = false)
# Unassign the current path from the NPC
npc.unassign_path() # Returns 1.0 on success
# Check if NPC has an assigned path
npc.has_assigned_path() # Returns 1.0 if has path, 0.0 if not
# Get the assigned path ID
npc.get_assigned_path() # Returns path ID string or empty string

Control per-player NPC visibility with conditional logic.

# Set a visibility condition for all players
npc.set_visibility_condition("q.player.has_flag('can_see_ghosts')")
# Set visibility condition for a specific player
npc.set_player_visibility('player-uuid', "q.player.levelable_level('perception') >= 10")
# Force show/hide for specific player (bypasses conditions)
npc.force_show_to_player('player-uuid') # Returns 1.0 on success
npc.force_hide_from_player('player-uuid') # Returns 1.0 on success
# Check if NPC is visible to a player
npc.is_visible_to_player('player-uuid') # Returns 1.0 if visible
# Force visibility update for all players
npc.update_visibility() # Returns 1.0

Journey integrates with Cobblemon’s extensive Molang functions. For the complete list of Cobblemon functions, refer to Cobblemon’s documentation.

# Basic math
math.abs(-5) # Absolute value: 5
math.ceil(4.2) # Ceiling: 5
math.floor(4.8) # Floor: 4
math.round(4.6) # Round: 5
math.sqrt(16) # Square root: 4
math.pow(2, 3) # Power: 8
# Trigonometric functions
math.sin(90) # Sine
math.cos(0) # Cosine
math.tan(45) # Tangent
# Random functions
math.random() # Random 0.0-1.0
math.random(1, 10) # Random integer 1-10

# Nested conditions for quest eligibility
q.player.has_completed_task('gym_badge_1') &&
q.player.has_completed_task('gym_badge_2') &&
q.player.levelable_level('trainer_rank') >= 25 ?
1.0 : 0.0
# Different behavior per zone
q.player.is_in_zone('pvp_arena_uuid') ?
(q.player.levelable_level('combat') >= 30 ? 1.0 : 0.0) :
q.player.is_in_zone('safe_zone_uuid') ?
1.0 :
0.0
# Check for specific Pokémon conditions
q.player.has_party_pokemon_matching('species=pikachu shiny=true') &&
q.player.has_party_pokemon_matching('species=raichu') ?
1.0 : 0.0
# Find slot and check level
temp.pikachu_slot = q.player.party_slot_for_pokemon('species=pikachu');
temp.pikachu_slot >= 0.0 ? 1.0 : 0.0
# Bad: Multiple calls
q.player.has_completed_task('task1') && q.player.has_completed_task('task2')
# Better: Use boolean logic efficiently
q.player.has_completed_task('task1') && q.player.has_completed_task('task2')
# Check cheaper conditions first
q.player.has_flag('eligible') &&
q.player.has_completed_task('prerequisite') &&
q.player.has_party_pokemon_matching('legendary=true')

Journey’s MoLang implementation is functional but limited compared to what may be described elsewhere. Specifically:

NOT AVAILABLE:

  • query.player.* query accessors (use player.* functions directly)
  • query.npc.* query accessors (use npc.* functions directly)
  • query.world_time, query.time_of_day, query.weather (world state queries)
  • Numeric flags or flag value operations
  • Flag expiry times
  • Player statistics beyond what’s in Journey data

AVAILABLE:

  • All player.* functions listed in this document
  • All npc.* functions listed in this document
  • Standard Cobblemon query functions (see Cobblemon docs)
  • Standard math functions

When events trigger (e.g., POKEMON_CAUGHT, ENTER_ZONE), they provide event-specific data through the q namespace:

# Example: In a POKEMON_CAUGHT event filter
q.pokemon.species.identifier == 'cobblemon:pikachu' && q.pokemon.is_shiny
# Example: In an ENTER_ZONE event filter
q.zone.name == 'Pallet Town'
# Example: In a BATTLE_VICTORY event filter
q.battle.is_wild && q.battle.team.contains_starter

See the Events Documentation for details on what data each event provides.


This documentation reflects the actual implementation of Journey’s MoLang functions as of the current version.