Skip to content

Cube

The core.cube module drives the Auto Cube state machine that lives under the Autos → Auto Cube panel. It writes through the same settings the web UI exposes, so changes show up in the menu and persist across sessions. The frontend widget and your Lua script share state — toggling one is visible to the other.

TIP

Auto Cube runs on the equipped or inventory item at the configured slot. Negative slot numbers refer to equipped items (e.g. -11 = weapon); positive numbers refer to Equip Tab slot 1 → N in the inventory.

Matching logic

Each cube roll's three potential lines are resolved to displayed strings (via the same game tooltip resolver the UI uses), then parsed into canonical {stat, value} pairs. A roll matches when every condition group is satisfied — see set_conditions below.

Functions

core.cube.start([opts: table]) -> boolean, string?

Configures and starts an Auto Cube run. All opts fields are optional — anything you omit keeps its current setting. The slot must be non-zero (either passed in opts or already configured) or start() returns false with an error message.

opts fields:

FieldTypeDescription
slotnumberEquipment slot. Negative = equipped (e.g. -11 = weapon), positive = Equip inventory slot.
cube_typestring | number"glowing", "bright", "mystical", "hard", or "solid" (also accepts 04). Mystical/Hard/Solid cap rolls at Epic/Unique/Legendary respectively.
min_gradenumberFloor for accepted rolls: 0=Common, 1=Rare, 2=Epic, 3=Unique, 4=Legendary. Setting min_grade above the cube's physical max tier will never be satisfied.

Returns: true on success, or false, "<error message>" if the slot isn't set, the cube type is unknown, or the autos module isn't ready.

lua
-- Tap the trigger using existing settings
core.cube.start()

-- Configure everything in one shot
local ok, err = core.cube.start({
    slot      = -11,        -- weapon
    cube_type = "bright",
    min_grade = 3,          -- Unique+
})
if not ok then core.log_error(err) end

core.cube.stop() -> boolean

Disables Auto Cube. Returns true if the toggle was flipped, false if the autos module isn't loaded. Safe to call when not running.


core.cube.is_running() -> boolean

Convenience wrapper for "is the Enable Auto Cube checkbox on right now?". Returns true while a run is active.


core.cube.get_status() -> table

Returns a snapshot of the current run.

FieldTypeDescription
runningbooleanWhether the Auto Cube toggle is on.
statestringState machine state: "idle", "sending_cube", "waiting_result", "checking_result", "accepting", "rejecting", "waiting_reject_confirm", "cooldown".
slotnumberSlot the run is targeting.
cubes_usednumberCubes consumed in this run.
last_rolledtable{ p1, p2, p3, grade } — the three potential IDs from the most recent roll and its grade.
resulttableLive status object pushed to the web UI.
lua
local s = core.cube.get_status()
core.log(string.format("[%s] slot=%d  cubes=%d  last=(%d, %d, %d)",
    s.state, s.slot or 0, s.cubes_used,
    s.last_rolled.p1, s.last_rolled.p2, s.last_rolled.p3))

core.cube.set_conditions(spec: table) -> boolean, string?

Defines what counts as a "good roll". Conditions are OR-of-AND: the roll is accepted as soon as any one group is fully satisfied, where a group is a list of conditions that must all hold.

Two input shapes are accepted:

lua
-- Flat (single AND group):
core.cube.set_conditions({
    { stat = "STR %",          min = 21 },
    { stat = "Boss Damage %",  min = 30 },
})

-- OR-of-AND (any group passes -> accept):
core.cube.set_conditions({
    { { stat = "Boss Damage %",          min = 30 },
      { stat = "Ignore Defense %",       min = 30 } },
    { { stat = "Attack Power %",         min = 18 },
      { exact = "30% chance to ignore 100% damage when attacked.", count = 1 } },
})

Each leaf is either:

  • { stat = "<canonical name>", min = <int> } — summed across all three lines (e.g. three STR +5% lines aggregate to 15).
  • { exact = "<exact tooltip line>", count = <int> } — matched literally, useful for lines like proc chances that don't parse into a stat number.

Canonical stat names are what parse_potential produces from the displayed tooltip string. The common ones, grouped by family:

  • Single stats: STR, STR %, DEX, DEX %, INT, INT %, LUK, LUK %, All Stats, All Stats %
  • Combat: Attack Power, Attack Power %, Magic ATT, Magic ATT %, DEF, DEF %
  • HP/MP: Max HP, Max HP %, Max MP, Max MP %
  • Damage: Boss Damage %, Critical Damage %, Critical Rate %, Damage %
  • Utility: Ignore Defense %, Item Drop Rate %, Mesos Obtained %, EXP Obtained %
  • Cooldowns/Costs: Cooldown Reduction (sec), MP Cost Reduction %

