Violet

Star Force

On this page

The core.starforce module controls Auto Star Force, the feature under the Autos → Auto Starforce panel. It writes through the same settings the web UI exposes, so changes show up in the menu and persist across sessions.

Tip

Star Force 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.

Insufficient meso protection

Before every attempt, Auto Star Force checks the price with the server and refuses to make the attempt if the player can't cover it. get_status().result.status will report "insufficient_meso" when this happens and the run will stop on its own. If the server doesn't answer a run's first price check, the rest of that run checks against estimated prices instead (costSource = "estimate").

How a run works

  • Server price and odds. Before every attempt, the run asks the server for that attempt's price and odds and uses the server's price for the meso check. The quoted terms are available as get_status().result.quote. If the server doesn't answer the price check, the rest of that run uses estimated prices, including for the meso check: costSource is "estimate" and there is no quote. The MVP and Sunny Sunday settings only affect estimates (estimate_cost(), the panel's cost preview, and a run that is using estimated prices).
  • In-game enhancement window. While the in-game equipment enhancement window is open, the run pauses (status = "paused", reason = "native_ui_open") and resumes on its own once the window is closed.
  • Enhancement mode (0-3 = Level 1-Level 4) only applies to 15-21 star attempts, and Level 4 is only available from 18 stars. A level that isn't available for the item at its current star count is lowered to the highest one that is; items that can't use enhancement mode (such as Superior equipment) always use Level 1. It is ignored while safeguard applies.
  • Safeguard only applies to 15-17 star attempts, and only when the attempt can destroy the item. Other attempts are made without it and without its extra cost. While a run is using estimated prices, safeguard is requested, and its cost counted, on every 15-17 star attempt the item allows it on.
  • Equipped items need one free Equip inventory slot on attempts that can destroy them. If there is none, the run stops with "equip_tab_full".

Functions

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

Available on GMS

Configures and starts an Auto Star Force 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.
targetnumberStop at this star level (1-30).
safeguardbooleanProtect 15-17 star attempts against destruction for an extra cost. Not applied when the attempt can't destroy the item.
sunny_sundaybooleanApply the 30% Sunny Sunday discount to estimates. A run uses the server's price unless it is using estimated prices.
mvp_tierstring | number"none", "silver", "gold", "diamond" (or 0-3). Discount on attempts up to 17 stars; only used for estimates.

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

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

-- Configure everything in one shot
local ok, err = core.starforce.start({
    slot         = -11,        -- weapon
    target       = 17,
    safeguard    = true,
    mvp_tier     = "gold",
    sunny_sunday = false,
})
if not ok then core.log_error(err) end

core.starforce.stop() -> boolean

Available on GMS

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


core.starforce.is_running() -> boolean

Available on GMS

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


core.starforce.get_status() -> table

Available on GMS

Returns a snapshot of the current run.

