Skip to content

ActionEffect System Overview

ActionEffects are Cobblemon’s keyframe-based animation and scripting system. Titan uses them to create complex boss attack sequences with precise timing, damage application, and visual effects.

An ActionEffect is a timeline of keyframes that execute sequentially to create a complete attack or ability. Think of it like a movie script:

  1. Keyframes = Individual actions (stop movement, play animation, show particles, deal damage)
  2. Timeline = Sequence of keyframes in order
  3. Execution = Keyframes run one after another until complete

Each titan move references one ActionEffect timeline.

{
"timeline": [
{
"type": "keyframe_type_1",
"property": "value"
},
{
"type": "keyframe_type_2",
"property": "value"
}
],
"condition": "true"
}

Key Components:

  • timeline - Array of keyframe objects
  • condition - MoLang expression to control execution (optional)

Keyframes execute in order, one at a time:

{
"timeline": [
{"type": "stop_movement", "duration": "2000"}, // Step 1: Freeze titan
{"type": "pause", "pause": 0.5}, // Step 2: Wait 0.5s
{"type": "define_obb", "name": "fireball"}, // Step 3: Define hitbox
{"type": "telegraph_obb", "name": "fireball"}, // Step 4: Show warning
{"type": "damage_obb", "name": "fireball"}, // Step 5: Deal damage
{"type": "pause", "pause": 1.0} // Step 6: End lag
]
}

Execution Flow:

  1. Titan stops moving for 2 seconds
  2. 0.5 second pause
  3. OBB defined (instant)
  4. Telegraph appears (1-2 seconds based on size)
  5. Damage applied to entities in OBB
  6. 1 second recovery pause
  7. Timeline complete

Control attack pacing with:

pause keyframes:

{"type": "pause", "pause": 1.5} // Wait 1.5 seconds

duration properties:

{"type": "stop_movement", "duration": "3000"} // 3000ms = 3s

telegraph_obb auto-timing:

// Telegraph duration calculated from OBB size
{"type": "telegraph_obb", "name": "huge_explosion"} // ~3s warning
{"type": "telegraph_obb", "name": "small_slash"} // ~1s warning

Prevent titan from acting during attack:

{
"timeline": [
{"type": "add_holds", "holds": ["effects"]}, // Lock titan
{"type": "stop_movement", "duration": "2500"},
// ... attack keyframes ...
{"type": "remove_holds", "holds": ["effects"]}, // Unlock titan
{"type": "pause", "pause": 1.0}
]
}

Without holds: Titan could start another attack mid-timeline With holds: Titan locked until remove_holds

Always pair:

  • Start timeline with add_holds
  • End timeline with remove_holds

When an ActionEffect executes, it has access to:

MoLang queries:

  • q.user_position - Titan’s current position
  • q.user_rotation - Titan’s yaw/pitch
  • q.user_health - Current HP
  • q.user_max_health - Max HP

Used in:

  • OBB positioning (positioning: "AT_USER")
  • Conditional keyframes
  • Damage calculations

MoLang queries:

  • q.target_position - Target’s position
  • q.target_distance - Distance to target
  • q.target_exists - Whether target is valid

Used in:

  • OBB positioning (positioning: "AT_TARGET")
  • Conditional execution
  • Distance-based effects

Set variables for complex logic:

{
"timeline": [
{"type": "set_variable", "name": "phase", "value": "2"},
{
"type": "damage_obb",
"name": "fireball",
"damage": "q.variable('phase') * 10" // 20 damage in phase 2
}
]
}

Make keyframes conditional with MoLang:

{
"type": "damage_obb",
"name": "electric_field",
"condition": "q.target_distance <= 5.0" // Only if target close
}

Common Conditions:

  • q.target_distance <= 8.0 - Close range only
  • q.user_health / q.user_max_health < 0.33 - Low HP only
  • q.is_phase(3) - Phase 3 only
  • q.target_exists - Has valid target

Timeline-level condition:

{
"timeline": [...],
"condition": "q.target_distance <= 10.0" // Entire timeline skips if false
}

Play Cobblemon animations:

{"type": "animation", "animation": "special"}

Common Animations:

  • physical - Physical attack
  • special - Special attack
  • status - Status move
  • battle_idle - Return to idle

Custom Animations: Create in pokemon species JSON:

