-
Notifications
You must be signed in to change notification settings - Fork 0
WeaponCustomHUD
This guide explains how to add a custom weapon HUD to an item asset, how to place icon files in an asset pack, how presets work, and how to use the WeaponCustomHUD JSON interactions.
The goal is simple: if you have an item with interactions, you can make a HUD for it without writing Java code.
WeaponCustomHUD shows a custom input HUD while the player is holding an item that has a WeaponCustomHUD block.
It can show:
- primary fire
- secondary fire / zoom
- ability slots
- reload
- use / attachments
- dodge
- a large signature-style ability
- cooldown progress
- use flashes
- error flashes
- state-dependent icons and visibility
When enabled for an item, WeaponCustomHUD also patches the item's root interactions at runtime. It inserts a tiny generated marker interaction before the original interaction chain. That marker tells the HUD which slot was pressed, then the original interaction chain continues normally.
Generated interactions are refreshed when assets reload. If the original root interaction chain changes, WeaponCustomHUD compares the generated root against the desired chain and rebuilds it only when needed. This avoids stale HUD bindings without causing an infinite asset reload loop.
You need:
- the
WeaponCustomHUDplugin installed and enabled on the server - an asset pack that contains your item asset
- optional icon textures in the asset pack
- optional preset JSON files in the asset pack
If your asset pack uses WeaponCustomHUD item blocks or WeaponCustomHUD interactions, it should depend on the WeaponCustomHUD plugin/pack in its manifest. This keeps load order predictable.
Add a top-level WeaponCustomHUD block to your item JSON:
{
"Id": "Weapon_TestRifle",
"TranslationProperties": {
"Name": "Test Rifle"
},
"WeaponCustomHUD": {
"Enabled": true
}
}This enables the built-in standard HUD preset.
For most weapons you should use a preset instead:
{
"Id": "Weapon_TestRifle",
"TranslationProperties": {
"Name": "Test Rifle"
},
"WeaponCustomHUD": {
"Enabled": true,
"Preset": "MyRifleHud"
}
}Recommended asset pack layout:
YourAssetPack/
manifest.json
Server/
Items/
Weapon_TestRifle.json
WeaponCustomHUD/
Presets/
MyRifleHud.json
Common/
UI/
Custom/
Hud/
WeaponCustomHUD/
Icons/
Shoot.png
Shoot@2x.png
Reload.png
Reload@2x.png
Scope.png
Scope@2x.png
Attachments.png
Attachments@2x.png
Use @2x versions when you want sharper UI icons. If you provide only one version, use the normal .png file first.
In JSON, do not write the full filesystem path.
If the file is here:
Common/UI/Custom/Hud/WeaponCustomHUD/Icons/Shoot.png
Use this in JSON:
"Icons": "WeaponCustomHUD/Icons/Shoot.png"You can also write:
"Icons": "Hud/WeaponCustomHUD/Icons/Shoot.png"WeaponCustomHUD only adds the Hud/ prefix when it is missing. It does not add WeaponCustomHUD/ or Icons/ for you.
These two values resolve to the same texture path:
"Icons": "WeaponCustomHUD/Icons/Shoot.png""Icons": "Hud/WeaponCustomHUD/Icons/Shoot.png"This value does not automatically become WeaponCustomHUD/Icons/Shoot.png:
"Icons": "Icons/Shoot.png"It becomes:
Hud/Icons/Shoot.png
So if your icon is inside Common/UI/Custom/Hud/WeaponCustomHUD/Icons, include WeaponCustomHUD/Icons/... in the JSON manually.
Do not use:
Common/UI/Custom/Hud/WeaponCustomHUD/Icons/Shoot.png
That is the asset pack file location, not the UI texture path.
Preset files go here:
Server/WeaponCustomHUD/Presets/<PresetId>.json
For example:
Server/WeaponCustomHUD/Presets/MyRifleHud.json
Then the item uses:
{
"WeaponCustomHUD": {
"Enabled": true,
"Preset": "MyRifleHud"
}
}Preset files are already the settings object. Do not wrap a preset in another WeaponCustomHUD key.
Correct preset:
{
"Scale": 0.85,
"Placement": "BottomRight",
"Position": [50, 40],
"Abilities": {
"Primary": {
"Display": true,
"Enabled": true,
"Icons": "WeaponCustomHUD/Icons/Shoot.png"
}
}
}Wrong preset:
{
"WeaponCustomHUD": {
"Scale": 0.85
}
}The wrapper is only used inside item JSON.
This preset is a good starting point for a rifle with fire, zoom, signature, reload, attachments, and dodge:
{
"Scale": 0.85,
"Placement": "BottomRight",
"Position": [50, 40],
"Abilities": {
"Primary": {
"Display": true,
"Enabled": {
"Default": true,
"Reloading": false,
"HasAmmo": true
},
"Icons": "WeaponCustomHUD/Icons/Shoot.png",
"Cooldown": "FireDelay"
},
"Secondary": {
"Display": true,
"Enabled": {
"Default": false,
"ZoomAvailable": true,
"Scoping": true
},
"Icons": {
"Default": "WeaponCustomHUD/Icons/Scope.png",
"Scoping": "WeaponCustomHUD/Icons/ZoomOut.png"
}
},
"Ability1": {
"Display": true,
"Enabled": true,
"Icons": "WeaponCustomHUD/Icons/Signature.png",
"Cooldown": "SignatureReady",
"Signature": true
},
"Ability3": {
"Display": true,
"Enabled": {
"Default": true,
"Reloading": false
},
"Icons": "WeaponCustomHUD/Icons/Reload.png",
"Cooldown": "Reloading"
},
"Use": {
"Display": true,
"Enabled": {
"Default": false,
"AttachmentAvailable": true
},
"Icons": "WeaponCustomHUD/Icons/Attachments.png"
},
"Dodge": {
"Display": true,
"Enabled": true,
"Icons": "WeaponCustomHUD/Icons/DodgeAbility.png"
}
}
}Important: HasAmmo, Reloading, FireDelay, ZoomAvailable, Scoping, and AttachmentAvailable are not built into WeaponCustomHUD itself. They are usually registered by another plugin, such as HyGuns. If no plugin registers them and no WCHud_SetState / WCHud_SetCooldown runtime override sets them, those state checks return false and those cooldown providers return 0.
WeaponCustomHUD itself always provides:
-
SignatureReadyas a state -
SignatureReadyas a cooldown provider
Item settings override preset settings.
Example: use the shared preset, but move only this weapon's HUD and replace one icon:
{
"WeaponCustomHUD": {
"Enabled": true,
"Preset": "MyRifleHud",
"Scale": 0.75,
"Position": [80, 60],
"Abilities": {
"Primary": {
"Icons": "WeaponCustomHUD/Icons/PlasmaShoot.png"
}
}
}
}Fallback order:
- item
WeaponCustomHUDblock - selected preset
- built-in standard preset
These fields can be used in a preset or directly in an item block:
| Field | Type | Default | Meaning |
|---|---|---|---|
Scale |
number | 1.0 |
Scales the HUD visual size. Must be positive. |
Placement |
string | BottomRight |
Screen anchor. |
Position |
array | [50, 40] |
Offset from the selected placement. |
Abilities |
object | standard preset | Per-slot HUD settings. |
Supported Placement values:
TopLeftTopRightBottomLeftBottomRight
Position does not get multiplied by Scale. It is always an absolute UI offset.
Supported ability keys:
PrimarySecondaryAbility1Ability2Ability3UseDodge
The keys are case-insensitive.
For interaction Target fields, these aliases are accepted:
| Slot | Accepted target aliases |
|---|---|
Primary |
Primary, Main, Left
|
Secondary |
Secondary, Alt, Right
|
Ability1 |
Ability1, Q
|
Ability2 |
Ability2, E
|
Ability3 |
Ability3, R
|
Use |
Use |
Dodge |
Dodge, Shift
|
For config JSON, prefer the official slot names.
Each ability can define:
| Field | Type | Meaning |
|---|---|---|
Display |
boolean or state map | Whether the slot is visible. |
Enabled |
boolean or state map | Whether the slot appears active. |
Icons |
string or state map | Texture path for the icon. |
Cooldown |
number, provider key, or state map | Cooldown progress source. |
Signature |
boolean | Renders the slot as the large signature slot. |
Always show a slot:
"Display": trueHide it by default, then show it when a state is true:
"Display": {
"Default": false,
"ZoomAvailable": true
}Show a slot as active only when a state is true:
"Enabled": {
"Default": false,
"HasAmmo": true
}Disable reload while reloading:
"Enabled": {
"Default": true,
"Reloading": false
}Use one icon all the time:
"Icons": "WeaponCustomHUD/Icons/Reload.png"Switch icon by state:
"Icons": {
"Default": "WeaponCustomHUD/Icons/Scope.png",
"Scoping": "WeaponCustomHUD/Icons/ZoomOut.png"
}Use no cooldown:
"Cooldown": 0Use a constant progress value:
"Cooldown": 0.5Use a registered cooldown provider:
"Cooldown": "Reloading"Use different cooldown providers by state:
"Cooldown": {
"Default": 0,
"Reloading": "Reloading",
"Overheated": "HeatCooldown"
}Cooldown values are clamped to 0.0 through 1.0.
Manual cooldowns started by WCHud_SetCooldown progress from 0.0 to 1.0 over their duration.
Mark a slot as the large signature slot:
{
"Ability1": {
"Display": true,
"Enabled": true,
"Icons": "WeaponCustomHUD/Icons/Signature.png",
"Cooldown": "SignatureReady",
"Signature": true
}
}Only one signature-style slot is recommended. The layout is designed for Ability1.
Display, Enabled, Icons, and Cooldown can use state maps.
State maps are evaluated in JSON order:
- start with
Default - for every state in order, if the state is true, replace the current value
- the last matching state wins
Example:
"Icons": {
"Default": "WeaponCustomHUD/Icons/Scope.png",
"ZoomAvailable": "WeaponCustomHUD/Icons/ScopeReady.png",
"Scoping": "WeaponCustomHUD/Icons/ZoomOut.png"
}If both ZoomAvailable and Scoping are true, Scoping wins because it appears later.
WeaponCustomHUD can use states and cooldowns registered through its API. JSON interactions can also set per-player runtime state and cooldown overrides.
Built-in:
| Key | Type | Meaning |
|---|---|---|
SignatureReady |
state | True when the held item's signature is ready. |
SignatureReady |
cooldown | Signature charge progress. |
Common keys registered by HyGuns:
| Key | Type | Typical meaning |
|---|---|---|
HasAmmo |
state | The held weapon can fire with current ammo. |
Reloading |
state and cooldown | The held weapon is reloading; cooldown is reload progress. |
FireDelay |
cooldown | Temporary fire delay progress. |
Scoping |
state | The player is currently scoped. |
ZoomAvailable |
state | The held weapon can zoom. |
AttachmentAvailable |
state | The held weapon has attachment slots or the requested attachment type is available. |
If you are writing another plugin, register your own:
import com.ensox.wchud.api.WCHudApi;
import com.ensox.wchud.api.WCHudApiProvider;
WCHudApi api = WCHudApiProvider.require();
api.registerState("Overheated", context -> isOverheated(context.playerRef()));
api.registerCooldown("HeatCooldown", context -> heatCooldownProgress(context.playerRef()));When WeaponCustomHUD.Enabled is true, WeaponCustomHUD looks at the item's Interactions map.
For each supported interaction type:
PrimarySecondaryAbility1Ability2Ability3UseDodge
WeaponCustomHUD generates:
- a
WCHud_UseKey/...marker interaction - a
WCHud_UseKeyRoot/...root interaction
The generated root runs the marker first, then runs your original root interaction chain.
This is why use flashes can work without manually adding WCHud_UseKey to every interaction.
Latest behavior:
- generated roots are refreshed when the original root chain changes
- unchanged generated roots are not reloaded
- stale generated marker/root assets are removed
- original pack assets are not deleted by WeaponCustomHUD
If a slot has no root interaction, WeaponCustomHUD can still display the slot, but it cannot automatically detect that the slot was pressed.
WeaponCustomHUD provides several interactions for asset authors.
These interactions are server-side, per-player, and runtime-only. They do not permanently modify item assets.
Sets a runtime state for the current player.
{
"Type": "WCHud_SetState",
"State": "Overheated",
"Value": true
}Fields:
| Field | Type | Required | Meaning |
|---|---|---|---|
State |
string | Yes | State key to override. |
Value |
boolean | Yes | State value. |
Use this when your interaction chain already knows a condition.
Example:
{
"Type": "WCHud_SetState",
"State": "Overheated",
"Value": true,
"Next": {
"Type": "WCHud_Error",
"Target": "Primary"
}
}Starts a manual cooldown for the current player.
{
"Type": "WCHud_SetCooldown",
"Target": "Ability3",
"Duration": 6.0
}Fields:
| Field | Type | Required | Meaning |
|---|---|---|---|
Target |
string | Yes | Slot name or custom cooldown key. |
Duration |
number | Yes | Duration in seconds. Must be greater than 0. |
If Target is a slot alias, WeaponCustomHUD also stores the cooldown under the normalized slot name.
You can display a manual cooldown without a custom provider:
{
"Ability3": {
"Display": true,
"Enabled": true,
"Icons": "WeaponCustomHUD/Icons/Vent.png"
}
}Then run:
{
"Type": "WCHud_SetCooldown",
"Target": "Ability3",
"Duration": 6.0
}If no explicit Cooldown is configured for the slot, the slot automatically uses its manual slot cooldown.
You can also use a custom key:
{
"Ability3": {
"Display": true,
"Icons": "WeaponCustomHUD/Icons/Vent.png",
"Cooldown": "VentCooldown"
}
}{
"Type": "WCHud_SetCooldown",
"Target": "VentCooldown",
"Duration": 6.0
}Clears a manual cooldown.
{
"Type": "WCHud_ResetCooldown",
"Target": "Ability3"
}Fields:
| Field | Type | Required | Meaning |
|---|---|---|---|
Target |
string | Yes | Slot name or custom cooldown key. |
Checks whether a manual cooldown exists.
{
"Type": "WCHud_HasCooldown",
"Target": "Ability3",
"Value": false,
"Next": {
"Type": "Your_Interaction"
},
"Failed": {
"Type": "WCHud_Error",
"Target": "Ability3"
}
}Fields:
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
Target |
string | Yes | none | Slot name or custom cooldown key. |
Value |
boolean | No | true |
Expected cooldown state. |
Use Value: false to allow an action only when the cooldown is not active.
Flashes a red error overlay on a slot.
{
"Type": "WCHud_Error",
"Target": "Primary"
}Fields:
| Field | Type | Required | Meaning |
|---|---|---|---|
Target |
string | Yes | Slot to flash. |
Put this in a Failed branch when an action is blocked.
Marks a slot as used.
{
"Type": "WCHud_UseKey",
"Slot": "Primary"
}Fields:
| Field | Type | Required | Meaning |
|---|---|---|---|
Slot |
string | Yes | Slot to flash as used. |
Most asset authors do not need to add this manually. WeaponCustomHUD generates it automatically when patching item root interactions.
Use it manually only for custom chains that are not attached through the item's normal interaction root.
Item file:
{
"Id": "Weapon_ExampleRifle",
"TranslationProperties": {
"Name": "Example Rifle"
},
"Interactions": {
"Primary": "ExampleRifle_PrimaryRoot",
"Secondary": "ExampleRifle_ZoomRoot",
"Ability3": "ExampleRifle_ReloadRoot",
"Use": "ExampleRifle_AttachmentsRoot"
},
"WeaponCustomHUD": {
"Enabled": true,
"Preset": "ExampleRifleHud"
}
}Preset file:
{
"Scale": 0.85,
"Placement": "BottomRight",
"Position": [50, 40],
"Abilities": {
"Primary": {
"Display": true,
"Enabled": {
"Default": true,
"HasAmmo": true,
"Reloading": false
},
"Icons": "WeaponCustomHUD/Icons/Shoot.png",
"Cooldown": "FireDelay"
},
"Secondary": {
"Display": true,
"Enabled": {
"Default": false,
"ZoomAvailable": true,
"Scoping": true
},
"Icons": {
"Default": "WeaponCustomHUD/Icons/Scope.png",
"Scoping": "WeaponCustomHUD/Icons/ZoomOut.png"
}
},
"Ability3": {
"Display": true,
"Enabled": {
"Default": true,
"Reloading": false
},
"Icons": "WeaponCustomHUD/Icons/Reload.png",
"Cooldown": "Reloading"
},
"Use": {
"Display": true,
"Enabled": {
"Default": false,
"AttachmentAvailable": true
},
"Icons": "WeaponCustomHUD/Icons/Attachments.png"
}
}
}Interaction example for a manual cooldown:
{
"Type": "WCHud_HasCooldown",
"Target": "Ability3",
"Value": false,
"Next": {
"Type": "Your_VentWeapon",
"Next": {
"Type": "WCHud_SetCooldown",
"Target": "Ability3",
"Duration": 6.0
}
},
"Failed": {
"Type": "WCHud_Error",
"Target": "Ability3"
}
}Check:
- the item has
"WeaponCustomHUD": { "Enabled": true } - the player is actually holding that item
- the item id matches the item asset that contains the settings
- the preset id is correct
- the preset JSON is in
Server/WeaponCustomHUD/Presets - the server log has no JSON parse errors
Check:
- the texture file is under
Common/UI/Custom/Hud - the JSON path does not include
Common/UI/Custom/Hud - the file extension is correct
- the path uses
/, not\ - the asset pack is loaded by the client/server
Correct:
"Icons": "WeaponCustomHUD/Icons/Shoot.png"File:
Common/UI/Custom/Hud/WeaponCustomHUD/Icons/Shoot.png
WeaponCustomHUD does not know most gameplay states by itself.
If you use this:
"Enabled": {
"Default": false,
"ZoomAvailable": true
}then some plugin must register ZoomAvailable.
If no plugin registers it and no interaction sets it with WCHud_SetState, it is always false.
Check:
- the
Cooldownvalue is a number, a registered provider key, or a manual cooldown target -
WCHud_SetCooldownhas a positiveDuration -
Targetmatches the slot or provider key used by the ability - if using a plugin provider, the provider is registered and returns progress from
0.0to1.0
The generated WCHud_UseKey marker only marks the HUD. It does not replace your original interaction.
Check that the item's original root interaction still exists and works.
Current WeaponCustomHUD refreshes generated roots when original root chains change. Save the changed asset and wait for asset reload.
If it still uses the old chain, check:
- the item asset actually reloaded
- the root interaction id in the item is the one you edited
- the server log has no
WeaponCustomHUD root refresh failedwarning - no other pack overrides the same item/root id later
WeaponCustomHUD removes stale generated marker/root interactions for ids it owns:
WCHud_UseKey/...WCHud_UseKeyRoot/...
It does not delete your original asset pack interactions. If you remove an original interaction asset from your pack, normal asset reload rules decide when that original asset disappears.
- Add
WeaponCustomHUD.Enabled: trueto the item. - Add a preset in
Server/WeaponCustomHUD/Presets. - Put icons under
Common/UI/Custom/Hud/WeaponCustomHUD/Icons. - Use icon paths like
WeaponCustomHUD/Icons/MyIcon.png. - Remember: WeaponCustomHUD adds only
Hud/; it does not addWeaponCustomHUD/Icons/. - Use official ability names in config:
Primary,Secondary,Ability1,Ability2,Ability3,Use,Dodge. - Use
WCHud_Errorin failed interaction branches. - Use
WCHud_SetCooldownfor manual cooldowns. - Do not rely on HyGuns states unless HyGuns is installed and registers them.
- Save assets and check the server log for parse/refresh warnings.