Skip to content

๐Ÿท๏ธ PlaceholderAPI Placeholders โ€‹

Previous: Eventsใ€€ยทใ€€Next: Script API

QS exposes skill runtime data to HUDs, scoreboards, BetterHud, and other consumers through PlaceholderAPI (PAPI). The identifier prefix is always qinhskills. This chapter lists all placeholders and gives usage examples. This document targets QS 1.0.22.

PAPI is an optional soft dependency. When PlaceholderAPI isn't installed, QS doesn't register placeholders (it skips when PapiBridge.isEnabled() is false); everything else keeps working.


1. Global placeholders โ€‹

No skill id required; these reflect the player's overall state:

PlaceholderReturnsNotes
%qinhskills_skill_count%IntegerTotal number of skills defined on the server
%qinhskills_unlocked_count%IntegerNumber of skills this player has unlocked
%qinhskills_mana%IntegerThe player's current mana (truncated)
%qinhskills_mana_max%IntegerMana cap (config resources.max_mana, default 100)

โš ๏ธ mana / mana_max are temporary placeholders until QC takes over. The resource pool ultimately belongs to QinhClass; once QC takes over, the data source for these two placeholders switches to QC while the key names stay the same. See Data Storage.


2. Per-skill placeholders โ€‹

Format:

%qinhskills_<skillId>_<suffix>%

For example, the remaining cooldown seconds of skill fire_wave: %qinhskills_fire_wave_cooldown%.

SuffixReturnsNotes
_levelIntegerThe player's level for this skill (default 1)
_unlockedtrue/falseWhether it's unlocked
_readytrue/falseWhether it can currently be cast (cooldown / charges, etc. combined)
_cooldownSeconds (1 decimal)Remaining cooldown in seconds, e.g. 2.4
_cooldown_msMillisecondsRemaining cooldown in milliseconds
_chargesIntegerCurrent charge count
_max_chargesIntegerCharge cap
_toggledtrue/falseWhether a toggle skill is in the on state
_channelingtrue/falseWhether a channel cast bar is in progress
_channel_progressInteger 0โ€“100Channel progress percentage

๐Ÿ“Œ Suffixes are matched from the tail (_cooldown_ms matches before _cooldown to avoid ambiguity). Don't let a skill id itself contain fragments identical to these suffixes.

Resolution logic: _level reads the profile directly; the rest pull live state from the internal skillStatus(uuid, skillId).

Null behavior: when a skill has no state record in the player's profile, or the skill id doesn't exist at all, skillStatus returns null, so the corresponding per-skill placeholder returns null (PAPI usually renders this as an empty string). Other per-skill suffixes (_cooldown / _ready / _charges, etc.) are likewise empty when there's no state. _level is the exception: when a skill is defined but has no record, it's treated as 1.


3. Usage examples โ€‹

Scoreboard / Actionbar โ€‹

yaml
# Some scoreboard plugin
lines:
  - "&6Fire Wave &7Lv.%qinhskills_fire_wave_level%"
  - "&7Cooldown: &e%qinhskills_fire_wave_cooldown%s"
  - "&7Charges: &b%qinhskills_dash_charges%/%qinhskills_dash_max_charges%"
  - "&9Mana &b%qinhskills_mana%&7/&b%qinhskills_mana_max%"

BetterHud channel cast bar โ€‹

Skills with channel.bar_type: none hand bar drawing to the HUD itself โ€” a perfect fit for the progress placeholder:

yaml
# BetterHud component (pseudo-config)
condition: "%qinhskills_demo_slash_charged_channeling% == true"
progress: "%qinhskills_demo_slash_charged_channel_progress%"   # 0-100

Greying out a button by unlock state โ€‹

yaml
# Menu plugin
icon:
  material: "DIAMOND_SWORD"
  glow: "%qinhskills_fire_wave_unlocked%"   # glows when true
  lore:
    - "%qinhskills_fire_wave_ready% available state"

4. Things to watch โ€‹

  • Case: skill ids are always lowercase inside QS. Writing skill ids in lowercase in placeholders too is recommended so they match.
  • Offline players: the placeholder callback returns null when player == null; offline player data depends on whether PAPI provides an OfflinePlayer.
  • Refresh rate: placeholders are pull-based โ€” the consumer (scoreboard/HUD) calls them on its own refresh cadence. For a smooth _cooldown countdown, just have the HUD refresh at a high frequency.
  • QS does not draw UI. Placeholders are only a data outlet; UI/HUD belong to the consumer.

5. Quick reference (from SKILL_REFERENCE) โ€‹

Per-skill: %qinhskills_<skill>_cooldown%(remaining sec) _cooldown_ms _charges _max_charges
           _ready(true/false) _unlocked _toggled _channeling _channel_progress(0-100) _level
Global:    %qinhskills_skill_count% %qinhskills_unlocked_count%
           %qinhskills_mana% %qinhskills_mana_max% (placeholders until QC takes over)

Further reading โ€‹

  • API โ€” read isUnlocked / setLevel directly in code
  • Data Storage โ€” the PlayerSkillProfile behind the placeholders
  • Diagnostics & Protocol โ€” how to troubleshoot when a placeholder returns null