Skip to content

Move Sets

Move sets define all attacks available to a Titan, their properties, cooldowns, and selection strategy. In the new modular architecture, move sets are separate, reusable configurations referenced by fight manifests.

Path: config/titan/moves/{moveSet}.json

config/titan/moves/
├── core.json # Shared generic moves
├── charizard.json # Charizard-specific moves
├── raichu.json # Raichu-specific moves
├── ceruledge.json # Ceruledge-specific moves
├── default_titan.json # Fallback move set
└── ... (33 total)
{
"moves": {
"thunderstrike": {
"name": "Thunderstrike",
"cooldown": "120",
"range": "10.0",
"damage": "42.0",
"damageType": "ELECTRIC",
"actionEffect": "titan:raichu_thunderstrike",
"condition": "true",
"weight": 1.4,
"minHealthPercent": 0.5,
"maxHealthPercent": 1.0,
"phase": -1
},
"gigavolt_havoc": {
"name": "Gigavolt Havoc",
"cooldown": "300",
"range": "20.0",
"damage": "110.0",
"damageType": "ELECTRIC",
"actionEffect": "titan:raichu_gigavolt_havoc",
"condition": "true",
"weight": 0.7,
"minHealthPercent": 0.0,
"maxHealthPercent": 0.4,
"phase": -1
},
"storm_call": {
"name": "Storm Call",
"cooldown": "160",
"range": "0.0",
"damage": "0.0",
"damageType": "STATUS",
"actionEffect": "titan:raichu_storm_call",
"condition": "true",
"weight": 0.8,
"minHealthPercent": 0.66,
"maxHealthPercent": 1.0,
"phase": -1,
"onUse": "q.invoke_move('spark_clone')"
}
},
"selectionStrategy": "WEIGHTED_RANDOM"
}

Display name shown to players when move is used.

"name": "Thunderstrike"
// In-game: "Storm Surge Titan Raichu used Thunderstrike!"

Best Practices:

  • Capitalize each word
  • Keep under 25 characters
  • Match Pokémon move theme
  • Make it memorable

Ticks before move can be used again (20 ticks = 1 second).

"cooldown": "120" // 6 seconds
// Common cooldown tiers:
"cooldown": "80" // 4s - Fast attacks
"cooldown": "120" // 6s - Medium attacks
"cooldown": "200" // 10s - Heavy attacks
"cooldown": "300" // 15s - Ultimate moves
"cooldown": "500" // 25s - Rare ultimates

Maximum distance to target in blocks.

"range": "10.0" // Medium range
"range": "0.0" // Self-centered (no target required)
"range": "20.0" // Long range

Special Value: "0.0" = Always available (self-buffs, AoE explosions)

Base damage value used by ActionEffect keyframes.

"damage": "42.0"
// Damage tiers:
"damage": "8.0-12.0" // Light attacks
"damage": "15.0-25.0" // Medium attacks
"damage": "30.0-50.0" // Heavy attacks
"damage": "60.0-85.0" // Powerful attacks
"damage": "90.0-120.0" // Ultimate attacks

Note: Actual damage dealt depends on ActionEffect keyframes. This is a reference value.

Descriptive type label (does NOT affect damage calculation).

"damageType": "ELECTRIC"
// Common types:
"FIRE", "WATER", "ELECTRIC", "GRASS", "ICE", "DRAGON",
"PSYCHIC", "GHOST", "DARK", "PHYSICAL", "SPECIAL", "STATUS"

Used for logging and future type-based mechanics.

Resource location of the ActionEffect timeline.

"actionEffect": "titan:raichu_thunderstrike"
// → Loads data/titan/action_effects/raichu_thunderstrike.json
"actionEffect": "cobblemon:moves/flamethrower"
// → Can reference Cobblemon's built-in effects

Format: namespace:path

See: Action Effects →

MoLang expression that must be true for move to be available.

// Always available
"condition": "true"
"condition": "1.0"
// Only when below 50% HP
"condition": "q.titan_health_percent < 0.5"
// Only when target is close
"condition": "q.titan_distance_to_target < 6.0"
// Complex condition
"condition": "q.titan_health_percent < 0.3 && q.titan_time_in_phase > 5000"

See: Titan Queries →

Selection weight for WEIGHTED_RANDOM strategy.

"weight": 1.0 // Normal frequency
"weight": 0.5 // Half as likely
"weight": 2.0 // Twice as likely
"weight": 0.1 // Very rare (ultimates)

Formula: P(move) = weight / Σ(all_available_weights)

Example:

{
"slash": { "weight": 1.5 }, // 1.5 / 3.5 = 43%
"fireball": { "weight": 1.0 }, // 1.0 / 3.5 = 29%
"heal": { "weight": 1.0 } // 1.0 / 3.5 = 29%
}

