Skip to content

HyGuns Attachments Guide

enso-x edited this page May 28, 2026 · 1 revision

HyGuns Attachments Guide

This guide explains how to create custom weapon attachments in HyGuns, how to define a new attachment type from scratch, how to create an attachment item, how to connect it to a weapon, and how to use attachment-related interactions.

1. Attachment system overview

HyGuns attachments are built from three parts:

  1. Attachment type definition
    A standalone JSON file under:

    Server/HyGuns/AttachmentTypes
    

    This defines the attachment category, for example Scope, Silencer, Magazine, Grip, or any custom type you create.

  2. Attachment item asset
    A normal item JSON with:

    "HyGuns": {
      "AttachmentSettings": {
        "Type": "YourAttachmentType"
      }
    }

    This turns the item into a valid weapon attachment.

  3. Weapon attachment slots
    A weapon declares which attachment types it accepts through:

    "HyGuns": {
      "WeaponSettings": {
        "SupportedAttachments": {
          "YourAttachmentType": {
            "Count": 1
          }
        }
      }
    }

When the player opens the attachment UI, HyGuns creates the attachment container from SupportedAttachments. Drag-and-drop then checks attachment type, wildcard rules, conflicts, and max-count limits.


2. Create a new attachment type

Create a new JSON file inside:

Server/HyGuns/AttachmentTypes

The filename is only for organization. The real type id is the Type field.

Example:

{
  "Type": "Laser",
  "Icon": "Attachments/laser.png",
  "AnyAllowed": true,
  "ConflictsWith": [],
  "MaxCount": 1
}

Fields

Field Type Required Meaning
Type string Yes Attachment type id. This is the id used by weapons and attachment items.
Icon string No Slot icon path relative to Common/UI/Custom.
AnyAllowed boolean No Whether this type can be placed into wildcard * slots. Defaults to true.
ConflictsWith string array No Other attachment type ids that cannot be installed together with this type.
MaxCount integer No Maximum number of installed attachments of this type on one weapon.

Example: scope type

{
  "Type": "Scope",
  "Icon": "Attachments/scope.png",
  "AnyAllowed": false,
  "ConflictsWith": ["ThermalScope"],
  "MaxCount": 1
}

AnyAllowed: false is useful for attachments like scopes. A weapon may have a dedicated Scope slot and also wildcard slots, but you may still want to prevent a second scope from being installed into a wildcard slot.

ConflictsWith is checked both ways. If either installed type declares a conflict with the other type, the combination is rejected.


3. Create an attachment item

An attachment item is a normal item asset with HyGuns.AttachmentSettings.

Example:

{
  "Id": "Attachment_Laser_Red",
  "TranslationProperties": {
    "Name": "Red Laser"
  },
  "Quality": "Uncommon",
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Laser",
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*0.85"
        }
      }
    }
  }
}

This item:

  • belongs to the Laser attachment type;
  • can be installed only into weapons that support Laser or compatible wildcard slots;
  • reduces weapon spread by multiplying it by 0.85 while installed.

4. Attachment settings fields

{
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Scope",
      "ZoomSettings": {
        "MaxDistance": 20.0,
        "MinDistance": 1.0,
        "DefaultZoomMultiplier": 1.0,
        "MaxZoomMultiplier": 6.0,
        "ZoomMultiplierStep": 1.0,
        "OverlayTexturePath": "Scopes/Scope_8x.png"
      },
      "FireSound": {
        "Volume": "*0.05"
      },
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*0.75"
        },
        "AutoGuidance": {
          "Enabled": true
        }
      }
    }
  }
}
Field Type Required Meaning
Type string Yes Attachment type id loaded from Server/HyGuns/AttachmentTypes.
SettingsModifiers object No Weapon stat modifiers applied while this attachment is installed.
ZoomSettings object No Zoom settings provided by this attachment.
FireSound object No Fire sound modifiers provided by this attachment.

5. Using SettingsModifiers

SettingsModifiers changes the effective weapon settings while the attachment is installed.

The block follows the same general shape as HyGuns.WeaponSettings, but numeric fields may also use operation strings.

Example:

{
  "SettingsModifiers": {
    "Projectiles": {
      "Spread": "*0.75",
      "Damage": "+2"
    },
    "Ammo": {
      "Capacity": "+10",
      "Reload": {
        "Time": "-0.2"
      }
    },
    "Fire": {
      "Cooldown": "*0.9"
    }
  }
}

Numeric operation tokens

Token Meaning Example
* multiply current value "Spread": "*0.75"
/ divide current value "Cooldown": "/2"
+ add to current value "Damage": "+2"
- subtract from current value "Reload": { "Time": "-0.2" }
= set final value "Cooldown": "=0.15"