"animations": {
"titan_roar": "animation.pokemon.titan_roar"
}

Use Cobblemon/Minecraft particles:

{
"type": "entity_particles",
"particleType": "minecraft:flame",
"count": 20,
"spread": {"x": 1.0, "y": 1.0, "z": 1.0}
}

Common Particles:

  • minecraft:flame - Fire
  • minecraft:electric_spark - Electric
  • minecraft:dragon_breath - Dragon
  • minecraft:snowflake - Ice
  • minecraft:explosion - Explosion

Play sounds for impact:

{
"type": "sound",
"sound": "entity.generic.explode",
"volume": "1.0",
"pitch": "1.0"
}

Common Sounds:

  • entity.generic.explode - Explosion
  • entity.lightning_bolt.thunder - Thunder
  • entity.ender_dragon.growl - Dragon roar
  • entity.blaze.shoot - Fire attack

Data Pack Structure:

server/
├── data/
│ └── titan/
│ └── action_effects/
│ ├── charizard_inferno_blaze.json
│ ├── mewtwo_psycho_break.json
│ └── ... (30+ effects)

Or:

server/
├── datapacks/
│ └── your_pack/
│ └── data/
│ └── titan/
│ └── action_effects/
│ └── custom_move.json

Format: pokemon_move_name.json

Examples:

  • charizard_inferno_blaze.json
  • mewtwo_psycho_break.json
  • rayquaza_draco_meteor.json
  • lucario_aura_sphere.json
{
"moves": {
"inferno_blaze": {
"name": "Inferno Blaze",
"actionEffect": "titan:charizard_inferno_blaze", // namespace:filename
...
}
}
}

Namespace:

  • titan: - Mod resources or data pack under data/titan/
  • custom: - Data pack under data/custom/

Titan uses 23 Cobblemon keyframes + 8 Titan-specific keyframes:

Standard Cobblemon ActionEffect keyframes:

  • Movement control
  • Animation playback
  • Particle effects
  • Sound effects
  • Entity manipulation
  • Status effects
  • MoLang scripting

See Cobblemon ActionEffect Docs for full reference.

OBB System (3):

  1. define_obb - Create hitbox shape
  2. telegraph_obb - Show ground warning
  3. damage_obb - Deal damage in OBB

Combat System (2):

  1. stop_movement - Freeze titan temporarily
  2. set_vulnerable - Set vulnerability state (RECOVERING/EXHAUSTED)

Damage System (3):

  1. sequenced_damage - Multiple damage pulses
  2. repeating_damage_obb - Continuous damage field
  3. delayed_damage_obb - Damage after delay

See OBB System → for Titan keyframes.

{
"timeline": [
{"type": "add_holds", "holds": ["effects"]},
{"type": "stop_movement", "duration": "2000"},
{"type": "animation", "animation": "special"},
{"type": "pause", "pause": 0.5},
{"type": "define_obb", "name": "flame", "shape": "CONE", "positioning": "IN_FRONT", "distance": "2.5", "halfExtents": {"x": "2.0", "y": "6.0", "z": "2.0"}, "includePitch": true},
{"type": "telegraph_obb", "name": "flame", "telegraphType": "WARNING"},
{"type": "entity_particles", "particleType": "minecraft:flame", "count": 30},
{"type": "sound", "sound": "entity.blaze.shoot", "volume": "1.5", "pitch": "0.8"},
{"type": "damage_obb", "name": "flame", "damage": "15.0", "damageType": "FIRE"},
{"type": "remove_holds", "holds": ["effects"]},
{"type": "pause", "pause": 1.0}
],
"condition": "true"
}

Timeline Breakdown:

  1. Lock titan (2000ms)
  2. Play special animation
  3. 0.5s windup
  4. Define cone hitbox in front
  5. Show warning markers (~1.5s)
  6. Fire particles + sound
  7. Deal 15 fire damage
  8. Unlock titan
  9. 1s recovery

Total Duration: ~5.5 seconds