minHealthPercent / maxHealthPercent (Number, default: 0.0 / 1.0)

Section titled “minHealthPercent / maxHealthPercent (Number, default: 0.0 / 1.0)”

Health percentage range when move is available.

// Phase 1 move (100% → 66% HP)
"minHealthPercent": 0.66,
"maxHealthPercent": 1.0
// Phase 3 move (33% → 0% HP)
"minHealthPercent": 0.0,
"maxHealthPercent": 0.33
// Always available
"minHealthPercent": 0.0,
"maxHealthPercent": 1.0

Use Case: Create phase-specific move pools without hardcoding phase indices.

Specific phase index where move is available.

"phase": -1 // All phases (recommended)
"phase": 0 // Phase 1 only
"phase": 1 // Phase 2 only
"phase": 2 // Phase 3 only

MoLang script executed when move is used (before ActionEffect).

"onUse": "q.invoke_move('spark_clone')"
// Chains another move
"onUse": "q.apply_potion('minecraft:strength', 200, 1)"
// Applies buff before attack
"onUse": "q.particle_effect('cobblemon:thunder_actorcloud', q.position(0), 100, 3.0)"
// Spawns particles

See: Effect Functions →

Property: selectionStrategy at root level

Picks moves based on weight values.

{
"moves": {
"fast_attack": { "weight": 2.0 }, // 50% chance
"medium_attack": { "weight": 1.0 }, // 25% chance
"slow_attack": { "weight": 1.0 } // 25% chance
},
"selectionStrategy": "WEIGHTED_RANDOM"
}

Best For: Dynamic, varied combat

Equal chance for all available moves (ignores weights).

{
"moves": { ... },
"selectionStrategy": "RANDOM"
}

Best For: Unpredictable bosses

Uses moves in definition order, loops when reaching end.

{
"moves": {
"move_1": { ... },
"move_2": { ... },
"move_3": { ... }
},
"selectionStrategy": "SEQUENCE"
}
// Execution: move_1 → move_2 → move_3 → move_1 → ...

Best For: Choreographed attack patterns

Evaluates moves in order, uses first with matching condition.

{
"moves": {
"heal": {
"condition": "q.titan_health_percent < 0.4",
"weight": 1.0
},
"ultimate": {
"condition": "q.titan_time_in_phase > 10000",
"weight": 1.0
},
"basic_attack": {
"condition": "1.0", // Fallback
"weight": 1.0
}
},
"selectionStrategy": "CONDITIONAL"
}

Best For: Priority-based AI

A move is available if ALL of these are true:

graph TD
    A[Check Move] --> B{Cooldown OK?}
    B -->|No| X[NOT AVAILABLE]
    B -->|Yes| C{Condition True?}
    C -->|No| X
    C -->|Yes| D{Target in Range?}
    D -->|No| X
    D -->|Yes| E{Health % Match?}
    E -->|No| X
    E -->|Yes| F{Phase Match?}
    F -->|No| X
    F -->|Yes| Y[AVAILABLE]
  1. ✅ Cooldown expired
  2. condition evaluates to true
  3. ✅ Target within range (or range is 0.0)
  4. ✅ Current HP% between minHealthPercent and maxHealthPercent
  5. phase matches current phase (or phase is -1)

Early Game (100% → 66% HP):

"basic_slash": {
"damage": "15.0",
"cooldown": "100",
"minHealthPercent": 0.66,
"maxHealthPercent": 1.0
}

Mid Game (66% → 33% HP):

"power_strike": {
"damage": "30.0",
"cooldown": "150",
"minHealthPercent": 0.33,
"maxHealthPercent": 0.66
}

Late Game (33% → 0% HP):

"ultimate_attack": {
"damage": "80.0",
"cooldown": "300",
"minHealthPercent": 0.0,
"maxHealthPercent": 0.33
}
"quick_jab": {
"damage": "10.0",
"cooldown": "80",
"weight": 1.5,
"minHealthPercent": 0.0,
"maxHealthPercent": 1.0,
"phase": -1
}
"healing_aura": {
"name": "Healing Aura",
"damage": "0.0",
"damageType": "STATUS",
"range": "0.0",
"cooldown": "400",
"actionEffect": "titan:heal_self",
"condition": "q.titan_health_percent < 0.5",
"weight": 2.0
}

Generic attacks reusable across multiple Titans:

{
"moves": {
"generic_slash": {
"name": "Titan Slash",
"cooldown": "100",
"range": "5.0",
"damage": "12.0",
"damageType": "PHYSICAL",
"actionEffect": "titan:generic_slash",
"condition": "true",
"weight": 1.0
},
"titan_roar": {
"name": "Titan Roar",
"cooldown": "200",
"range": "0.0",
"damage": "0.0",
"damageType": "STATUS",
"actionEffect": "titan:roar",
"condition": "true",
"weight": 0.8
}
},
"selectionStrategy": "WEIGHTED_RANDOM"
}

