🗄️ Vault
Unbox The Vault 🗄️ (free, like every expansion) and your bot gets its own isolated database — SQLite, living on the Engine. Define the schema in the Vault tab; the Engine creates or migrates it on every deploy.
🏗️Defining Your Schema
Add tables and columns in the Vault tab. This is what a table looks like:
scoresuser_idPKusernamepoints// Your Vault schema becomes real SQLite tables:
db.run(`
CREATE TABLE IF NOT EXISTS scores (
user_id TEXT PRIMARY KEY, -- type: TEXT, primaryKey
username TEXT DEFAULT '', -- type: TEXT, default ""
points INTEGER DEFAULT 0 -- type: INTEGER, default 0
)
`);
// The Engine applies CREATE TABLE IF NOT EXISTS on every deploy — safe and additive.📊Column Types
| Type | Stores | Good for |
|---|---|---|
📝 TEXT | String text | User IDs, names, messages, ISO timestamps |
🔢 INTEGER | Whole numbers | Counters, scores, Discord snowflakes |
💫 REAL | Floating-point numbers | Averages, percentages |
✅ BOOLEAN | True/false (stored as 0/1) | Flags, active/inactive states |
📦 BLOB | Raw binary data | Rarely needed — prefer TEXT |
🧩Vault Pieces
Read, write and delete rows from any flow — the three classic pieces of The Vault.
base.db.readResults land in {{result}} — use {{result.0.points}}.
base.db.writeTurn on upsert to update existing rows by primary key — +10 adds to the current points.
base.db.deleteAlways set a filter — without one, the entire table is wiped.
🏆Leaderboards, Tallies & Cooldowns
The rest of the pack — the things almost every economy or levelling bot ends up needing.
Add to or take from one number in a single step — set "Never go below" to make spending safe.
One row, straight to sparks: {{row.coins}} instead of {{result.0.coins}}.
A leaderboard in one piece — sorted, trimmed, and every row knows its place.
"You're #4 of 120" without fetching the whole board. Ties share a place.
Count rows, or total / average / lowest / highest a column.
Pull a random row — quotes, prizes, giveaway winners.
Change every matching row at once, never adding new ones.
"Once every 24 hours" for /daily — no table needed.
The newer pieces can filter with = ≠ > ≥ < ≤, contains or starts with.
🔐All-or-Nothing
Some changes only make sense together: take coins from one person, give them to another. All-or-Nothing makes sure it's both — or neither.
Drop a 🔐 All-or-Nothing box and wire the Vault pieces that belong together off its Inside exit. If everything works, every change is saved at once and the flow carries on from All saved. If anything fails — or a ✋ Call it Off runs — every change inside is undone and the flow takes Undone, where {{oops.reason}} says why.
// 🔐 All-or-Nothing — what the box does for you:
db.exec("BEGIN IMMEDIATE"); // other spells wait a blink
try {
takeCoins(payer, amount, { neverBelow: 0 }); // Not enough? → throw CallItOff
giveCoins(friend, amount);
db.exec("COMMIT"); // → All saved ✓
} catch (err) {
db.exec("ROLLBACK"); // → Undone ↩ with {{oops.reason}}
}Vault pieces and thinking pieces — conditions, math, variables, text, lists, loops and your own custom pieces. Replies, DMs, roles and waits go afterthe box, on All saved or Undone: a box can't un-send a message.
While a box saves, other spells wait a blink before touching the Vault — so two people pressing /pay at the same moment can never spend the same coins. Spending one number? ➕ Bump a Number with "Never go below 0" is already safe on its own.
📐Naming Rules
Table and column names must be lowercase snake_case — letters, digits, underscores only. Must start with a letter.
🚀Schema on Deploy
Removing a table or column from your schema leaves the data in SQLite. To remove data, use Delete from Vault explicitly.