Skip to content

sdk.localplayer ​

Local character: Player reads plus talk / walk / use / attack. Actions return ok, err.

lua
local M = require("sdk.localplayer")

Constants ​

Lua 5.4 has no enums — these are integer (or string) fields on the module.

NameValueSummary
FIGHT_OFFENSIVE1—
FIGHT_BALANCED2—
FIGHT_DEFENSIVE3—
CHASE_STAND0—
CHASE_FOLLOW1—
PVP_DOVE0—
PVP_WHITE1—
PVP_YELLOW2—
PVP_RED3—
QUICK_LOOT_SINGLE0—
QUICK_LOOT_AREA_CORPSE1—
QUICK_LOOT_AREA_PLAYER2—
attackdo_attackLocal player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
stopAttackdo_stop_attackLocal player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
followdo_followLocal player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
stopFollowdo_stop_followLocal player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
shareExperiencedo_share_experienceLocal player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
quickLootdo_quick_loot—
setTacticsdo_set_tacticsLocal player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
attackas_module(do_attack)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
stopAttackas_module(do_stop_attack)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
followas_module(do_follow)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
stopFollowas_module(do_stop_follow)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
inviteToPartyas_module(LocalPlayer.inviteToParty)—
joinPartyas_module(LocalPlayer.joinParty)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
passLeadershipas_module(LocalPlayer.passLeadership)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
leavePartyas_module(LocalPlayer.leaveParty)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
shareExperienceas_module(do_share_experience)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
quickLootas_module(do_quick_loot)—
setTacticsas_module(do_set_tactics)Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement.
cancelas_module(LocalPlayer.cancel)—
quitGameas_module(LocalPlayer.quitGame)—

useOnCreature ​

function · useOnCreature(item_id, loc, creature)

Use an item on a creature (potion, rune, food-on-self). Equipped = ObjectPosition case 2; backpack = case 3. Case 1 is worldmap and will crash if mis-tagged. Self-use potions go through :useItem / :useItemAt, which call this.

inviteToParty ​

function · inviteToParty()

Invite target to the local character's party. One-id InviteToParty packet; target must be a player on screen. Rewrapped by as_module so both LocalPlayer.inviteToParty(id) and :inviteToParty work.

joinParty ​

function · joinParty(self: LocalPlayer, target: Player|integer): Result?, ErrorMessage?

Accept a party invite from target. Same one-id layout as invite; id 0 is not a cancel here. Call after seeing the invite shield, not on an arbitrary player.

Parameters

NameTypeSummary
targetPlayer|integer—

Returns

TypeSummary
Result?, ErrorMessage?—

passLeadership ​

function · passLeadership(self: LocalPlayer, target: Player|integer): Result?, ErrorMessage?

Pass party leadership to target. Only the current leader's client should send this. UI usually gates on player:isPartyLeader() plus isSelf.

Parameters

NameTypeSummary
targetPlayer|integer—

Returns

TypeSummary
Result?, ErrorMessage?—

leaveParty ​

function · leaveParty(self: LocalPlayer): Result?, ErrorMessage?

Leave the current party (no creature id). Empty LeaveParty body; not the same as passing leadership. Safe to call when already unpartied — server ignores it.

Returns

TypeSummary
Result?, ErrorMessage?—

cancel ​

function · cancel()

Cancel the current action (official Cancel packet, empty body). Does not clear attack/follow by itself; those have dedicated stops. Use when a modal use/aim should be dropped.

quitGame ​

function · quitGame()

Request logout / close the game session. Native QuitGame first; empty packet fallback. :logout is the familiar alias; still blocked in-fight / PZ-lock by the server.

new ​

function · new(data: table): LocalPlayer

LocalPlayer wrapper. Copies id onto local_id when the caller omitted it. Metatable chains to Player for reads; actions stay on this table. Engine.GetLocalPlayer / status.enrich typically construct this.

Parameters

NameTypeSummary
datatable—

Returns

TypeSummary
LocalPlayer—

inventory ​

method · inventory(self: LocalPlayer): Inventory

Open the live Inventory singleton for this character. Not a snapshot; container windows can change under the caller. Equip/stow/gold all go through this, not a second container scan.

Returns

