Login
Use core.login from on_tick(stage) while stage == core.stage.LOGIN to inspect the login flow and manage characters from the character-selection screen.
Reordering, deletion, and restoration affect the account's character list. A true result means the action was submitted, not that it has completed. Re-read the character list before sending another action.
Login Steps
| Step | Meaning |
|---|---|
1 | World and channel selection |
2 | Character selection |
3 | New-character setup |
4 | New-character name entry |
Other values may appear during transitions.
Character Structure
get_characters() returns one record per created character:
| Property | Type | Description |
|---|---|---|
id | number | Stable character ID |
index | number | Zero-based display position |
name | string | Character name |
level | number | Character level |
job | number | Job ID |
ghost | boolean | Whether deletion is pending |
delete_deadline | number | Deletion eligibility time as a Unix timestamp, or 0 |
deletion_ready | boolean | Whether permanent deletion is currently eligible |
Character actions accept a returned character record, a character ID, or a zero-based display index. Prefer passing the complete record; numeric values are resolved as IDs first and then as indices.
Functions
core.login.get_step() -> number | nil
Available on GMS and CW
Returns the current login step, or nil when the login interface is unavailable.
core.login.get_char_count() -> number | nil
Available on GMS and CW
Returns the number of created characters during character selection.
core.login.get_total_slot_count() -> number | nil
Available on GMS and CW
Returns the account's total available character slots during character selection.
core.login.get_empty_slot_count() -> number | nil
Available on GMS and CW
Returns the number of unoccupied character slots during character selection.
core.login.get_characters() -> table<login_character> | nil
Available on GMS and CW
Returns the current character list during character selection.
core.login.move_character_to_front(character: login_character | number) -> boolean
Available on GMS and CW
Moves the selected character to the front of the displayed character order.
core.login.soft_delete_character(character: login_character | number) -> boolean
Available on GMS
Starts the deletion waiting period for an active character that is not already pending deletion.
core.login.hard_delete_character(character: login_character | number) -> boolean
Available on GMS and CW
Permanently deletes a character whose deletion waiting period has completed.
core.login.restore_character(character: login_character | number) -> boolean
Available on GMS and CW
Restores a character that is pending deletion.
function on_tick(stage)
if stage ~= core.stage.LOGIN then return end
if core.login.get_step() ~= 2 then
return
end
for _, character in ipairs(core.login.get_characters() or {}) do
if character.ghost and not character.deletion_ready then
core.login.restore_character(character)
break
end
end
endcore.login.get_hold() -> table | nil
Available on GMS and CW
Returns why Auto Login is currently parked, or nil when nothing is holding it back. Usable from any stage — a hold armed in the field is visible before the logout lands.
| Property | Type | Description |
|---|---|---|
reason | string | "gm_evade" after Evade Potential GM fires, or "stay_logged_out" during the Stay Logged Out wait |
remaining_sec | number | Seconds until the hold expires on its own |
core.login.clear_hold() -> boolean
Available on GMS and CW
Releases every Auto Login hold so the next login tick logs back in — the same effect as re-ticking Auto Login in the menu. Returns false only when the autos module is unavailable.
Evade Potential GM is per character, not per account: the 6-hour hold keeps the character that triggered it offline. Logging into a different character is fine — switch profile first, then release the hold, as in the example below. Releasing it without switching logs the same character straight back in.
Example: rotate characters after a GM evade
Each saved profile points Auto Login at a different character slot. When Evade Potential GM fires, switch to the next profile, wait for it to become active, then release the hold so Auto Login logs into that profile's character instead of waiting six hours.
plugin = {
name = "GM Rotate",
version = "1.0.0",
author = "you",
description = "Switch profile and log into the next character after a GM evade",
load = true,
}
-- Profiles that differ only in autos.auto_login.char_index
local ROTATION = { "Farm A", "Farm B", "Farm C" }
local pending -- profile we are waiting on before releasing the hold
local function next_profile()
local active = core.profiles.get_active()
for i, name in ipairs(ROTATION) do
if active and active.name == name then
return ROTATION[i % #ROTATION + 1]
end
end
return ROTATION[1]
end
function on_gm_evasion()
pending = next_profile()
if core.profiles.switch(pending) then
core.log_warning("GM evade: switching to " .. pending)
else
core.log_error("GM evade: could not switch to " .. pending .. ", staying logged out")
pending = nil
end
end
function on_tick(stage)
if not pending then return end
-- Profile switches apply asynchronously; release the hold only once the
-- new profile (and its Auto Login slot) is actually live.
local active = core.profiles.get_active()
if active and active.name == pending then
core.login.clear_hold()
core.log_warning("GM evade: " .. pending .. " is active, Auto Login released")
pending = nil
end
end