Events and Shared State
Category: Development
description: Learn about PowBot Desktop event system architecture and shared state for cross-engine communication. Understand how to use events and shared state in your scripts.
Events and Shared State Guide
This guide explains the event system architecture and how to use shared state for cross-engine communication in your scripts.
Architecture Overview
The scripting engine uses a dual Lua engine architecture:
- Main Lua Engine: Runs your script's main logic (
on_start,poll,on_stop) - Event Lua Engine: Dedicated to event handlers, runs on the event thread
This architecture enables immediate event dispatch with near-zero latency. When a game event occurs, it dispatches directly to the Event Lua Engine without waiting for the Main Engine.
The Shared State API
Since event handlers run in a separate Lua engine, they cannot access local variables from your main script. The shared API provides a Rust-backed store for cross-engine state synchronization using atomic operations.
Creating Shared Values
-- Create typed shared values
local counter = shared:int("counter") -- Integer value
local ratio = shared:float("ratio") -- Float value
local status = shared:string("status") -- String value
local enabled = shared:bool("enabled") -- Boolean value
local tbl = shared:table("my_table") -- Table value (key-value store)
Integer Operations
local count = shared:int("ore_count")
count:set(0) -- Set value
count:get() -- Get current value (returns 0)
count:increment() -- Add 1, returns new value
count:decrement() -- Subtract 1, returns new value
count:add(5) -- Add 5, returns new value
count:subtract(3) -- Subtract 3, returns new value
String Operations
local status = shared:string("status")
status:set("mining") -- Set value
status:get() -- Get current value
status:append("_done") -- Append to value
Boolean Operations
local enabled = shared:bool("enabled")
enabled:set(true) -- Set value
enabled:get() -- Get current value
enabled:toggle() -- Toggle value
Table Operations
local data = shared:table("player_data")
data:set("name", "Player123") -- Set key-value
data:get("name") -- Get value by key
data:remove("name") -- Remove key
data:clear() -- Clear all keys
Event System
Events allow your script to react to game state changes immediately.
Registering Event Handlers
-- Register handler for inventory change event
events:on("inventory_changed", function(event)
local item = event.item
local count = shared:int("item_count")
count:increment()
logger:info("Item added: " .. item:name())
end)
Available Events
Common events include:
inventory_changed- Inventory item added/removedlevel_up- Skill level increasedcombat_started- Combat initiatedcombat_ended- Combat finishedbank_opened- Bank interface openedbank_closed- Bank interface closed
Example: Event-Driven Script
local script = {
name = "EventExample",
version = "1.0.0"
}
function script:on_start()
-- Create shared counters
self.ores_mined = shared:int("ores_mined")
self.ores_mined:set(0)
-- Register event handler
events:on("inventory_changed", function(event)
if event.item:name():contains("ore") then
self.ores_mined:increment()
logger:info("Ore mined! Total: " .. self.ores_mined:get())
end
end)
return true
end
function script:poll()
-- Main loop can read shared state
local count = self.ores_mined:get()
stats:set("Ores mined", tostring(count))
sleep(50)
end
return script
Best Practices
- Use Shared State for Cross-Engine Communication: Always use shared state when event handlers need to communicate with main script
- Atomic Operations: Shared state operations are atomic and thread-safe
- Initialize in on_start: Create shared values in
on_start()for consistency - Clean Up Events: Unregister event handlers in
on_stop()if needed
For complete event documentation, see the Events API Reference.