Supported numeric modifier fields include:

Ammo.Capacity
Ammo.Reload.Amount
Ammo.Reload.Time
Fire.Cooldown
Projectiles.Spread
Projectiles.Count
Projectiles.Damage
AutoGuidance.ConeDegrees
AutoGuidance.MaxDistance
AutoGuidance.TurnRate
WallPenetration.Blocks
WallPenetration.DamageReductionModifier
WallPenetration.DamageReductionDistance

Non-numeric values are merged as normal partial weapon settings.

Example:

{
  "SettingsModifiers": {
    "AutoGuidance": {
      "Enabled": true,
      "ConeDegrees": 25.0,
      "MaxDistance": 80.0,
      "TurnRate": 240.0,
      "EffectId": "MarkedTarget"
    }
  }
}

6. Create a scope attachment

Attachment type

File:

Server/HyGuns/AttachmentTypes/Scope.json
{
  "Type": "Scope",
  "Icon": "Attachments/scope.png",
  "AnyAllowed": false,
  "ConflictsWith": ["ThermalScope"],
  "MaxCount": 1
}

Attachment item

{
  "Id": "Scope_8x",
  "TranslationProperties": {
    "Name": "8x Scope"
  },
  "Quality": "Rare",
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Scope",
      "ZoomSettings": {
        "MaxDistance": 20.0,
        "MinDistance": 1.0,
        "DefaultZoomMultiplier": 1.0,
        "MaxZoomMultiplier": 6.0,
        "ZoomMultiplierStep": 1.0,
        "OverlayTexturePath": "Scopes/Scope_8x.png"
      },
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*0.9"
        }
      }
    }
  }
}

ZoomSettings can be defined on any attachment type, not only scopes. When a zoom interaction runs, the first installed valid attachment with ZoomSettings overrides the interaction zoom settings.


7. Create a silencer attachment

Attachment type

{
  "Type": "Silencer",
  "Icon": "Attachments/silencer.png",
  "AnyAllowed": true,
  "ConflictsWith": ["MuzzleBrake"],
  "MaxCount": 1
}

Attachment item

{
  "Id": "Silencer_Basic",
  "TranslationProperties": {
    "Name": "Basic Silencer"
  },
  "Quality": "Uncommon",
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Silencer",
      "FireSound": {
        "Volume": "*0.05"
      },
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*1.05"
        },
        "Fire": {
          "Cooldown": "*1.1"
        }
      }
    }
  }
}

FireSound.Volume uses the same numeric operation syntax as settings modifiers. For example, "*0.05" multiplies the current fire sound volume by 0.05.

To make FireSound work, use Hyguns_PlayWeaponFireSound in the weapon interaction instead of relying only on standard item effect sounds.


8. Add attachment slots to a weapon

A weapon accepts attachments through HyGuns.WeaponSettings.SupportedAttachments.

Example:

{
  "Id": "Weapon_Rifle_Custom",
  "TranslationProperties": {
    "Name": "Custom Rifle"
  },
  "HyGuns": {
    "WeaponSettings": {
      "WeaponIcon": "Weapons/CustomRifle.png",

      "Ammo": {
        "Family": "Bullet",
        "WeaponClass": "Rifle",
        "ItemId": "Ammo_Bullet_Base",
        "Capacity": 30,
        "Reload": {
          "Time": 1.5,
          "Amount": 30
        }
      },

      "Fire": {
        "Cooldown": 0.1
      },

      "Projectiles": {
        "ConfigId": "Rifle",
        "ProjectileId": "Projectile_Bullet_Base",
        "Spread": 0.02,
        "Count": 1,
        "Damage": 8
      },

      "SupportedAttachments": {
        "Scope": {
          "Count": 1,
          "Visual": true,
          "Index": 0
        },
        "Silencer": {
          "Count": 1,
          "Visual": true,
          "Index": 1
        },
        "Laser": {
          "Count": 1
        },
        "*": {
          "Count": 2
        }
      }
    }
  }
}

Slot fields

Field Type Meaning
Count integer Number of slots to create for this type.
Visual boolean Whether this type contributes to visual state key generation.
Index integer Ordering value for visual state keys and front-of-grid slot ordering.

The special key * creates wildcard slots. Wildcard slots only accept valid attachment items whose attachment type has AnyAllowed enabled.

Wildcard slots do not bypass compatibility. They still reject:

  • non-attachment items;
  • attachment types with AnyAllowed: false;
  • conflicting attachment types;
  • attachments beyond MaxCount.

9. Add default attachments to a weapon

DefaultAttachments creates attachment item stacks automatically when a weapon is initialized for the first time.

Important: values are real item asset ids, not attachment type ids.