All Stats % automatically counts toward STR %/DEX %/INT %/LUK % thresholds, mirroring how the in-game total is computed.

If you're unsure what name a tooltip line resolves to, feed it through parse_potential first:

lua
core.cube.parse_potential("Boss Damage: +30%")  --> { stat = "Boss Damage %", value = 30 }

Returns: true on success, or false, "<error>" if an entry is missing required fields or has the wrong types.


core.cube.get_conditions() -> table | nil

Returns the stored conditions as a nested Lua table, in the same OR-of-AND shape as what set_conditions writes. Returns nil if the autos module isn't loaded.


core.cube.clear_conditions() -> boolean

Removes all conditions. With no conditions set, every roll that passes the min_grade floor will be accepted.


core.cube.resolve_potential(pot_id: number [, level: number]) -> string | nil

Resolves a raw potential ID (e.g. one of the values returned in get_status().last_rolled) to its displayed tooltip line — for example "Boss Damage +30%". The "[Grade]" suffix is stripped.

If level is omitted, the function looks up the level by matching pot_id against the three potential IDs on the configured equip slot. Pass level explicitly if you're inspecting a potential that isn't on the current item.

Returns nil if pot_id is 0, the game function can't be resolved, or the lookup fails.

lua
local s = core.cube.get_status()
core.log(core.cube.resolve_potential(s.last_rolled.p1))

core.cube.parse_potential(str: string) -> table | nil

Parses a displayed tooltip line into its canonical {stat, value} form — the same canonical name that set_conditions matches against. Returns nil for lines that don't fit any known stat pattern (e.g. "30% chance to reflect 30% damage." — those need exact matching instead).

lua
core.cube.parse_potential("STR: +12%")           --> { stat = "STR %",          value = 12 }
core.cube.parse_potential("Skill Cooldowns -2 sec")  --> { stat = "Cooldown Reduction (sec)", value = 2 }
core.cube.parse_potential("30% chance to reflect 30% damage.")  --> nil

core.cube.inspect_current_item() -> table | nil

Reads the equip configured under Autos → Auto Cube → Equip Slot and returns its three rolled potentials, fully resolved and parsed.

FieldTypeDescription
gradenumberTier of the rolls (0=Common .. 4=Legendary). Derived from the first potential ID.
potentialstableArray of 3 entries, one per potential line.

Each potentials[i] entry:

FieldTypeDescription
idnumberRaw potential ID.
levelnumberPer-line option level used for value scaling.
linestringResolved tooltip text. Empty string for unused slots.
statstring?Canonical stat name, if the line parses.
valuenumber?Parsed numeric value, if the line parses.

Returns nil if the equip slot is 0 or no item is at that slot.

lua
local inspected = core.cube.inspect_current_item()
if inspected then
    core.log("Grade: " .. inspected.grade)
    for i, p in ipairs(inspected.potentials) do
        core.log(string.format("  %d: %s", i, p.line))
    end
end

Example: stop when conditions are met and log progress

lua
plugin = {
    name        = "Cube Watchdog",
    version     = "1.0.0",
    author      = "you",
    description = "Auto-stops when goals are reached; reports every roll",
    load        = true,
}

local last_cubes = 0

function on_tick()
    local s = core.cube.get_status()
    if not s.running then return end

    if s.cubes_used ~= last_cubes then
        last_cubes = s.cubes_used
        local p1 = core.cube.resolve_potential(s.last_rolled.p1) or "?"
        local p2 = core.cube.resolve_potential(s.last_rolled.p2) or "?"
        local p3 = core.cube.resolve_potential(s.last_rolled.p3) or "?"
        core.log(string.format("Cube %d -> [%s | %s | %s]",
            s.cubes_used, p1, p2, p3))
    end
end

Example: set up "Boss Damage 30% AND Ignore Defense 30%" and start

lua
local ok, err = core.cube.set_conditions({
    { stat = "Boss Damage %",     min = 30 },
    { stat = "Ignore Defense %",  min = 30 },
})
if not ok then return core.log_error(err) end

core.cube.start({ slot = -11, cube_type = "bright", min_grade = 3 })