TypeSummary
Inventory—

talk ​

function · talk(text, opts)

Say text via Talk. opts.mode selects say/whisper/yell/channel. Npc.greet already says hi — jobs should not send "hi" again through this. Default talk mode is say unless opts overrides it.

privateMessage ​

function · privateMessage(receiver, text)

Send a private message to receiver. Talk module owns the packet; this is the LocalPlayer entry point. Receiver is a name string, not a creature id.

say ​

method · say(self: LocalPlayer, text: string): Result?, ErrorMessage?

Speak in say mode (Talk mode 1). Default public speech; NPCs hear this within talk range 3. Prefer Npc helpers for greet/trade instead of raw say.

Parameters

NameTypeSummary
textstring—

Returns

TypeSummary
Result?, ErrorMessage?—

whisper ​

method · whisper(self: LocalPlayer, text: string): Result?, ErrorMessage?

Whisper (Talk mode 2). Range is shorter than say. Same Talk path as :say; only the mode byte changes. Use for party-adjacent chat, not NPC words.

Parameters

NameTypeSummary
textstring—

Returns

TypeSummary
Result?, ErrorMessage?—

walk ​

method · walk(self: LocalPlayer, direction: Direction): Result?, ErrorMessage?

One-tile step in dir (0-3 or name). Movement owns the packet. Does not pathfind; :moveTo is the automap walk. Rooted / paralyze will fail server-side — check those bits first.

Parameters

NameTypeSummary
directionDirection—

Returns

TypeSummary
Result?, ErrorMessage?—

moveTo ​

method · moveTo(self: LocalPlayer, x: integer, y: integer, z: integer): Result?, ErrorMessage?

Path / automap walk toward {x,y,z}. Movement module owns the map query; this is the LocalPlayer facade. NPC counters often need a Chebyshev-1..3 stand tile, not the NPC tile itself.

Parameters

NameTypeSummary
xinteger—
yinteger—
zinteger—

Returns

TypeSummary
Result?, ErrorMessage?—

stopWalk ​

method · stopWalk(self: LocalPlayer): Result?, ErrorMessage?

Stop the current walk (Movement.stop). Attack/Follow may also cancel walk when retargeting (see should_cancel_target_movement). Call before a precise tile step if an automap walk is still queued.

Returns

TypeSummary
Result?, ErrorMessage?—

useItem ​

method · useItem(self: LocalPlayer, item_id: ItemId): Result?, ErrorMessage?

Use the first matching backpack/equipped stack of item_id on self. Looks up a location, then useItemAt; missing item is an error. Potions/food go here; ground use is Tiles, not this.

Parameters

NameTypeSummary
item_idItemId—

Returns

TypeSummary
Result?, ErrorMessage?—

useItemAt ​

method · useItemAt(self: LocalPlayer, item_id: ItemId, location: ItemLocation): Result?, ErrorMessage?

Use item_id at loc on the local creature id. Equipped vs container tagging is handled in useOnCreature (cases 2/3). Pass the location inventory:find returned; do not invent slot numbers.

Parameters

NameTypeSummary
item_idItemId—
locationItemLocation—

Returns

TypeSummary
Result?, ErrorMessage?—

useSkill ​

method · useSkill(self: LocalPlayer, words: string): Result?, ErrorMessage?

Cast by spell words (exura, utevo gran lux, ...). Skills.use owns cooldown / packet; this is the LocalPlayer facade. Prefer :canCast first so mana/level misses do not spam the server.

Parameters

NameTypeSummary
wordsstring—

Returns

TypeSummary
Result?, ErrorMessage?—

skill ​

method · skill(self: LocalPlayer, name: string): SkillSnapshot?, ErrorMessage?

One skill row (level / percent / tries) by name. Reads the Skills cache, not TCreature. Training jobs key off this plus :skills() for the full set.

Parameters

NameTypeSummary
namestring—

Returns

TypeSummary
SkillSnapshot?, ErrorMessage?—

skills ​

method · skills(self: LocalPlayer): table?, ErrorMessage?

All skill rows from the Skills cache. Empty/nil until PlayerSkills has been seen this session. HUD and trainers iterate this instead of hardcoding skill names.

Returns

