Appearance
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.
| Name | Value | Summary |
|---|---|---|
FIGHT_OFFENSIVE | 1 | — |
FIGHT_BALANCED | 2 | — |
FIGHT_DEFENSIVE | 3 | — |
CHASE_STAND | 0 | — |
CHASE_FOLLOW | 1 | — |
PVP_DOVE | 0 | — |
PVP_WHITE | 1 | — |
PVP_YELLOW | 2 | — |
PVP_RED | 3 | — |
QUICK_LOOT_SINGLE | 0 | — |
QUICK_LOOT_AREA_CORPSE | 1 | — |
QUICK_LOOT_AREA_PLAYER | 2 | — |
attack | do_attack | Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement. |
stopAttack | 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. |
follow | do_follow | Local player actions return true when accepted by the local client, or nil, error before/while sending. Acceptance is not server acknowledgement. |
stopFollow | 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. |
shareExperience | 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. |
quickLoot | do_quick_loot | — |
setTactics | 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. |
attack | as_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. |
stopAttack | as_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. |
follow | as_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. |
stopFollow | as_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. |
inviteToParty | as_module(LocalPlayer.inviteToParty) | — |
joinParty | as_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. |
passLeadership | as_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. |
leaveParty | as_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. |
shareExperience | as_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. |
quickLoot | as_module(do_quick_loot) | — |
setTactics | as_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. |
cancel | as_module(LocalPlayer.cancel) | — |
quitGame | as_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
| Name | Type | Summary |
|---|---|---|
target | Player|integer | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
target | Player|integer | — |
Returns
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
data | table | — |
Returns
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
text | string | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
text | string | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
direction | Direction | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
x | integer | — |
y | integer | — |
z | integer | — |
Returns
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
item_id | ItemId | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
item_id | ItemId | — |
location | ItemLocation | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
words | string | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
name | string | — |
Returns
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
type | integer | — |
Returns
| Type | Summary |
|---|---|
Result?, ErrorMessage? | — |
inviteParty
alias · inviteParty(self: LocalPlayer, target: Player|integer): Result?, ErrorMessage?
Same as inviteToParty.
Alias
Same as inviteToParty.
Parameters
| Name | Type | Summary |
|---|---|---|
target | Player|integer | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
target | Player|integer | — |
options | TargetActionOptions | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
target | Player|integer | — |
options | TargetActionOptions | — |
Returns
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
opts | table | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
direction | Direction | — |
Returns
| Type | Summary |
|---|---|
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
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
item | ItemStack|ItemId | — |
count | integer | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
item | ItemStack|ItemId | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
slot | integer | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
container | ContainerId | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
from | any | — |
to | any | — |
Returns
| Type | Summary |
|---|---|
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
| Name | Type | Summary |
|---|---|---|
words | string | — |
Returns
| Type | Summary |
|---|---|
boolean|nil, ErrorMessage? | — |