{
  "HyGuns": {
    "WeaponSettings": {
      "SupportedAttachments": {
        "Scope": {
          "Count": 1
        },
        "Magazine": {
          "Count": 1
        }
      },
      "DefaultAttachments": {
        "Scope": "Scope_8x",
        "Magazine": ["Magazine_Tier_II"]
      }
    }
  }
}

The key is the preferred slot type. The created item still has to pass normal attachment compatibility checks, including type, conflicts, wildcard rules, and MaxCount.


10. Visual weapon states for installed attachments

Visual state switching is driven by SupportedAttachments.

Every supported attachment type with:

"Visual": true

and an Index contributes its type id to the state key when a valid attachment of that type is installed.

The key is built in Index order and joined with _.

Example:

{
  "HyGuns": {
    "WeaponSettings": {
      "SupportedAttachments": {
        "Scope": {
          "Count": 1,
          "Visual": true,
          "Index": 0
        },
        "Silencer": {
          "Count": 1,
          "Visual": true,
          "Index": 1
        },
        "Magazine": {
          "Count": 2
        }
      }
    }
  },
  "State": {
    "Scope": {
      "Model": "Items/Weapons/Rifle/Rifle_Scope.blockymodel"
    },
    "Silencer": {
      "Model": "Items/Weapons/Rifle/Rifle_Silencer.blockymodel"
    },
    "Scope_Silencer": {
      "Model": "Items/Weapons/Rifle/Rifle_Scope_Silencer.blockymodel"
    }
  }
}

In this example:

Installed visual attachments State key
only Scope Scope
only Silencer Silencer
Scope + Silencer Scope_Silencer
none base item state

The generated state key must exist in the item JSON State block.

Automatic visual state updates happen when default attachments are added during first weapon initialization and when the attachment window is closed.


11. Open the attachment UI

Use the Hyguns_OpenAttachments interaction.

{
  "Type": "Hyguns_OpenAttachments"
}

This opens the held weapon attachment container.

A common pattern is to bind this interaction to a weapon action, for example a secondary use, radial menu entry, or another custom interaction path depending on how your item is configured.

Example:

{
  "Interactions": {
    "Use": [
      {
        "Type": "Hyguns_OpenAttachments"
      }
    ]
  }
}

Use the exact interaction location supported by your item setup.


12. Require an installed attachment before zooming

Use Hyguns_AttachmentsInstalled before a zoom interaction.

{
  "Type": "Hyguns_AttachmentsInstalled",
  "AttachmentTypes": ["Scope"],
  "RequireAll": false,
  "Next": {
    "Type": "Scope_Zoom"
  },
  "Failed": {
    "Type": "Hyguns_ResetZoom"
  }
}

Fields:

Field Type Meaning
AttachmentTypes string array Attachment type ids to check.
AttachmentsTypes string array Alias for AttachmentTypes.
RequireAll boolean false means at least one requested type is required; true means all requested types are required.

If AttachmentTypes is omitted or empty, the check succeeds when any valid attachment is installed.


13. Scope zoom interactions

Toggle zoom

{
  "Type": "Scope_Zoom"
}

With explicit fallback settings:

{
  "Type": "Scope_Zoom",
  "OverlayTexturePath": "UI/Scope/ScopeOverlay.png",
  "MaxDistance": 20.0,
  "MinDistance": 1.0,
  "DefaultZoomMultiplier": 1.0,
  "MaxZoomMultiplier": 2.5,
  "ZoomMultiplierStep": 0.5
}

If the installed attachment has ZoomSettings, those settings override the interaction zoom settings.

Increase zoom step

{
  "Type": "Scope_Zoom_In"
}

Decrease zoom step

{
  "Type": "Scope_Zoom_Out"
}

Cycle zoom step

{
  "Type": "Scope_Step_Zoom"
}

Reset zoom

{
  "Type": "Hyguns_ResetZoom"
}

14. Play fire sounds with attachment modifiers

Use Hyguns_PlayWeaponFireSound when silencers or other attachments should modify shot volume.

{
  "Type": "Hyguns_PlayWeaponFireSound",
  "WorldSoundEventId": "Rifle_Fire",
  "LocalSoundEventId": "Rifle_Fire"
}

Example silencer:

{
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Silencer",
      "FireSound": {
        "Volume": "*0.05"
      }
    }
  }
}

Do not keep the same fire sound in the standard Effects.WorldSoundEventId or Effects.LocalSoundEventId on the same shot interaction, otherwise both the standard sound and the HyGuns-modified sound may play.


15. Complete example: custom rifle with scope, silencer, and laser

Attachment type: Laser

{
  "Type": "Laser",
  "Icon": "Attachments/laser.png",
  "AnyAllowed": true,
  "ConflictsWith": [],
  "MaxCount": 1
}