Usage:

config/titan/fights/machamp.json
{
"pokemonProperties": "machamp",
"name": "Brawler Titan Machamp",
"moveSet": "core" // ← Uses shared moves
}

You can’t directly extend move sets, but you can duplicate core.json and add custom moves:

config/titan/moves/custom_machamp.json
{
"moves": {
"generic_slash": { ... }, // From core
"titan_roar": { ... }, // From core
"dynamic_punch": { ... }, // Custom Machamp move
"cross_chop": { ... } // Custom Machamp move
},
"selectionStrategy": "WEIGHTED_RANDOM"
}

Phases:

  • Phase 1 (100%-66%): storm_call, thunderstrike, chain_lightning, discharge_nova, lightning_dash
  • Phase 2 (66%-35%): storm_surge, electroweb, thunder_cage, spark_clone, magnetic_flux, lightning_rod
  • Phase 3 (35%-0%): thunderbolt_barrage, volt_tackle, gigavolt_havoc, overcharge

Strategy: Escalating power, teleport in phase 2, rush in phase 3

File: config/titan/moves/raichu.json

Phases:

  • All phases: shadow_claw, bitter_blade, flame_charge
  • Phase 2+: poltergeist, infernal_charge
  • Phase 3: armor_oblivion (ultimate)

Strategy: Melee focus, hit-and-run combat, ultimate finisher

File: config/titan/moves/ceruledge.json

Moves:

  • titan_strike (always available)
  • titan_slam (phase 2+)
  • titan_rage (phase 3 ultimate)

Strategy: Simple progression for generic Titans

File: config/titan/moves/default_titan.json

Cooldowns can be reset when Titan is interrupted to allow immediate counterattack.

ActionEffect Usage:

{
"type": "titan:start_interrupt_window",
"startTicks": 10,
"damageThreshold": 50.0,
"onInterrupt": "q.clear_cooldowns()" // ← Reset on interrupt
}

Cooldowns are tracked independently per move ID. Using the same move multiple times (if referenced in different phases) shares cooldown.

Damage RangeCooldown RangeCategory
8-1580-120 ticksFast/Light
16-30120-180 ticksMedium
31-50180-250 ticksHeavy
51-85250-350 ticksPowerful
86-120350-500 ticksUltimate
  • Basic Attacks: 1.5-2.0 (high frequency)
  • Medium Attacks: 1.0-1.3 (normal)
  • Heavy Attacks: 0.7-1.0 (moderate)
  • Ultimates: 0.3-0.6 (rare)
  • Utility/Heals: 1.5-2.5 (prioritized when conditions met)
  • Melee: 3.0-6.0 blocks
  • Medium: 7.0-12.0 blocks
  • Long: 13.0-20.0 blocks
  • Self-Centered: 0.0 (no target required)
"final_explosion": {
"name": "Final Explosion",
"cooldown": "600",
"range": "0.0",
"damage": "100.0",
"damageType": "SPECIAL",
"actionEffect": "titan:final_explosion",
"condition": "q.titan_health_percent < 0.1", // Only at 10% HP
"weight": 3.0, // High priority
"minHealthPercent": 0.0,
"maxHealthPercent": 0.1
}
"combo_starter": {
"name": "Combo Starter",
"cooldown": "200",
"range": "8.0",
"damage": "20.0",
"damageType": "PHYSICAL",
"actionEffect": "titan:combo_1",
"onUse": "q.invoke_move('combo_finisher')", // Chains next move
"weight": 1.0
}
"regenerate": {
"name": "Regenerate",
"cooldown": "300",
"range": "0.0",
"damage": "0.0",
"damageType": "STATUS",
"actionEffect": "titan:heal",
"condition": "q.titan_health_percent < 0.5 && q.titan_time_since_damage > 3000",
"weight": 5.0 // Very high priority when available
}

Possible Causes:

  1. Cooldown too long (no time to use in phase)
  2. Condition always false
  3. Range too short (target out of range)
  4. Health percent range doesn’t match phases
  5. Weight too low compared to other moves

Debug:

  • Set condition: "1.0" to test
  • Increase weight to 5.0 temporarily
  • Check logs for move selection attempts

Symptoms: Titan idles, doesn’t attack

Fixes:

  • Reduce cooldown values (aim for 100-200 for basic attacks)
  • Add more moves with staggered cooldowns
  • Ensure at least 3-4 moves per phase

Remember: damage property is a reference value. Actual damage is dealt by ActionEffect keyframes:

// Move config
"damage": "50.0" // Reference only
// ActionEffect (actual damage)
{
"type": "titan:damage_obb",
"startTicks": 20,
"id": "slash_1",
"damage": 50.0 // ← This is what matters
}

Design compelling move sets to create epic, varied boss encounters!