TypeSummary
table?, ErrorMessage?—

gold ​

method · gold(self: LocalPlayer): integer?, ErrorMessage?

Inventory gold (coins + crystal, not bank). Delegates to Inventory:gold(); bank is :bankGold. Shop jobs snapshot this before walking; do not assume the banker has coins.

Returns

TypeSummary
integer?, ErrorMessage?—

hasReceivedBasicData ​

method · hasReceivedBasicData(self: LocalPlayer): boolean

True once PlayerDataBasic has been seen this session. Premium/blessings survive WorldEntered; this flag is how scripts know they exist. Gate account UI on this so a mid-login inject does not show "free".

Returns

TypeSummary
boolean—

isPremium ​

method · isPremium(self: LocalPlayer): boolean|nil

Premium flag from the account cache (survives WorldEntered). Nil if Basic never carried it — not the same as false. Premium-only spells/depot should wait on nil.

Returns

TypeSummary
boolean|nil—

premiumUntil ​

method · premiumUntil(self: LocalPlayer): integer?

Premium expiry timestamp, or nil if unknown / free account. Comes from PlayerDataBasic; WorldEntered does not wipe it. Display as a date; do not treat 0 as "expired" without has_basic.

Returns

TypeSummary
integer?—

blessings ​

method · blessings(self: LocalPlayer): BlessingsSnapshot?

Blessings bits + premium-blessing flag from the last Blessings packet. Account cache; not reset on world enter. Death-cost / hunt-start checks read this table, not a chat line.

Returns

TypeSummary
BlessingsSnapshot?—

bankGold ​

method · bankGold(self: LocalPlayer): integer?

Banked gold from Resources (PlayerInventory / resource query). May be stale until :requestResource lands. Withdraw the shortfall, not a round 200, when shopping.

Returns

TypeSummary
integer?—

goldBalance ​

method · goldBalance(self: LocalPlayer): integer?

Combined carried + bank gold. Resources module owns the sum; inventory-only gold is :gold. Wealth HUD uses this; shop affordance should still snapshot backpack coins.

Returns

TypeSummary
integer?—

dusts ​

method · dusts(self: LocalPlayer): integer?

Exalted-dust count from the resource cache. Nil until the dust resource packet; request it if missing. Forge UI should not treat nil as 0.

Returns

TypeSummary
integer?—

dustsMaximum ​

method · dustsMaximum(self: LocalPlayer): integer?

Exalted-dust cap. Pair with :dusts for "can I extract more". Cap changes with loyalty / store; do not hardcode 225.

Returns

TypeSummary
integer?—

huntingPoints ​

method · huntingPoints(self: LocalPlayer): integer?

Hunting-task points from the resource cache. Nil until requested / last packet. Task-board jobs should request before comparing a threshold.

Returns

TypeSummary
integer?—

preyWildcards ​

method · preyWildcards(self: LocalPlayer): integer?

Prey wildcard count from the resource cache. Nil until the prey resource packet. Reroll jobs check this before sending the prey action.

Returns

TypeSummary
integer?—

requestResource ​

method · requestResource(self: LocalPlayer, type: integer): Result?, ErrorMessage?

Ask the server for one resource type (bank, dust, prey, ...). Async: the getters above update when the reply is decoded. Call once, then wait on the cache — do not request every tick.

Parameters

NameTypeSummary
typeinteger—

Returns

TypeSummary
Result?, ErrorMessage?—

inviteParty ​

alias · inviteParty(self: LocalPlayer, target: Player|integer): Result?, ErrorMessage?

Same as inviteToParty.

Alias

Same as inviteToParty.

Parameters

NameTypeSummary
targetPlayer|integer—

Returns

TypeSummary
Result?, ErrorMessage?—

setTarget ​

method · setTarget(self: LocalPlayer, target: Player|integer, options?: TargetActionOptions): Result?, ErrorMessage?

Attack alias (setTarget naming used by older bot APIs). Same lock / toggle rules as do_attack; does not refresh an existing red box. Prefer this name only when porting scripts that already say setTarget.

Parameters

NameTypeSummary
targetPlayer|integer—
optionsTargetActionOptions—

Returns

TypeSummary
Result?, ErrorMessage?—

