asterobot:gamedata reads the texts and the data of the game version the bot uses: items, monsters, maps, spells and everything else Asterobot extracts from the game files. It only reads. Game data overview, Lookups and SQL show how to use it.
import { text, record, table, find, search, query } from "asterobot:gamedata";
These are the module's only exports. There's no gamedata object to import.
| Export | Returns | What it reads |
|---|---|---|
text() |
A string or undefined, right away |
One game text, by id or key |
record() |
An object or undefined, right away |
One row of a table, by id |
table() |
A promise of an array | The rows of a table, a page at a time |
find() |
A promise of an array | The rows whose columns equal given values |
search() |
A promise of an array | Records found by their name |
query() |
A promise of a result | The answer to a read-only SQL query |
What the data is
The data comes from the game version the bot is set to. text() and search() answer in the language the script was started with, session.language, which is fr for every start made from Asteroboard today.
Asterobot looks for the data when the script starts. When that game version has no extracted game data at that moment, record() returns undefined, and table(), find(), search() and query() resolve with undefined rather than an array, until the script starts again after the data is extracted. When Asterobot can't load the game's texts in that language, text() returns undefined for every key. Extract game data explains how to get the data.
Table and column names, such as monsters or name_id, are the ones of the extracted data, and they can change between game versions. Browse them on the Game page's game data (see Game data), and try queries in the SQL tab.
In the rows these functions return, numbers are regular JavaScript numbers, not BigInt. A packed column arrives as an array of objects, and a JSON column as the value it holds. record(), table() and find() leave empty columns out of their objects.
table(), find(), search() and query() share these rules:
- They reject after 30 seconds, and there's no option to change that.
- Each call counts as one of the 32 operations a script can have pending at once, along with
send()andrequest(). Past that, the promise rejects withbehavior resource limit exceeded: maximum pending operations reached. limitdefaults to 200 rows and can't go above 5000. Alimitoroffsetthat isn't a whole number greater than 0 is ignored.
text()
text(key) returns a string, or undefined.
| Parameter | Type | Description |
|---|---|---|
key |
number or string | A text id, as found in columns such as name_id, or a text key such as "ui.common.classic" |
It returns the text in the script's language, or undefined when no text has that id or key.
When the game's texts are loaded, text() throws a TypeError with gamedata.text key must be a string or integer for any other key: a fraction, a number outside the 32-bit range, a BigInt, undefined or an object. Check a value exists before passing it.
record()
record(table, id) returns an object, or undefined.
| Parameter | Type | Description |
|---|---|---|
table |
string | The table's name, such as "monsters" |
id |
number | The record's id: a whole number, not a BigInt |
It returns the row with that id, or undefined when there's none.
| Error | Type | Cause |
|---|---|---|
gamedata.record table must be a non-empty string |
TypeError |
table is missing, empty or not a string |
gamedata.record id must be an integer |
TypeError |
id isn't a whole number, is too big to be exact in JavaScript, or is a BigInt or a string |
datacenter: no such table: "<table>" |
Error | This game version has no table with that name. String(error) gives GoError: datacenter: no such table: "<table>". |
const monster = record("monsters", 31);
if (monster) botInfo("Monster 31 is", text(monster.name_id));
table()
table(name, options?) returns Promise<object[]>.
| Parameter | Type | Description |
|---|---|---|
name |
string | The table's name |
options.limit |
number | How many rows to return. Default 200, at most 5000. |
options.offset |
number | How many rows to skip first. Default 0. |
It resolves with the rows, in the order of their ids. A call without options returns the first 200 rows, not the whole table.
The promise rejects with gamedata.table name must be a non-empty string when name isn't a non-empty string, and with datacenter: no such table: "<name>" for a table this game version doesn't have.
const page = await table("items", { limit: 50, offset: 100 });
find()
find(name, filter, options?) returns Promise<object[]>.
| Parameter | Type | Description |
|---|---|---|
name |
string | The table's name |
filter |
object | Column names and the values they must equal. A row matches when every column equals its value. |
options.limit |
number | How many rows to return. Default 200, at most 5000. offset is ignored. |
| Error | Cause |
|---|---|
gamedata.find table must be a non-empty string |
name isn't a non-empty string |
gamedata.find filter must be a non-empty object |
filter is missing, empty, an array, or not an object |
datacenter: no such table: "<name>" |
This game version has no table with that name |
datacenter: no such column: table "<name>" has no column "<column>" |
A filter column doesn't exist in the table |
const spots = await find("maps__interactive_elements", { gfx_id: 1018 });
search()
search(query, options?) returns Promise<Match[]>.
| Parameter | Type | Description |
|---|---|---|
query |
string | The name, or part of it |
options.table |
string | Only search this table's records, such as "monsters". Without it, every named record is searched. |
options.limit |
number | How many matches to return. Default 200, at most 5000. |
Each word of query matches the beginning of a word, so a partial name works. Shorter names come first. Without options.table, the results take one match from each table in turn, so the first results show every kind of thing that has that name. A query made only of spaces resolves with an empty array.
| Error | Cause |
|---|---|
gamedata.search query must be a non-empty string |
query isn't a non-empty string |
gamedata.search options.table must be a string |
options.table is there but isn't a string |
datacenter: no such table: "<table>" |
This game version has no table with that name |
datacenter: no text for this language: "<language>" |
The extracted data has no names in the script's language |
const [hit] = await search("Bouftou Royal", { table: "monsters" });
if (hit) botInfo(hit.name, "is monster", hit.id);
query()
query(sql, params?, options?) returns Promise<QueryResult>.
| Parameter | Type | Description |
|---|---|---|
sql |
string | One or more SQL statements |
params |
array | Values for the ? placeholders, in order |
options.limit |
number | How many rows to return. Default 200, at most 5000. |
The game data is opened read-only, so any statement that writes fails, and attaching another database is refused. Every statement in sql runs, and the result is the last one's: "SELECT 1; SELECT 2" answers 2. A query runs for at most 10 seconds, and its text can't be longer than 65,536 bytes.
Pass values through params instead of writing them into the SQL: a number written into the text arrives as text, and doesn't equal the number stored in a column.
In rows, an empty value is null.
| Error | Cause |
|---|---|
gamedata.query sql must be a non-empty string |
sql isn't a non-empty string |
gamedata.query params must be an array |
params is there but isn't an array |
datacenter: empty query |
sql holds only spaces |
datacenter: query is <size> bytes, over the 65536 byte limit |
The SQL text is too long |
datacenter: followed by the database's message |
The SQL is wrong, names a table or column that doesn't exist, or tries to write, in which case the message mentions attempt to write a readonly database |
The promise also rejects when the query runs for more than 10 seconds.
const { columns, rows, truncated } = await query(
"SELECT _id, name_id FROM monsters WHERE _id = ?",
[31],
);
Types
| Type | Shape |
|---|---|
Row |
An object whose keys are the table's column names |
Window |
{ limit?: number, offset?: number }, the options of table() and find() |
SearchOptions |
{ table?: string, limit?: number } |
QueryOptions |
{ limit?: number } |
Match |
{ table: string, id: number, nameId: number, name: string }: the record's table and id, to pass to record(), the id of the text its name comes from, and the name in the script's language |
QueryResult |
{ columns: string[], rows: unknown[][], truncated: boolean }. columns lists the column names in order, and they can repeat, which is why each row is an array aligned with them. truncated is true when the query had more rows than limit. |
Aucun avis à afficher.