Skip to content

Combat System

The combat system defines weapon attacks, damage calculations, and effects through a layered interaction architecture. Items override base interactions using InteractionVars to customize damage, effects, and behavior.

flowchart TB
    subgraph ItemDef["Item Definition"]
        subgraph Interactions["Interactions"]
            Primary["Primary: Root"]
            Secondary["Secondary: Root"]
        end
        subgraph Vars["InteractionVars"]
            SwingLeft["Swing_Left_Damage: {...}"]
            SwingRight["Swing_Right_Damage: {...}"]
        end
    end

    subgraph RootInt["RootInteraction"]
        Cooldown["Cooldown, Queueing"]
    end

    subgraph Override["Override Base Values"]
        BaseDamage["BaseDamage, Effects"]
    end

    subgraph Chain["Interaction Chain"]
        Charging --> Chaining --> Attack --> Selector --> Damage
    end

    Interactions --> RootInt
    Vars --> Override
    RootInt --> Chain
  • DirectoryAssets/Server/Item/
    • DirectoryItems/Weapon/
      • DirectorySword/
        • Template_Weapon_Sword.json
        • Weapon_Sword_Iron.json
      • DirectoryMace/
      • DirectoryDagger/
      • DirectoryBattleaxe/
    • DirectoryRootInteractions/
      • DirectoryWeapons/
        • DirectorySword/
          • Root_Weapon_Sword_Primary.json
          • Root_Weapon_Sword_Secondary_Guard.json
          • Root_Weapon_Sword_Signature_Vortexstrike.json
    • DirectoryInteractions/
      • DirectoryWeapons/
        • DirectorySword/
          • DirectoryAttacks/
            • DirectoryPrimary/
            • DirectorySecondary/
            • DirectorySignature/

Items define interaction bindings in the Interactions property:

Template_Weapon_Sword.json (excerpt)
{
"Interactions": {
"Primary": "Root_Weapon_Sword_Primary",
"Secondary": "Root_Weapon_Sword_Secondary_Guard",
"Ability1": "Root_Weapon_Sword_Signature_Vortexstrike"
}
}
BindingDescription
PrimaryLeft-click / primary attack
SecondaryRight-click / secondary action
Ability1Special/signature ability
Ability2Additional ability

Root interactions define the entry point for attack chains:

Root_Weapon_Sword_Primary.json
{
"RequireNewClick": true,
"ClickQueuingTimeout": 0.2,
"Cooldown": {
"Cooldown": 0.25
},
"Interactions": [
"Weapon_Sword_Primary"
]
}
FieldTypeDescription
RequireNewClickboolRequire new input for each attack
ClickQueuingTimeoutfloatInput queue window (seconds)
CooldownobjectCooldown configuration
Cooldown.CooldownfloatCooldown duration (seconds)
InteractionsarrayInteraction chain to execute

Hold-to-charge mechanics with time-based thresholds:

Weapon_Sword_Primary.json
{
"Type": "Charging",
"DisplayProgress": false,
"Next": {
"0": "Weapon_Sword_Primary_Chain",
"0.2": {
"Type": "Replace",
"Var": "Thrust_Stamina",
"DefaultOk": true,
"DefaultValue": {
"Interactions": [
"Weapon_Sword_Primary_Thrust_StaminaCondition"
]
}
}
}
}
FieldTypeDescription
Type"Charging"Charging interaction type
DisplayProgressboolShow charge bar
NextobjectTime-based branches (keys are seconds)

Combo attack sequences:

Weapon_Sword_Primary_Chain.json
{
"Type": "Chaining",
"ChainingAllowance": 2,
"ChainId": "Sword_Swings",
"Next": [
{
"Type": "Replace",
"DefaultOk": true,
"Var": "Swing_Left",
"DefaultValue": {
"Interactions": [
"Weapon_Sword_Primary_Swing_Left"
]
}
},
{
"Type": "Replace",
"DefaultOk": true,
"Var": "Swing_Right",
"DefaultValue": {
"Interactions": [
"Weapon_Sword_Primary_Swing_Right"
]
}
},
{
"Type": "Replace",
"DefaultOk": true,
"Var": "Swing_Down",
"DefaultValue": {
"Interactions": [
"Weapon_Sword_Primary_Swing_Down"
]
}
}
]
}
FieldTypeDescription
Type"Chaining"Chaining interaction type
ChainingAllowanceintMax combo chain count
ChainIdstringUnique chain identifier
NextarraySequential attack options

Basic single-action interactions:

Weapon_Sword_Primary_Swing_Left.json
{
"Type": "Simple",
"RunTime": 0.117,
"Effects": {
"ItemAnimationId": "SwingLeft",
"WorldSoundEventId": "SFX_Light_Melee_T2_Swing",
"LocalSoundEventId": "SFX_Sword_T2_Swing_RL_Local"
},
"Next": {
"Type": "Replace",
"Var": "Swing_Left_Selector",
"DefaultOk": true,
"DefaultValue": {
"Interactions": [
"Weapon_Sword_Primary_Swing_Left_Selector"
]
}
}
}
FieldTypeDescription
Type"Simple"Simple interaction type
RunTimefloatExecution time (seconds)
EffectsobjectVisual/audio effects
NextobjectNext interaction in chain

