Skip to content

Timeline System

The Timeline System enables you to create orchestrated sequences of actions that execute at specific tick intervals. Perfect for cutscenes, story sequences, automated events, and any content requiring precise timing.

🛠️ Visual Timeline Builder - Create timeline configurations with an easy-to-use visual interface and action builder

Timelines provide:

  • Tick-Based Scheduling: Execute actions at specific game ticks
  • Two Action Types: Commands and MoLang scripts
  • Multiple Actions Per Tick: Run several actions simultaneously
  • Player Context: All actions execute with player context
  • Task & Levelable Integration: Launch timelines as rewards

Common Use Cases:

  • Cutscene sequences with dialogue and effects
  • Timed story events
  • Automated server announcements
  • Complex event orchestration
  • Tutorial sequences

Timelines are simple: a map of tick numbers to actions.

{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>Timeline started!')"
},
"20": {
"type": "command",
"command": "playsound minecraft:entity.experience_orb.pickup player @a"
},
"40": [
{
"type": "molang",
"script": "q.player.snowstorm_particle('cobblemon:hit', -585.0, 80.0, -20.0)"
},
{
"type": "command",
"command": "particle minecraft:explosion_emitter ~ ~ ~ 0 0 0 0 1"
}
]
}
}

Structure:

  • timeline - Object containing tick-to-actions mappings
  • Ticks are keys (as strings: "0", "20", "40")
  • Values are either single actions or arrays of actions

Tick Count:

  • 20 ticks = 1 second
  • Tick 0 = immediately when timeline launches
  • Tick 100 = 5 seconds after launch

Timelines support two action types:

Execute Minecraft commands with \{\{player\}\} placeholder:

{
"type": "command",
"command": "give {player} minecraft:diamond 1"
}

Placeholders:

  • \{\{player\}\} - Replaced with player’s username

Command Context:

  • Executes as server console
  • Has full permissions
  • Can use selectors (@a, @p, etc.)

Examples:

{
"type": "command",
"command": "playsound minecraft:entity.tnt.primed block {player} -584.00 80.11 -20.67 0.5 1"
}
{
"type": "command",
"command": "particle minecraft:explosion_emitter -584.00 80.14 -20.62 0 0 0 0 1 normal"
}

Execute MoLang scripts with full player context:

{
"type": "molang",
"script": "q.player.tell_minimessage('<gold>Hello world!')"
}

Available Functions:

  • All q.player.* MoLang functions
  • All npc.* MoLang functions (if NPC entity is in scope)
  • Full world and entity queries

Examples:

{
"type": "molang",
"script": "q.player.snowstorm_particle('cobblemon:hit', -585.0, 80.0, -20.0)"
}
{
"type": "molang",
"script": "q.player.remove_item('minecraft:tnt', 1)"
}
{
"type": "molang",
"script": "q.player.add_flag('cutscene_complete')"
}

When one action happens at a tick:

{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>Timeline started!')"
},
"20": {
"type": "command",
"command": "playsound minecraft:ui.button.click player {player}"
}
}
}

When multiple actions happen simultaneously:

{
"timeline": {
"55": [
{
"type": "command",
"command": "execute as {player} run flag add test"
},
{
"type": "command",
"command": "playsound minecraft:entity.generic.explode block {player} -584.00 80.11 -20.67 0.5 1"
},
{
"type": "molang",
"script": "q.player.snowstorm_particle('cobblemon:hit', -585.0, 80.0, -20.0)"
},
{
"type": "molang",
"script": "q.player.remove_item('minecraft:tnt', 1)"
},
{
"type": "command",
"command": "particle minecraft:explosion_emitter -584.00 80.14 -20.62 0 0 0 0 1 normal"
}
]
}
}

All actions in the array execute on tick 55.


Real timeline from production config:

Config: config/journey/timelines/test.json

{
"timeline": {
"5": {
"type": "molang",
"script": "q.player.tell_minimessage('<Professor Willow> Agh... The TNT wont ignite!')"
},
"35": {
"type": "molang",
"script": "q.player.tell_minimessage('<Professor Willow> Ah! Got it')"
},
"40": {
"type": "command",
"command": "playsound minecraft:entity.tnt.primed block {player} -584.00 80.11 -20.67 0.5 1"
},
"55": [
{
"type": "command",
"command": "execute as {player} run flag add test"
},
{
"type": "command",
"command": "playsound minecraft:entity.generic.explode block {player} -584.00 80.11 -20.67 0.5 1"
},
{
"type": "molang",
"script": "q.player.snowstorm_particle('cobblemon:hit', -585.0, 80.0, -20.0)"
},
{
"type": "molang",
"script": "q.player.remove_item('minecraft:tnt', 1)"
},
{
"type": "command",
"command": "particle minecraft:explosion_emitter -584.00 80.14 -20.62 0 0 0 0 1 normal"
}
]
}
}

Timeline Breakdown:

  • Tick 5 (0.25s): Professor Willow speaks (dialogue 1)
  • Tick 35 (1.75s): Professor Willow speaks (dialogue 2)
  • Tick 40 (2s): TNT primed sound plays
  • Tick 55 (2.75s):
    • Add flag to player
    • Play explosion sound
    • Spawn particle effect
    • Remove TNT item
    • Spawn explosion particle

Duration: 55 ticks = 2.75 seconds total


{
"rewards": [
{
"type": "timeline",
"data": {
"timeline": "journey:cutscene_intro"
}
}
]
}
{
"level": 10,
"required_experience": 1000,
"rewards": [
{
"type": "timeline",
"data": {
"timeline": "journey:level_10_celebration"
}
}
]
}
q.player.launch_timeline('journey:my_timeline')

Usage in task rewards:

{
"type": "script",
"data": {
"scripts": [
"q.player.launch_timeline('journey:quest_complete_cutscene');"
]
}
}

Timeline resource locations follow Minecraft namespace conventions:

journey:test
journey:cutscene_intro
journey:quest_complete
mymod:custom_event

Format: namespace:timeline_id

File Location:

config/journey/timelines/test.json → journey:test
config/journey/timelines/cutscene.json → journey:cutscene

Calculate tick values for precise timing:

20 ticks = 1 second
10 ticks = 0.5 seconds
5 ticks = 0.25 seconds
1 tick = 0.05 seconds (50ms)
1 second = 20 ticks
2 seconds = 40 ticks
5 seconds = 100 ticks
10 seconds = 200 ticks
1 minute = 1200 ticks
{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>Starting...')"
},
"20": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>1 second')"
},
"40": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>2 seconds')"
},
"100": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>5 seconds')"
},
"200": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>10 seconds - Done!')"
}
}
}

{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<NPC Name> Hello there!')"
},
"40": {
"type": "molang",
"script": "q.player.tell_minimessage('<NPC Name> How can I help you today?')"
},
"80": {
"type": "molang",
"script": "q.player.tell_minimessage('<NPC Name> Feel free to ask questions.')"
}
}
}

Pacing: 2-second gaps between dialogue lines.


{
"timeline": {
"0": [
{
"type": "command",
"command": "playsound minecraft:entity.firework_rocket.launch player @a ~ ~ ~"
},
{
"type": "command",
"command": "particle minecraft:firework ~ ~1 ~ 0.5 0.5 0.5 0.1 50"
}
],
"20": [
{
"type": "command",
"command": "playsound minecraft:entity.firework_rocket.blast player @a ~ ~ ~"
},
{
"type": "command",
"command": "particle minecraft:explosion ~ ~2 ~ 0 0 0 0 1"
}
]
}
}

Effect: Firework launch sound + particles, then explosion.


{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold><bold>REWARD INCOMING!')"
},
"20": {
"type": "command",
"command": "playsound minecraft:entity.player.levelup player {player}"
},
"40": [
{
"type": "command",
"command": "give {player} minecraft:diamond 5"
},
{
"type": "molang",
"script": "q.player.tell_minimessage('<green>You received 5 Diamonds!')"
},
{
"type": "command",
"command": "particle minecraft:totem_of_undying ~ ~1 ~ 0.5 0.5 0.5 0.1 20"
}
]
}
}

{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<gray>Checking permissions...')"
},
"40": {
"type": "molang",
"script": "q.player.has_flag('admin_access') ? q.player.tell_minimessage('<green>Access Granted!') : q.player.tell_minimessage('<red>Access Denied!')"
},
"60": {
"type": "molang",
"script": "q.player.has_flag('admin_access') ? q.player.execute_command('tp @s 100 70 200') : 0.0"
}
}
}

Timeline configurations are stored in:

config/journey/timelines/<name>.json

File Structure:

config/
journey/
timelines/
test.json
cutscene_intro.json
quest_complete.json
level_up_celebration.json

{
"name": "Complete the Trial",
"tasks": [],
"rewards": [
{
"type": "timeline",
"data": {
"timeline": "journey:trial_complete"
}
},
{
"type": "currency",
"data": {
"currency": "impactor:pokedollars",
"amount": 1000
}
}
]
}
{
"level": 50,
"required_experience": 50000,
"rewards": [
{
"type": "timeline",
"data": {
"timeline": "journey:mastery_achieved"
}
}
]
}

Zone Entry Script:

journey:zone_entry_timeline

Timeline:

{
"timeline": {
"0": {
"type": "molang",
"script": "q.player.tell_minimessage('<gold>Welcome to the Sacred Grove!')"
},
"40": {
"type": "molang",
"script": "q.player.snowstorm_particle('cobblemon:sparkle', 0.0, 2.0, 0.0)"
}
}
}

Space dialogue appropriately:

  • 2-3 seconds (40-60 ticks) between messages
  • Longer for important/complex messages

Synchronize audio and visuals:

"40": [
{"type": "command", "command": "playsound ..."},
{"type": "command", "command": "particle ..."}
]

Test timing in-game:

  • Server lag can affect timing
  • Test on production server, not local

Use MoLang for player-specific actions:

// Good
q.player.tell_minimessage('<gold>Message')
// Avoid command when MoLang works
/tellraw {player} ...

Use commands for world effects:

{
"type": "command",
"command": "particle minecraft:explosion ~ ~ ~ 0 0 0 0 1"
}

Batch simultaneous actions:

"55": [
{"type": "command", "command": "sound..."},
{"type": "molang", "script": "particle..."},
{"type": "molang", "script": "flag..."}
]

Descriptive file names:

quest_complete_celebration.json
zone_entry_dialogue.json
level_milestone_50.json

Document complex timelines: Add comments in your planning docs:

Tick 0: Intro message
Tick 40: Sound effect
Tick 55: Explosion + flag + item removal

✅ Execute actions at specific ticks ✅ Support commands and MoLang scripts ✅ Run multiple actions per tick ✅ Launch per-player (each player gets own timeline instance) ✅ Work with \{player\} placeholder in commands

No pausing/resuming - Timelines run to completion once started ❌ No branching logic - Use MoLang ternary in scripts for simple conditions ❌ No loops - Timelines execute once ❌ No player interaction mid-timeline - Can’t wait for player input ❌ No cancellation - Can’t stop a timeline after launch

For complex logic: Use tasks, zones, or combination of systems.


The Timeline System provides precise timing control for orchestrated events. Combine with tasks, levelables, and zones to create immersive scripted experiences.