Each module has its own storage, in the game database. No other module can read it, and a module never sees the game's own tables.
Bags
A bag keeps small values.
| bag | holds values for |
|---|---|
m:global() | the whole server |
m:char(player) | one character (a player table or a character id) |
m:account(player) | one account (a player table or an account id) |
m:item(item) | one item instance (an item table or its uid), never a slot or an item code |
local bag = m:char(ev.player)
bag:set("kills", (bag:get("kills") or 0) + 1)
bag:delete("kills")
for _, key in ipairs(bag:keys()) do ... end
Values are strings, numbers, booleans, or tables of those up to four levels deep. A value is at most 4096 bytes once stored, a key at most 64 characters, and one bag holds at most 256 keys.
rf.get(scope, owner, key) and rf.set(scope, owner, key, value) reach the same values by scope name ("server" with no owner, "character", "account", "item"). Prefer the bags.
An item's bag stays with that item. It follows the item through the bag, the trunk, the mail, a trade and the auction, and it is deleted when the item is destroyed.
Stacks have a rule of their own. Splitting a stack makes a new item with an empty bag, and the part left behind keeps the old one. Merging keeps the target stack's bag, and a stack that merges away loses its own.
Custom Tables
For data that is a list rather than a few values, declare a table:
tables = {
kills = {
columns = { char = "int", boss = "text(16)", n = "int", last = "time" },
key = { "char", "boss" },
index = { { "boss" } },
},
},
The table is created in the game database as mod_<module>_<name> when the module loads, and a column added later is added to it. Changing a column's kind or the key is refused.
| column kind | holds |
|---|---|
int | a whole number |
num | a number |
bool | true or false |
text(N) | a string; N is at most 1024 |
time | Unix seconds |
Use it as m.db.kills:
m.db.kills:put{ char = p.id, boss = "01005", n = 1, last = m:now() } -- insert or replace
local row = m.db.kills:get{ char = p.id, boss = "01005" } -- by the full key, or nil
m.db.kills:delete{ char = p.id, boss = "01005" }
local top = m.db.kills:find{ where = { boss = "01005" }, order = "-n", limit = 10 }
local n = m.db.kills:count{ where = { boss = "01005" } }
find returns at most 500 rows, or 100 if no limit is given. Leave where out to match every row, and order = "-n" sorts descending. There is no SQL.