Damage interactions define damage calculations and hit effects:

Weapon_Sword_Primary_Swing_Left_Damage.json
{
"Parent": "DamageEntityParent",
"DamageCalculator": {
"Class": "Light"
},
"Effects": {
"CameraEffect": "Impact"
},
"DamageEffects": {
"Knockback": {
"Type": "Force",
"VelocityConfig": {
"AirResistance": 0.99,
"AirResistanceMax": 0.98,
"GroundResistance": 0.94,
"GroundResistanceMax": 0.3,
"Threshold": 3.0,
"Style": "Linear"
},
"Direction": {
"X": 0,
"Y": 1,
"Z": -1
},
"Force": 6.0,
"VelocityType": "Add"
},
"WorldParticles": [
{
"SystemId": "Impact_Sword_Basic"
}
],
"CameraEffect": "Impact_Light"
},
"EntityStatsOnHit": [
{
"EntityStatId": "SignatureEnergy",
"Amount": 1
}
]
}
FieldTypeDescription
ClassstringDamage class (Light, Charged, Signature)
BaseDamageobjectMap of DamageCause IDs to damage amounts
TypestringCalculation type (Absolute or DPS)
RandomPercentageModifierfloatDamage variance (0.1 = ±10%)
FieldTypeDescription
KnockbackobjectKnockback configuration
WorldParticlesarrayParticles spawned on hit
WorldSoundEventIdstringSound played globally
LocalSoundEventIdstringSound played locally
CameraEffectstringCamera shake on hit
FieldTypeDescription
TypestringKnockback type (Force)
DirectionobjectKnockback direction {X, Y, Z}
ForcefloatKnockback strength
VelocityTypestringHow velocity is applied (Add)
VelocityConfigobjectPhysics configuration

Stats modified when attack hits:

"EntityStatsOnHit": [
{
"EntityStatId": "SignatureEnergy",
"Amount": 1
}
]

Items override base interactions using InteractionVars. This allows items to customize damage while sharing the same attack animations:

Weapon_Sword_Iron.json (InteractionVars)
{
"InteractionVars": {
"Swing_Left_Damage": {
"Interactions": [
{
"Parent": "Weapon_Sword_Primary_Swing_Left_Damage",
"DamageCalculator": {
"BaseDamage": {
"Physical": 9
}
},
"DamageEffects": {
"WorldSoundEventId": "SFX_Sword_T2_Impact",
"LocalSoundEventId": "SFX_Sword_T2_Impact"
}
}
]
},
"Swing_Right_Damage": {
"Interactions": [
{
"Parent": "Weapon_Sword_Primary_Swing_Right_Damage",
"DamageCalculator": {
"BaseDamage": {
"Physical": 10
}
}
}
]
},
"Swing_Down_Damage": {
"Interactions": [
{
"Parent": "Weapon_Sword_Primary_Swing_Down_Damage",
"DamageCalculator": {
"BaseDamage": {
"Physical": 18
}
}
}
]
},
"Thrust_Damage": {
"Interactions": [
{
"Parent": "Weapon_Sword_Primary_Thrust_Damage",
"DamageCalculator": {
"BaseDamage": {
"Physical": 26
}
},
"EntityStatsOnHit": [
{
"EntityStatId": "SignatureEnergy",
"Amount": 3
}
]
}
]
}
}
}

Common InteractionVar names for weapons:

Var NameDescription
Swing_Left_DamageLeft swing damage
Swing_Right_DamageRight swing damage
Swing_Down_DamageOverhead swing damage
Thrust_DamageCharged thrust damage
Guard_WieldGuard/block stance
Vortexstrike_Spin_DamageSignature spin damage
Vortexstrike_Stab_DamageSignature stab damage

Properties that can be overridden:

PropertyTypeDescription
ParentstringBase interaction to inherit from
DamageCalculatorobjectDamage configuration
DamageEffectsobjectHit effects
EffectsobjectAnimation/sound effects
EntityStatsOnHitarrayStats modified on hit
StaminaCostobjectStamina cost

Actions can cost stamina:

"Guard_Wield": {
"Interactions": [
{
"Parent": "Weapon_Sword_Secondary_Guard_Wield",
"StaminaCost": {
"Value": 10,
"CostType": "Damage"
}
}
]
}
FieldTypeDescription
ValuefloatStamina cost amount
CostTypestringCost type (Damage, Flat)

Weapons can build signature energy for special attacks:

Template_Weapon_Sword.json (Weapon section)
{
"Weapon": {
"EntityStatsToClear": [
"SignatureEnergy"
],
"StatModifiers": {
"SignatureEnergy": [
{
"Amount": 20,
"CalculationType": "Additive"
}
]
}
}
}
FieldTypeDescription
EntityStatsToCleararrayStats reset on weapon switch
StatModifiersobjectStat modifications
AmountintMax signature energy
CalculationTypestringHow modifier applies

Visual effects when signature is ready:

"ItemAppearanceConditions": {
"SignatureEnergy": [
{
"Condition": [100, 100],
"ConditionValueType": "Percent",
"Particles": [
{
"SystemId": "Sword_Signature_Ready",
"TargetNodeName": "Handle",
"PositionOffset": { "X": 0.8 },
"TargetEntityPart": "PrimaryItem"
}
],
"ModelVFXId": "Sword_Signature_Status"
}
]
}
Template_Weapon_Sword.json
{
"TranslationProperties": {
"Name": "server.items.Template_Weapon_Sword.name"
},
"Model": "Items/Weapons/Sword/Iron.blockymodel",
"PlayerAnimationsId": "Sword",
"Reticle": "DefaultMelee",
"Categories": ["Items.Weapons"],
"Interactions": {
"Primary": "Root_Weapon_Sword_Primary",
"Secondary": "Root_Weapon_Sword_Secondary_Guard",
"Ability1": "Root_Weapon_Sword_Signature_Vortexstrike"
},
"Tags": {
"Type": ["Weapon"],
"Family": ["Sword"]
},
"Weapon": {
"EntityStatsToClear": ["SignatureEnergy"],
"StatModifiers": {
"SignatureEnergy": [
{ "Amount": 20, "CalculationType": "Additive" }
]
}
},
"ItemSoundSetId": "ISS_Weapons_Blade_Large",
"MaxDurability": 80,
"DurabilityLossOnHit": 0.21
}

Damage causes are asset-based, loaded from JSON files at Assets/Server/Entity/Damage/. They are not hardcoded — you can define custom damage causes for your mod. The keys used in BaseDamage (like "Physical" or "Fire") are DamageCause asset IDs.

Each DamageCause has these properties:

FieldTypeDescription
InheritsstringParent damage cause to inherit from
DurabilityLossboolWhether this damage reduces item durability
StaminaLossboolWhether this damage drains stamina
BypassResistancesboolWhether this damage ignores armor resistances
DamageTextColorstringColor used for damage number text
AnimationIdstringHurt animation (default: "Hurt")
DeathAnimationIdstringDeath animation (default: "Death")

The vanilla game ships with built-in causes like Physical, Projectile, Fall, Drowning, Suffocation, Environment, Command, and Out_Of_World. Armor can define per-cause resistance via DamageResistance in its configuration.

Separate from damage causes, DamageClass is a hardcoded enum that classifies the attack style. It’s set on the DamageCalculator via the Class field:

ClassDescription
LightStandard light attacks (swings)
ChargedCharged/heavy attacks (thrusts)
SignatureSignature ability attacks
MyPlugin_Weapon_Sword_Custom.json
{
"Parent": "Template_Weapon_Sword",
"TranslationProperties": {
"Name": "my_plugin.items.custom_sword.name"
},
"Model": "MyPlugin/Items/Weapons/Sword/Custom.blockymodel",
"Texture": "MyPlugin/Items/Weapons/Sword/Custom_Texture.png",
"Quality": "Rare",
"ItemLevel": 35,
"InteractionVars": {
"Swing_Left_Damage": {
"Interactions": [{
"Parent": "Weapon_Sword_Primary_Swing_Left_Damage",
"DamageCalculator": {
"BaseDamage": { "Physical": 15 }
}
}]
},
"Swing_Right_Damage": {
"Interactions": [{
"Parent": "Weapon_Sword_Primary_Swing_Right_Damage",
"DamageCalculator": {
"BaseDamage": { "Physical": 17 }
}
}]
},
"Swing_Down_Damage": {
"Interactions": [{
"Parent": "Weapon_Sword_Primary_Swing_Down_Damage",
"DamageCalculator": {
"BaseDamage": { "Physical": 28 }
}
}]
},
"Thrust_Damage": {
"Interactions": [{
"Parent": "Weapon_Sword_Primary_Thrust_Damage",
"DamageCalculator": {
"BaseDamage": { "Physical": 42 }
}
}]
}
},
"MaxDurability": 180,
"DurabilityLossOnHit": 0.18
}
MyPlugin_Weapon_Sword_Fire.json
{
"Parent": "Template_Weapon_Sword",
"TranslationProperties": {
"Name": "my_plugin.items.fire_sword.name"
},
"Quality": "Epic",
"InteractionVars": {
"Swing_Left_Damage": {
"Interactions": [{
"Parent": "Weapon_Sword_Primary_Swing_Left_Damage",
"DamageCalculator": {
"BaseDamage": {
"Physical": 8,
"Fire": 6
}
},
"DamageEffects": {
"WorldParticles": [
{ "SystemId": "Impact_Fire_Basic" }
]
}
}]
}
}
}
  1. Inherit from templates - Use Parent to share attack logic
  2. Override only needed values - InteractionVars can be minimal
  3. Scale damage consistently - Higher tiers = more damage
  4. Use appropriate sound tiers - T1, T2, T3 match item quality
  5. Balance signature energy - More on heavy attacks
  6. Test knockback values - Ensure combat feels right
  7. Match particles to element - Fire weapons use fire particles