Attachment item: Laser_Red

{
  "Id": "Laser_Red",
  "TranslationProperties": {
    "Name": "Red Laser"
  },
  "Quality": "Uncommon",
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Laser",
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*0.85"
        }
      }
    }
  }
}

Attachment item: Scope_8x

{
  "Id": "Scope_8x",
  "TranslationProperties": {
    "Name": "8x Scope"
  },
  "Quality": "Rare",
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Scope",
      "ZoomSettings": {
        "MaxDistance": 20.0,
        "MinDistance": 1.0,
        "DefaultZoomMultiplier": 1.0,
        "MaxZoomMultiplier": 6.0,
        "ZoomMultiplierStep": 1.0,
        "OverlayTexturePath": "Scopes/Scope_8x.png"
      },
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*0.9"
        }
      }
    }
  }
}

Attachment item: Silencer_Basic

{
  "Id": "Silencer_Basic",
  "TranslationProperties": {
    "Name": "Basic Silencer"
  },
  "Quality": "Uncommon",
  "HyGuns": {
    "AttachmentSettings": {
      "Type": "Silencer",
      "FireSound": {
        "Volume": "*0.05"
      },
      "SettingsModifiers": {
        "Projectiles": {
          "Spread": "*1.05"
        },
        "Fire": {
          "Cooldown": "*1.1"
        }
      }
    }
  }
}

Weapon item

{
  "Id": "Weapon_Custom_Rifle",
  "TranslationProperties": {
    "Name": "Custom Rifle"
  },
  "HyGuns": {
    "WeaponSettings": {
      "WeaponIcon": "Weapons/CustomRifle.png",

      "Ammo": {
        "Family": "Bullet",
        "WeaponClass": "Rifle",
        "ItemId": "Ammo_Bullet_Base",
        "Capacity": 30,
        "Reload": {
          "Time": 1.5,
          "Amount": 30
        }
      },

      "Fire": {
        "Cooldown": 0.1
      },

      "Projectiles": {
        "ConfigId": "Rifle",
        "ProjectileId": "Projectile_Bullet_Base",
        "Spread": 0.02,
        "Count": 1,
        "Damage": 8
      },

      "SupportedAttachments": {
        "Scope": {
          "Count": 1,
          "Visual": true,
          "Index": 0
        },
        "Silencer": {
          "Count": 1,
          "Visual": true,
          "Index": 1
        },
        "Laser": {
          "Count": 1
        },
        "*": {
          "Count": 1
        }
      },

      "DefaultAttachments": {
        "Laser": "Laser_Red"
      }
    }
  },

  "State": {
    "Scope": {
      "Model": "Items/Weapons/CustomRifle/CustomRifle_Scope.blockymodel"
    },
    "Silencer": {
      "Model": "Items/Weapons/CustomRifle/CustomRifle_Silencer.blockymodel"
    },
    "Scope_Silencer": {
      "Model": "Items/Weapons/CustomRifle/CustomRifle_Scope_Silencer.blockymodel"
    }
  }
}

16. Suggested interaction setup

Fire chain with attachment-aware sound

{
  "Type": "Hyguns_CanShoot",
  "Next": {
    "Type": "Hyguns_PlayWeaponFireSound",
    "WorldSoundEventId": "CustomRifle_Fire",
    "LocalSoundEventId": "CustomRifle_Fire",
    "Next": {
      "Type": "Hyguns_Shoot"
    }
  }
}

Open attachments

{
  "Type": "Hyguns_OpenAttachments"
}

Zoom only when a scope is installed

{
  "Type": "Hyguns_AttachmentsInstalled",
  "AttachmentTypes": ["Scope"],
  "RequireAll": false,
  "Next": {
    "Type": "Scope_Zoom"
  },
  "Failed": {
    "Type": "Hyguns_ResetZoom"
  }
}

17. Checklist

When an attachment does not work, check the following:

  • The attachment type JSON exists under Server/HyGuns/AttachmentTypes.
  • The type JSON has the correct Type value.
  • The attachment item has HyGuns.AttachmentSettings.Type.
  • The weapon has a matching entry in SupportedAttachments.
  • The attachment does not exceed MaxCount.
  • The attachment type is not blocked by ConflictsWith.
  • If installing into a wildcard * slot, the type has AnyAllowed: true.
  • If using visual states, the supported slot has Visual: true and an Index.
  • If using visual states, the generated state key exists in the item State block.
  • If using silencer-like sound changes, the shot uses Hyguns_PlayWeaponFireSound.
  • If using scope zoom, the interaction checks Hyguns_AttachmentsInstalled before running Scope_Zoom.
  • Numeric modifier strings start with one of: *, /, +, -, =.

Clone this wiki locally