{
"timeline": [
{"type": "add_holds", "holds": ["effects"]},
{"type": "stop_movement", "duration": "5000"},
{"type": "animation", "animation": "special"},
{"type": "sound", "sound": "entity.ender_dragon.growl", "volume": "2.0", "pitch": "0.6"},
{"type": "pause", "pause": 1.5},
{"type": "entity_particles", "particleType": "minecraft:dragon_breath", "count": 50},
{"type": "pause", "pause": 0.5},
{"type": "define_obb", "name": "explosion", "shape": "SPHERE", "positioning": "AT_USER", "halfExtents": {"x": "12.0", "y": "12.0", "z": "12.0"}},
{"type": "telegraph_obb", "name": "explosion", "telegraphType": "CRITICAL"},
{"type": "sound", "sound": "entity.generic.explode", "volume": "2.0", "pitch": "0.8"},
{"type": "entity_particles", "particleType": "minecraft:explosion", "count": 100},
{"type": "damage_obb", "name": "explosion", "damage": "40.0", "damageType": "EXPLOSION", "knockback": "3.0"},
{"type": "set_vulnerable", "vulnerabilityState": "EXHAUSTED"},
{"type": "remove_holds", "holds": ["effects"]},
{"type": "pause", "pause": 3.0}
],
"condition": "q.user_health / q.user_max_health < 0.33"
}

Timeline Breakdown:

  1. Lock titan (5000ms)
  2. Play animation + roar sound
  3. 1.5s dramatic pause
  4. Dragon breath particles
  5. 0.5s charge
  6. Define massive sphere
  7. Show CRITICAL warning (~3s)
  8. Explosion sound + particles
  9. Deal 40 damage + knockback
  10. Enter EXHAUSTED state (vulnerable)
  11. Unlock titan
  12. 3s recovery

Total Duration: ~10 seconds Condition: Only at <33% HP

Attack Pacing:

  • Quick attacks: 2-4 seconds total
  • Medium attacks: 4-6 seconds total
  • Ultimate attacks: 8-12 seconds total

Telegraph Duration:

  • Small OBB (<5 blocks): ~1s warning
  • Medium OBB (5-8 blocks): ~1.5-2s warning
  • Large OBB (8-12 blocks): ~2-3s warning
  • Massive OBB (12+ blocks): ~3-4s warning

Recovery Windows:

  • Always include pause after damage
  • Match recovery to attack power
  • 1-3 second pause is standard

Always Include:

  1. add_holds at start
  2. stop_movement if titan should freeze
  3. Telegraph before damage
  4. remove_holds before end
  5. Final pause for recovery

Recommended Order:

  1. Locks (add_holds, stop_movement)
  2. Windup (animation, particles, sounds)
  3. Pause (charge time)
  4. Define OBB
  5. Telegraph OBB
  6. Damage OBB
  7. Unlocks (remove_holds)
  8. Recovery pause

Keep Timelines Lean:

  • Avoid excessive particles (>100 per effect)
  • Don’t spam sounds
  • Use appropriate OBB sizes
  • Limit keyframe count (<20 per timeline)

Optimize OBBs:

  • Match size to visual effect
  • Don’t make everything huge
  • Use appropriate shapes
  • Test performance with multiple titans

Test Incrementally:

  1. Start with basic timeline (just damage)
  2. Add telegraph
  3. Add particles/sounds
  4. Add holds/pauses
  5. Test timing

Common Issues:

  • Timeline too fast? Add more pause keyframes
  • Titan moving during attack? Check stop_movement duration
  • Damage not applying? Verify OBB positioning
  • Players can’t dodge? Increase telegraph duration

Use the ActionEffect Builder → for visual timeline creation:

  1. Add keyframes from library
  2. Configure properties
  3. Preview timeline
  4. Export JSON
  5. Save to data pack

Best for: New users, prototyping, visual learners

Edit JSON files directly:

  1. Copy existing ActionEffect
  2. Modify keyframes
  3. Adjust timing
  4. Test in-game
  5. Iterate

Best for: Advanced users, complex logic, version control

Start with builder, finish with manual editing:

  1. Build basic timeline in builder
  2. Export JSON
  3. Add advanced features manually
  4. Test and refine

Best for: Most users, balanced workflow

