Skip to content

Channeling Staff Tutorial

Final Channeling Staff weapon in-game

In this tutorial, you’ll create a magical channeling staff that demonstrates complex interaction patterns including multi-tier charging, forking, damage cancellation, and visual feedback.

Multi-Tier ChargingFork ActionsDamage CancellationVisual Feedback

Final Result:

  • A magical staff with 3 charge tiers (0.5s, 1.5s, 3.0s)
  • Secondary “quick cast” fork while channeling
  • Visual/audio feedback at each tier
  • Damage cancellation if hit while channeling
  • Progress bar during charge

Before starting, you should understand:

  • Directorymy-plugin/
    • manifest.json
    • Directoryassets/
      • DirectoryServer/
        • DirectoryItem/
          • DirectoryItems/
            • DirectoryWeapon/
              • DirectoryStaff/
                • Weapon_Staff_Channeling.json
          • DirectoryInteractions/
            • DirectoryStaff/
              • Staff_Channeling_Primary.json
              • Staff_Channeling_Tier1.json
              • Staff_Channeling_Tier2.json
              • Staff_Channeling_Tier3.json
              • Staff_Channeling_QuickCast.json
              • Staff_Channeling_Failed.json
          • DirectoryRootInteractions/
            • DirectoryStaff/
              • Root_Staff_Channeling_Primary.json
              • Root_Staff_Channeling_QuickCast.json

The RootInteraction is the entry point that items reference.

  1. Create the folder structure for your staff interactions

  2. Create the root interaction file

Root_Staff_Channeling_Primary.json
{
"RequireNewClick": true,
"ClickQueuingTimeout": 0.3,
"Cooldown": {
"Cooldown": 0.5,
"Id": "Staff_Channeling"
},
"Interactions": [
"Staff_Channeling_Primary"
]
}
FieldDescription
RequireNewClickMust click again, not hold
ClickQueuingTimeoutWindow to queue next click
IdCooldown identifier shared across staff abilities

This is the core of our staff - the charging mechanic with three tiers.

Staff_Channeling_Primary.json
{
"Type": "Charging",
"DisplayProgress": true,
"FailOnDamage": true,
"MouseSensitivityAdjustmentTarget": 0.5,
"MouseSensitivityAdjustmentDuration": 0.3,
"Effects": {
"ItemAnimationId": "Channel",
"WorldSoundEventId": "SFX_Staff_Charge_Loop"
},
"Delay": {
"MinDelay": 0.1,
"MaxDelay": 0.4,
"MinHealth": 0.2,
"MaxHealth": 0.8
},
"Next": {
"0.5": "Staff_Channeling_Tier1",
"1.5": "Staff_Channeling_Tier2",
"3.0": "Staff_Channeling_Tier3"
},
"Forks": {
"Secondary": "Root_Staff_Channeling_QuickCast"
},
"Failed": "Staff_Channeling_Failed"
}

The Next field maps charge duration to interactions:

DurationTierEffect
0.5sTier 1Quick spark projectile
1.5sTier 2AOE burst damage
3.0sTier 3Powerful beam with knockback

When released, the system picks the highest tier reached.


Each tier has its own interaction chain for unique effects.

Quick projectile attack for instant release:

Staff_Channeling_Tier1.json
{
"Type": "Serial",
"Interactions": [
{
"Type": "Simple",
"RunTime": 0.15,
"Effects": {
"ItemAnimationId": "Cast_Quick",
"WorldSoundEventId": "SFX_Staff_Cast_Light",
"WorldParticles": [
{ "SystemId": "Magic_Spark_Cast" }
]
}
},
{
"Type": "LaunchProjectile",
"ProjectileId": "Projectile_Magic_Spark"
}
]
}

Create a secondary spell that can be cast while channeling:

  1. Create the RootInteraction for the quick cast

  2. Create the quick cast interaction

Root_Staff_Channeling_QuickCast.json
{
"RequireNewClick": true,
"Cooldown": {
"Cooldown": 1.0,
"Id": "Staff_QuickCast"
},
"Interactions": [
"Staff_Channeling_QuickCast"
]
}
Staff_Channeling_QuickCast.json
{
"Type": "Serial",
"Interactions": [
{
"Type": "Simple",
"RunTime": 0.1,
"Effects": {
"ItemAnimationId": "QuickCast",
"WorldSoundEventId": "SFX_Staff_QuickCast",
"WorldParticles": [
{ "SystemId": "Magic_Shield_Flash" }
]
}
},
{
"Type": "ApplyEffect",
"EffectId": "Magic_Shield",
"Entity": "User"
}
]
}

When charge is interrupted by damage:

Staff_Channeling_Failed.json
{
"Type": "Serial",
"Interactions": [
{
"Type": "Simple",
"RunTime": 0.3,
"Effects": {
"ItemAnimationId": "Channel_Fail",
"WorldSoundEventId": "SFX_Staff_Fizzle",
"WorldParticles": [
{ "SystemId": "Magic_Fizzle" }
],
"CameraEffect": "Stagger_Light"
}
},
{
"Type": "ApplyEffect",
"EffectId": "Stagger_Brief",
"Entity": "User"
}
]
}

Now tie it all together with the item:

Weapon_Staff_Channeling.json
{
"Parent": "Template_Weapon_Staff",
"TranslationProperties": {
"Name": "myplugin.items.staff_channeling.name",
"Lore": "myplugin.items.staff_channeling.lore"
},
"Model": "MyPlugin/Weapons/Staff_Channeling.blockymodel",
"Texture": "MyPlugin/Weapons/Staff_Channeling_Texture.png",
"Icon": "MyPlugin/Icons/Staff_Channeling.png",
"Quality": "Rare",
"ItemLevel": 25,
"MaxDurability": 150,
"DurabilityLossOnHit": 0.1,
"Interactions": {
"Primary": "Root_Staff_Channeling_Primary"
},
"ItemSoundSetId": "ISS_Weapons_Staff"
}

  1. Build your plugin and install it on a test server

  2. Give yourself the staff with /give Weapon_Staff_Channeling

  3. Test each tier by holding and releasing at different times

  4. Test the quick cast by right-clicking while charging

  5. Test damage cancellation by having another player hit you while charging

  • Tier 1 (0.5s release) fires spark projectile
  • Tier 2 (1.5s release) creates AOE burst
  • Tier 3 (3.0s release) fires powerful beam
  • Quick cast (right-click during charge) applies shield
  • Getting hit cancels charge and plays fizzle effect
  • Progress bar shows during charge
  • All sounds and particles trigger correctly

Root_Staff_Channeling_Primary.json
{
"RequireNewClick": true,
"ClickQueuingTimeout": 0.3,
"Cooldown": {
"Cooldown": 0.5,
"Id": "Staff_Channeling"
},
"Interactions": ["Staff_Channeling_Primary"]
}
Root_Staff_Channeling_QuickCast.json
{
"RequireNewClick": true,
"Cooldown": {
"Cooldown": 1.0,
"Id": "Staff_QuickCast"
},
"Interactions": ["Staff_Channeling_QuickCast"]
}