Scripts and Runtime
Decision Scripts
Section titled “Decision Scripts”Scripts are written in Lua and are the module’s decision core. A new module ships with no scripts — you write them yourself: double-click a Lua row in the editor to open it, give it a name, and enter code.
Execution Model
Section titled “Execution Model”Each trigger runs the whole script once — don’t write an infinite loop inside. The “loop” comes from outside: as long as you hold the start key (hold mode) or leave the toggle on (toggle mode), the app calls your script once per pass at the APM pace. So the script only states what to do right now: if true, fire one macro; if false, do nothing and try again next pass.
Available Functions
Section titled “Available Functions”| Function | Purpose |
|---|---|
Prop(name) |
Read a property’s current value (a number). The name must match the property table exactly, or this pass errors out. |
Macro(slotOrName) |
Calls a macro by slot or name. Returns whether dispatch was submitted, not whether a spell succeeded. Returns false when unavailable, unsynchronized or the frame is invalid. |
Cast(name) |
Supports existing macro names and synchronized dynamic names; returns nil. New code can use Macro(slotOrName) to obtain whether a key dispatch was submitted. |
Select(index) |
Select a target; equivalent to Cast("SelectTarget"..index): 1=self, 2-5=party 1-4, 6-45=raid 1-40. |
CoolDown(name, ms) |
Throttle gate: returns true only once ms milliseconds have passed since the last call, then resets. Use it to limit how often an action fires. |
SetTimeOut(name, ms)GetTimeOut(name) |
Set / query a timer point: expires after ms milliseconds; GetTimeOut returns whether it has expired. |
Sleep(ms) |
Block for some milliseconds (stalls the execution thread — usually prefer CoolDown). |
PressKey(code, [ms]) |
Send a virtual key code straight to the game, with an optional hold duration. |
The Lua standard library (math / string / table, etc.) is also available.
Example
Section titled “Example”Here is a sample script (rewrite it with your own property and macro names). It decides once per pass and uses CoolDown to avoid firing every tick:
-- 目标可攻击才输出if Prop("目标可攻击") == 1 then -- 血量低于 50% 且距上次补盾满 1.5 秒,补一次 if Prop("生命百分比") < 0.5 and CoolDown("补盾", 1500) then Cast("治疗术") -- 连击点满 5,放终结技 elseif Prop("连击点") >= 5 then Cast("终结技") else Cast("主输出") endendProp("生命百分比") is a preset property returning a 0~1 fraction; Prop("连击点") returns raw points. Names inside Cast must match macros in your macro table.
Binding & Running
Section titled “Binding & Running”After writing and naming the script, bind a start key (a mouse side button or a chosen keyboard key) to that script name in the main settings. Then hold the start key (hold mode) or press once (toggle mode), and the app runs it repeatedly at the APM pace.
The Custom Code Environment
Section titled “The Custom Code Environment”Each custom property’s code is wrapped into a no-argument function sharing the addon’s Lua scope. The generated form looks like this (the first line re-shadows a few combat-value functions so you get the raw values; the second injects the parameters):
SuperDPS.CustomFunc["属性名"] = function() local UnitHealth, UnitHealthMax, UnitPower, UnitPowerMax = SuperDPS.RawUnitHealth, SuperDPS.RawUnitHealthMax, SuperDPS.RawUnitPower, SuperDPS.RawUnitPowerMax local arg1, arg2, arg3 = "player", nil, nil -- 由「参数」列注入 -- 你的代码从这里开始,必须 return 一个值 return UnitHealth(arg1)endYour code must return a value (number or boolean). Booleans come back as 1 / 0; returning nil or a runtime error is treated as 0, and each error is reported in chat only once. Because it shares the addon scope, you can call the compatibility functions below directly.
Compatibility Functions You Can Call Directly
Section titled “Compatibility Functions You Can Call Directly”GetSpellInfo(spell) GetSpellCooldown(spell) GetSpellCharges(id)UnitAura(unit,i,filter) UnitBuff(unit,i) UnitDebuff(unit,i)issecret(v) -- 判断是否为受保护值Interfaces Provided by SuperDPS
Section titled “Interfaces Provided by SuperDPS”| Interface | Purpose |
|---|---|
SuperDPS.GetUnitBuff(unit, aura)SuperDPS.GetUnitDebuff(unit, aura)SuperDPS.GetUnitAura(unit, aura, filter) |
Query auras. aura may be a spell ID or name. Returns 15 values: name, icon, count, dispelType, duration, expirationTime, source, ...; count / duration / expirationTime are already sanitized. Buff/Debuff take no filter argument. |
SuperDPS.SN(v, "标记") |
Sanitizer: turns a protected value or nil into 0 so it can be compared / computed. Run it before any calculation. |
SuperDPS.RawUnitHealth 等 4 个 Raw |
Raw (non-zeroed) health/power functions. In custom code the names UnitHealth etc. already point to these. |
SuperDPS.HekeliPrimary |
The ID of Hekili’s current top recommendation (a field, not a function); 0 when Hekili isn’t installed. |
SuperDPS.IsMidnight / SuperDPS.CleuAvailableSuperDPS.IsClassic() |
Contract stubs with fixed values that do not vary by client: the first two are boolean fields (always true / false) and IsClassic() is a function that always returns false. Retail and Classic share one code path, so these three cannot be used to detect the client — probe for the API itself instead, e.g. if C_AssistedCombat then. |
Writing for Protected Values (secret)
Section titled “Writing for Protected Values (secret)”Retail marks some combat values as protected. Always judge with issecret(v) — note that print() can display a protected value, so “seeing a number” doesn’t mean it’s computable. The rules for protected values:
| Allowed | Forbidden |
|---|---|
Direct return, passing as an argument, string concatenation, string.format / tostring, and truthiness tests like X or 0 / if not X on non-boolean values |
Arithmetic, comparison (> == etc.), truthiness tests on booleans, length, use as a table key, indexing, and calling as a function |
This yields three postures:
- Pass-through: just fetch the value, no math. Return it directly, e.g.
return UnitHealth(arg1). - Sanitize: to compare or compute, first run
SuperDPS.SN(v, "tag")to zero it, then calculate. - Only compare, calculate or index values confirmed to be non-secret. Sanitize recommended spell IDs with
SuperDPS.SNtoo, then check their type and range.