Getting information about the game world
In UtilityBelt, all scripts have access to a global variable called game
. This variable serves as the primary entry point for acquiring information about and interacting with the game world. You can utilize it to retrieve the current state of the world, subscribe to events, and execute actions. For a more comprehensive understanding of available information for your script, check out the API documentation for the Game class.
Tip
Each running script is provided with a distinct instance of the Game class. This design ensures that shutdown or erroneous scripts are appropriately cleaned up during unloading. Furthermore, it maintains a sandboxed environment for each script, preventing interference between scripts. Certain elements, such as the Action Queue, are shared among scripts to facilitate simultaneous operation with minimal hassle.
Using the game global
Let's start by obtaining some basic information about your character. Upon logging into the game, enter the following command in the ingame chat window to retrieve your character's object ID:
/ub lexec return game.CharacterId
Tip
The /ub lexec <code>
command allows you to run Lua code snippets. This code runs in a special Global script context that automatically starts once the scripting engine initializes. It's an efficient way to test Lua code without creating a separate script. Note that you will either need to return or print a result to see its output.
You should observe output similar to the following in the chat window, albeit with your unique character ID:
[UB] Evaluating script (context `Global`): "return game.CharacterId"
[UB] Result: (Number) 1342204037 (0.036ms)
In our example above, we are getting the value stored in Game.CharacterId. game
is a global lua variable that is an instance of the Game object. Game.CharacterId is a property stored on the Game object. Properties store values (like strings, numbers, etc) that can be read by our scripts.
Lets try getting another property on the Game object. This time we'll get the name of the server we are currently connected to.
/ub lexec return game.ServerName
You should observe output similar to the following in the chat window, although your server name will likely differ:
[UB] Evaluating script (context `Global`): "return game.ServerName"
[UB] Result: (String) My Asherons Call Server (0.035ms)
Note that this time a string type was returned. By referring to the Lua API Documentation for Game.ServerName, you can ascertain the expected return type or property value type—in this instance, it's a string.
World Objects
In the realm of AC, any entity you can interact with is categorized as a World Object (sometimes referred to as Weenies). This encompasses a broad spectrum, including monsters, NPCs, spell projectiles, doors, inventory items, and even your character. If you're capable of selecting it, it's a world object. However, objects like trees are not part of this category. The World interface is your gateway to accessing these world objects. To interact with this interface, utilize the Game property of the global game
variable—namely, game.World
.
Finding world objects
Let's harness the power of the World interface to retrieve a list of landscape world objects around us. Landscape objects, such as monsters, portals, and more, are defined as lacking a parent or container object. Type the following into the ingame chatbox:
/ub lexec return game.World.GetLandscape()
You should observe output similar to the following in the chat window:
[UB] Evaluating script (context `Global`): "return game.World.GetLandscape()"
[UB] Result: (table) (0.084ms)
We invoked the World.GetLandscape() method, which retrieves a collection of all landscape WorldObjects. Take note of the return type—table
. In Lua, a table
is a fundamental data structure that holds a collection of elements. Currently, we're not performing any specific actions with the table. However, we can iterate through it and take actions on each element within.
From now on, the code examples get slightly longer. Instead of using the /ubs lexec
command we will by modifying our helloworld
script from the Creating your first script document.
Paste the following code into your helloworld
script and start it up.
for wobject in game.World.GetLandscape() do
print(wobject.Id, wobject.Name)
end
The above should print a new line in the chatbox for each landscape object it found, similar to the following:
[helloworld] 2154558015 Ixirs Staff of Eyes
[helloworld] 2153110655 Weeping Wand
[helloworld] 2161627415 Orb of the Bunny Booty
Tip
An important note regarding world objects: Each instance of a World Object has a unique ID, which can be accessed via the WorldObject.Id property. These IDs serve as references to specific world object instances. Across the API, any parameter that accepts a world object ID can also accept a WorldObject instance, and vice versa.
Explore the various Get*()
methods exposed by the World class. For instance, you can retrieve all world object instances of a particular ObjectType using the World.GetAll(type) method or obtain a world object instance with a specific ID using the World.Get(objectId) method. Furthermore, the world interface defines an indexer. As an alternative to game.World.Get(objectId)
for fetching a specific world object instance by ID, you can use game.World[objectId]
.
Advanced filtering
Let's delve into an advanced filtering scenario. Suppose you want to compile a list of nearby players within a 10-meter radius. One of the overloads of the World.GetLandscape(matchFunction) method accepts a function as its initial argument. This function is invoked for each object found by the Get query. If the function returns true
, the object is included in the resulting collection. The subsequent example demonstrates retrieving all landscape objects within a 10-meter radius and displaying their names and IDs in the chat window.
local nearby_objects = game.World.GetLandscape(function(check_wobj)
return game.Character.DistanceTo(check_wobj) <= 10
end)
for wobject in nearby_objects do
print(wobject.Id, wobject.Name)
end
Accessing world object properties
World objects have "properties" of different value types (not to be confused with class properties). These include IntId, Int64Id, FloatId, BoolId, StringId, DataId, and InstanceId. Most of the information about a world object is stored within these properties, although some data is exposed directly on the WorldObject interface. Use the /ub propertydump command with an object selected to view a dump of all of its available properties. These will vary depending on the object type, if you have appraised the object, and the state of the object. You can use the WorldObject.HasValue(key) methods to see if a property of the specified type exists on an object.
Tip
To get a full list of available properties on an object instance when using /ub propertydump, make sure to appraise the object first. You can do this by right clicking the object in game, or pragmatically by calling WorldObject.Appraise(options,callback) on a world object instance. Some properties are only available after having appraised an object.
As another example, Lets grab all player objects and print their name and level. We can filter all objects down to just ones that match ObjectClass.Player using the World.GetAll(objectClass) method. Try running the following:
for wobject in game.World.GetAll(ObjectClass.Player) do
print(wobject.Name, "is level", wobject.Value(IntId.Level))
end
You should see something similar to the following in your chat window:
[helloworld] Brycters Money Dump I is level 41
[helloworld] Sellin Eighths is level 190
[helloworld] Smart Saves is level 129
[helloworld] Lan is level 244
The WorldObject.Value(key,default) method returns the int value property specified by the passed IntId. In this case IntId.Level which contains the level of the creature if applicable.