FieldTypeDescription
runningbooleanWhether the Auto SF toggle is on.
statestringRun phase: "idle", "quoting" (waiting for the server's price and odds), "waiting_result" (attempt sent), or "paused".
slotnumberSlot the run is targeting.
current_starsnumberLast-observed star count of the target item.
target_starsnumberConfigured target.
attemptsnumberAttempts that produced a result in this run.
spentnumberTotal mesos charged in this run.
resulttableLive status object — see fields below.

result fields (status, stars, attempts and spent are always present; the others depend on the status):

FieldTypeDescription
statusstringCurrent status — see the result.status table below.
starsnumberStar count last observed for the target item.
attemptsnumberAttempts that produced a result in this run.
spentnumberMesos charged in this run (the price of every attempt that produced a result).
reasonstring?Only on "paused": "native_ui_open" or "busy".
lastCostnumber?Only on "enhancing": price of the attempt just sent.
costSourcestring?With lastCost / nextCost: "server" (price quoted by the server) or "estimate" (local estimate, used for the rest of the run once the server didn't answer the price check).
quotetable?The server's terms for the attempt — see the result.quote table below. Present on "enhancing" and on stops that follow a price check; absent while the run uses estimated prices.
nextCostnumber?Only on "insufficient_meso": price of the next attempt.
currentMesonumber?Only on "insufficient_meso": mesos the character holds.
coinsNeedednumber?Only on "insufficient_coins": Shadowknight Coins the attempt costs.
coinsHeldnumber?Only on "insufficient_coins": Shadowknight Coins the character holds.
requestedModenumber?Only on "mode_rejected": enhancement mode (0-3) that was requested.
ackedModenumber?Only on "mode_rejected": enhancement mode the server answered with.
response_typenumber?Only on "server_rejected" / "invalid_response": type of the server's reply, useful in bug reports.
codenumber?Only on "server_aborted": the reply's code, or -1 if it carried none.
chargeUnverifiedboolean?May be present on "timeout" (an attempt was sent and no result arrived) and on "server_rejected" when the server interrupted an attempt already sent: the attempt may or may not have been charged, and it isn't counted in spent.

result.status values:

StatusRunDescription
"idle"—Nothing running; stars, attempts and spent are 0.
"quoting"continuesWaiting for the server's price and odds for the next attempt.
"enhancing"continuesThe attempt was sent; waiting for its result.
"paused"continuesWaiting to continue. reason = "native_ui_open": close the in-game equipment enhancement window to continue. reason = "busy": the character can't act right now (dead, another request pending, throttled).
"done"stopsTarget reached, or the item is at its maximum stars.
"item_not_found"stopsNo item at the configured slot.
"not_enhanceable"stopsThere is an item, but Star Force can't be used on it.
"item_boomed"stopsThe item was destroyed.
"insufficient_meso"stopsThe character can't afford the next attempt.
"insufficient_coins"stopsThe item also costs Shadowknight Coins and there aren't enough.
"equip_tab_full"stopsThe item is equipped, the attempt can destroy it, and the Equip inventory has no free slot.
"mode_rejected"stopsThe server wouldn't accept the selected enhancement mode.
"feature_disabled"stopsStar Force is disabled on this server or channel.
"timeout"stopsNo reply from the server in time.
"server_rejected"stopsThe server refused or interrupted the request.
"server_aborted"stopsThe server cancelled the request.
"invalid_response"stopsA reply couldn't be read.

"stops" means the Auto SF toggle is turned off.

result.quote fields:

FieldTypeDescription
costnumberMesos the server charges for this attempt, with discounts and safeguard already applied.
successPctnumberChance of gaining a star, in percent (one decimal).
destroyPctnumberChance the item is destroyed on this attempt, in percent (two decimals). 0 when safeguarded or when the attempt can't destroy the item.
canDropbooleanA failure can lower the star count.
chanceTimebooleanThe attempt is guaranteed to succeed (chance time).
coinCostnumber?Shadowknight Coins the attempt also costs (only for items that need them).
nextStarnumberStar count after a success.
lua
local s = core.starforce.get_status()
core.log(string.format("[%s] %d★ → %d★  (%d attempts, %d mesos)",
    s.state, s.current_stars, s.target_stars or 0, s.attempts, s.spent))

local r = s.result
if r and r.quote then
    core.log(string.format("Next: %d mesos, %.1f%% success, %.2f%% destroy",
        r.quote.cost, r.quote.successPct, r.quote.destroyPct))
end

if r and r.status == "item_boomed" then
    core.log_error("Item went boom!")
end

core.starforce.estimate_cost(item_level: number, current_star: number [, opts: table]) -> number

Available on GMS

Returns the estimated meso cost of one attempt at current_star stars on an item of the given required level. Uses the GMS formula with discounts, safeguard surcharge and enhancement mode applied; the base price is rounded to the nearest 100 mesos before they are applied. The server's price can differ; a run uses the server's price unless the server didn't answer its first price check.

If opts is omitted, the live settings (safeguard, sunny_sunday, mvp_tier, enhancement mode) are used — handy for asking "what would the next click cost right now?".

opts fields:

FieldTypeDescription
safeguardbooleanOverride safeguard.
sunny_sundaybooleanOverride Sunny Sunday.
mvp_tierstring | numberOverride MVP tier (same encoding as start()).
enhance_modenumberOverride enhancement mode (0-3, same index as the Enhancement Mode setting). A level the star count doesn't allow is lowered the same way a run lowers it.
lua
-- Cost of going 16 → 17 on a level-150 weapon with safeguard + Gold MVP
local cost = core.starforce.estimate_cost(150, 16, {
    safeguard = true,
    mvp_tier  = "gold",
})
core.log("Next attempt: " .. tostring(cost) .. " mesos")

-- Cost of going 18 → 19 at Level 4
local lv4 = core.starforce.estimate_cost(200, 18, { enhance_mode = 3 })

Example: log progress and report why a run stopped

lua
plugin = {
    name        = "SF Watchdog",
    version     = "1.0.0",
    author      = "you",
    description = "Logs SF progress and reports why a run stopped",
    load        = true,
}

local last_attempts = 0
local was_running = false

function on_tick()
    local s = core.starforce.get_status()

    if s.running and s.attempts ~= last_attempts then
        last_attempts = s.attempts
        core.log(string.format("Attempt %d  ★%d  spent=%d",
            s.attempts, s.current_stars, s.spent))
    end

    -- Stopping statuses turn the toggle off, so look for the on -> off edge
    if was_running and not s.running then
        local r = s.result or {}
        if r.status == "insufficient_meso" then
            core.log_error(string.format("SF stopped: next attempt costs %d, you have %d",
                r.nextCost or 0, r.currentMeso or 0))
        elseif r.status == "item_boomed" then
            core.log_error("SF stopped: the item was destroyed")
        else
            core.log("SF stopped: " .. tostring(r.status))
        end
        last_attempts = 0
    end
    was_running = s.running
end