Game functions
The Host exposes named game functions. A plugin lists what exists and calls it with typed arguments. No addresses, no offsets, no memory reads — the plugin composes features from the functions the Host provides and handles the results.
Methods
| Method | Permission | Result |
|---|---|---|
game.functions |
game.invoke |
{functions: [{name, args, returns, summary}]} |
game.invoke |
game.invoke |
{name, result} |
{"jsonrpc":"2.0","id":4,"method":"game.invoke",
"params":{"name":"player.teleport","args":{"x":123.5,"y":200,"z":-45,"method":0}}}
{"jsonrpc":"2.0","id":4,"result":{"name":"player.teleport","result":true}}
Current registry (API 1.0)
| Name | Args | Returns |
|---|---|---|
player.position |
- | {x, y, z, scene} |
player.teleport |
x, y, z, method? |
bool |
player.avatar_id |
- | int |
player.forward |
- | {x, y, z} |
world.scene |
- | int |
world.ground_height |
x, z |
float |
world.teleport_xz |
x, z |
bool |
entities.list |
limit? |
[{id, config, type, x, y, z, distance}] |
markers.list |
limit? |
[{name, category, x, y, z, distance}] |
markers.nearest |
- | {name, category, x, y, z, distance} |
waypoints.list |
limit? |
[{index, id, name, x, y, z, distance}] |
waypoints.nearest |
- | {index, id, name, x, y, z, distance} |
waypoints.teleport |
index |
bool |
map.list |
- | [{index, name, done, total}] |
map.items |
map, search?, limit? |
[{index, name, total, done}] |
map.complete |
index |
bool |
map.teleport |
index |
bool |
collect.start |
- | bool |
collect.cancel |
- | bool |
chests.start |
- | bool |
chests.cancel |
- | bool |
chests.status |
- | {running, current, total, found, confirmed} |
unlock.waypoints |
- | bool |
unlock.status |
- | {running, done, ran, sent, total, skipped, status} |
unlock.cancel |
- | bool |
achievements.claim_all |
- | int |
The registry is the extension point. A function that does not exist here needs a native adapter in the Host: the adapter owns the game call, validates the arguments and returns public data. Plugins never receive the address behind it.
Why not arbitrary offsets
Handing out the module base, raw memory access or a pattern scanner turns the SDK into a cheat-building kit and moves every crash and every patch-day break to the plugin process. The function registry keeps the reach (any feature the Host adapts) while keeping the ABI, the calling thread and the validation in one place.
If a plugin needs an operation that is not listed, it reports the operation and the Host grows one adapter. Additive functions are a minor API version; existing plugins keep working.
Python
for entry in plugin.functions():
print(entry["name"], entry["args"], "->", entry["returns"])
position = plugin.invoke("player.position")
plugin.invoke("player.teleport",
x=position["x"], y=position["y"], z=position["z"], method=0)
invoke raises ShireError with -32602 for an unknown name or bad argument
type, and -32000 when game.invoke was not approved.