changeTarget ​

method · changeTarget(self: LocalPlayer, target: Player|integer, options?: TargetActionOptions): Result?, ErrorMessage?

Attack alias. Same body as setTarget; does not stop the previous lock first. A different id is a new Attack; the same id is a no-op (official toggle). Kiting retargets should pass {kiting=true} so walk is kept.

Parameters

NameTypeSummary
targetPlayer|integer—
optionsTargetActionOptions—

Returns

TypeSummary
Result?, ErrorMessage?—

unjustified ​

method · unjustified(self: LocalPlayer): table?

Last UnjustifiedPoints event payload (kills / protection time), or nil. Read from Engine event state; not a TCreature field. PvP HUD shows this; it is not updated by PlayerState.

Returns

TypeSummary
table?—

loot ​

method · loot(self: LocalPlayer, opts?: table): Result?, ErrorMessage?

Quick-loot alias (loot naming used by older bot APIs). Same native-then-packet path as do_quick_loot. CaveBot corpse ticks should call this once per corpse, not drag items.

Parameters

NameTypeSummary
optstable—

Returns

TypeSummary
Result?, ErrorMessage?—

turn ​

method · turn(self: LocalPlayer, direction: Direction): Result?, ErrorMessage?

Face dir without stepping (Movement.rotate). Use when already on the tile and only the facing byte matters (rope, use). Rooted characters can still turn.

Parameters

NameTypeSummary
directionDirection—

Returns

TypeSummary
Result?, ErrorMessage?—

logout ​

method · logout(self: LocalPlayer): Result?, ErrorMessage?

Logout alias for quitGame. Server still blocks in-fight and PZ-lock; check those bits first. Offline-training scripts call this after :offlineTraining is > 0.

Returns

TypeSummary
Result?, ErrorMessage?—

pickup ​

method · pickup(self: LocalPlayer, item: ItemStack|ItemId, count?: integer): Result?, ErrorMessage?

Pick up a ground item into the open backpack (Tiles.pickup). Not quick-loot; this is a MoveObject from world to container. Capacity checks belong in the caller; this just sends the move.

Parameters

NameTypeSummary
itemItemStack|ItemId—
countinteger—

Returns

TypeSummary
Result?, ErrorMessage?—

equip ​

method · equip(self: LocalPlayer, item: ItemStack|ItemId): Result?, ErrorMessage?

Equip a location, or find item by id then equip. A number means "search inventory"; a location table is used as-is. Quiver/ammo should use Inventory:stowAmmo / EquipObject, not a drag.

Parameters

NameTypeSummary
itemItemStack|ItemId—

Returns

TypeSummary
Result?, ErrorMessage?—

dequip ​

method · dequip(self: LocalPlayer, slot: integer): Result?, ErrorMessage?

Unequip one inventory slot into the open backpack. Slot is the official inventory index (1-10), not a container slot. Fails if no backpack is open — open one first.

Parameters

NameTypeSummary
slotinteger—

Returns

TypeSummary
Result?, ErrorMessage?—

closeContainer ​

method · closeContainer(self: LocalPlayer, container: ContainerId): Result?, ErrorMessage?

Close a container window by index / handle. Delegates to Inventory:close; does not move items. Depot jobs close extras so the next open is the intended box.

Parameters

NameTypeSummary
containerContainerId—

Returns

TypeSummary
Result?, ErrorMessage?—

useWith ​

method · useWith(self: LocalPlayer, from: any, to: any): Result?, ErrorMessage?

Use item from on item to (Inventory.useWith). Both ends are locations (world / inventory / container), not raw ids. Rope/shovel/machete tools go through this, not :useItem.

Parameters

NameTypeSummary
fromany—
toany—

Returns

TypeSummary
Result?, ErrorMessage?—

canCast ​

method · canCast(self: LocalPlayer, words: string): boolean|nil, ErrorMessage?

Whether the local character can currently cast words (level, mana, voc). Skills.canCast owns the tables; this passes self for vitals. Always check before :useSkill in a tick loop.

Parameters

NameTypeSummary
wordsstring—

Returns

TypeSummary
boolean|nil, ErrorMessage?—

Arcane SDK catalog generated from scripts/sdk