ActionEffects load on server start from:

  1. Mod resources (titan.jar internal files)
  2. Data packs (datapacks/*/data/titan/action_effects/)
/titan reload

Reloads:

  • All fight configs
  • All ActionEffects from data packs
  • All state machines

Does NOT reload:

  • Existing titan entities (spawn new ones to test)
  • Mod internal ActionEffects (requires restart)

Workflow:

  1. Edit ActionEffect JSON
  2. /titan reload
  3. Spawn fresh titan
  4. Test attack
  5. Adjust and repeat

Tip: Use creative mode with god mode to survive testing.

{
"timeline": [
{"type": "add_holds", "holds": ["effects"]},
{"type": "animation", "animation": "physical"},
{"type": "pause", "pause": 0.3},
{"type": "define_obb", "name": "slash", "shape": "ARC", "positioning": "IN_FRONT", "distance": "2.0", "halfExtents": {"x": "3.0", "y": "2.0", "z": "3.0"}},
{"type": "telegraph_obb", "name": "slash", "telegraphType": "WARNING"},
{"type": "damage_obb", "name": "slash", "damage": "10.0"},
{"type": "remove_holds", "holds": ["effects"]},
{"type": "pause", "pause": 0.5}
]
}
{
"timeline": [
{"type": "add_holds", "holds": ["effects"]},
{"type": "stop_movement", "duration": "1500"},
{"type": "animation", "animation": "special"},
{"type": "pause", "pause": 0.5},
{"type": "define_obb", "name": "beam", "shape": "CYLINDER", "positioning": "IN_FRONT", "distance": "5.0", "halfExtents": {"x": "1.0", "y": "10.0", "z": "1.0"}, "includePitch": true},
{"type": "telegraph_obb", "name": "beam", "telegraphType": "DANGER"},
{"type": "entity_particles", "particleType": "minecraft:electric_spark", "count": 40},
{"type": "sound", "sound": "entity.lightning_bolt.thunder"},
{"type": "damage_obb", "name": "beam", "damage": "18.0", "damageType": "ELECTRIC"},
{"type": "remove_holds", "holds": ["effects"]},
{"type": "pause", "pause": 1.0}
]
}
{
"timeline": [
{"type": "add_holds", "holds": ["effects"]},
{"type": "stop_movement", "duration": "3000"},
{"type": "pause", "pause": 1.0},
{"type": "define_obb", "name": "blast", "shape": "SPHERE", "positioning": "AT_TARGET", "halfExtents": {"x": "8.0", "y": "8.0", "z": "8.0"}},
{"type": "telegraph_obb", "name": "blast", "telegraphType": "DANGER"},
{"type": "entity_particles", "particleType": "minecraft:explosion", "count": 50},
{"type": "sound", "sound": "entity.generic.explode", "volume": "1.5"},
{"type": "damage_obb", "name": "blast", "damage": "25.0", "knockback": "2.0"},
{"type": "set_vulnerable", "vulnerabilityState": "RECOVERING"},
{"type": "remove_holds", "holds": ["effects"]},
{"type": "pause", "pause": 2.0}
]
}
{
"timeline": [
{"type": "add_holds", "holds": ["effects"]},
{"type": "define_obb", "name": "hit1", "shape": "ARC", "positioning": "IN_FRONT", "distance": "1.5", "halfExtents": {"x": "2.5", "y": "2.0", "z": "2.5"}},
{"type": "telegraph_obb", "name": "hit1", "telegraphType": "WARNING"},
{"type": "damage_obb", "name": "hit1", "damage": "6.0"},
{"type": "pause", "pause": 0.4},
{"type": "define_obb", "name": "hit2", "shape": "ARC", "positioning": "IN_FRONT", "distance": "1.5", "halfExtents": {"x": "2.5", "y": "2.0", "z": "2.5"}},
{"type": "telegraph_obb", "name": "hit2", "telegraphType": "WARNING"},
{"type": "damage_obb", "name": "hit2", "damage": "6.0"},
{"type": "pause", "pause": 0.4},
{"type": "define_obb", "name": "hit3", "shape": "ARC", "positioning": "IN_FRONT", "distance": "2.0", "halfExtents": {"x": "3.5", "y": "2.5", "z": "3.5"}},
{"type": "telegraph_obb", "name": "hit3", "telegraphType": "DANGER"},
{"type": "damage_obb", "name": "hit3", "damage": "12.0", "knockback": "1.5"},
{"type": "remove_holds", "holds": ["effects"]},
{"type": "pause", "pause": 1.0}
]
}

Master ActionEffects to create unforgettable boss fights!