SQL or * variables?
A script has two ways to keep data after it stops: * variables, saved
in the Windows registry, and the SQL command, which keeps data in an SQLite database
file.
SQL does not replace * variables. They work exactly as before, and for a few values they are still
the simplest choice. Choose by the shape of the data:
- A few named values (a counter, a setting, an ID):
*variables. - Rows of data: a log, a list, several fields per entry, totals, or data that several scripts change at
the same time. Use
SQL.
At a glance
Section titled “At a glance”* variables |
SQL |
|
|---|---|---|
| Where the data is | The registry, under HKCU\Software\EasyUO. |
A file you name in sql open. |
| Setting up | Nothing: set *runs 1. |
sql open in each script, and a CREATE TABLE for your own tables. |
| Shape | One value per name. | Tables with as many rows and columns as you need. |
| Listing, searching, removing | Not from a script: you have to know the name, and no command deletes one. | SELECT … WHERE, DELETE, sql delete. |
| Totals, sorting, “in the last hour” | By hand, in a loop over numbered names. | SUM, COUNT, GROUP BY, ORDER BY, LIMIT. |
| Two scripts changing one value | A change can be lost (see below). | One statement is never interrupted by another. |
| Who sees it | Every script of your Windows user, in EasyUO Reforged and the original EasyUO. | Every script that opens the same file. |
| Original EasyUO | Works there too. | SQL is new in EasyUO Reforged. |
| Back up, move to another PC | reg export of the key (it holds EasyUO’s own settings too). |
Copy the file. |
| Looking at the data | regedit. |
Any SQLite tool, such as DB Browser for SQLite, or Python. |
| Needs | Nothing. | The SQLite that ships with Windows 10 and 11 (see Using SQL). |
When * variables are enough
Section titled “When * variables are enough”- You keep a handful of values: a run counter, the ID of your loot bag, a chosen option.
- The script must also run in the original EasyUO.
- Older scripts already read or write the same
*variables.
When SQL is worth it
Section titled “When SQL is worth it”- The data grows over time: every kill, every pickup, every skill gain.
- An entry has several fields (an ID, a name, a place, a time) and you want to find entries by any of them.
- You want totals, averages, the five best, or only what happened in the last hour.
- Several scripts, or several clients, write the same data at once.
- You want to look at the data, back it up or clear it without opening the registry.
Examples
Section titled “Examples”Counting runs
Section titled “Counting runs”A counter is the classic * variable, and it needs nothing else:
set *runs *runs + 1 ; N/A counts as 0, so the first run gives 1display ok This script has run *runs times.haltThe same with SQL takes two more lines: sql open, then
sql load and sql save around the change.
sql open mydata.dbsql load %runs ; the value saved last timeset %runs %runs + 1sql save %runs ; keep it for next timedisplay ok This script has run %runs times.haltFor a single value like this, * variables are fine. SQL only adds the choice of file.
One setting per character
Section titled “One setting per character”Several characters on one computer each need their own loot bag. With * variables, glue the character’s
ID to the name with .:
set %bag *lootbag . #CharID ; *lootbag followed by this character's IDif %bag = N/A{ set %bag ABCDEFG ; your loot bag's ID set *lootbag . #CharID %bag}display ok #CharName keeps loot in %baghaltThat works, but every character leaves a registry entry behind, and no script can list them. With SQL,
the characters are rows of one table, so a script can list them all:
sql open mydata.dbsql exec CREATE TABLE IF NOT EXISTS chars(id TEXT PRIMARY KEY, name TEXT, lootbag TEXT)sql query SELECT lootbag FROM chars WHERE id = #CharIDif #SqlCnt = 0{ set %lootbag ABCDEFG ; your loot bag's ID sql exec INSERT INTO chars VALUES(#CharID, #CharName, %lootbag)}sql query SELECT name, lootbag FROM chars ORDER BY namefor %i 1 #SqlCnt{ sql row %i ; sets %name and %lootbag display ok %name keeps loot in %lootbag}haltTo forget a character, sql exec DELETE FROM chars WHERE id = #CharID removes its row.
A loot log you can add up
Section titled “A loot log you can add up”Here SQL does something * variables can’t do. Each pickup becomes a row with the time
(#SysTime), and one query adds up the last hour:
sql open mydata.dbsql exec CREATE TABLE IF NOT EXISTS loot(at INTEGER, item TEXT, amount INTEGER)set %item gold ; in a real script: after each pickupset %amount 250sql exec INSERT INTO loot(at, item, amount) VALUES(#SysTime, %item, %amount)set %since #SysTime - 3600000 ; one hour agosql query SELECT item, SUM(amount) AS total FROM loot WHERE at > %since+ GROUP BY item ORDER BY total DESC LIMIT 5for %i 1 #SqlCnt{ sql row %i ; sets %item and %total display ok %item : %total in the last hour}haltThe same table answers other questions with one line each. For example,
SELECT COUNT(*) AS n FROM loot WHERE item = 'gold' counts the pickups of gold, and
SELECT item, MAX(amount) AS best FROM loot GROUP BY item gives the best pickup of each item.
With * variables, you would need a numbered variable for each pickup (*loot1, *loot2, …), another one
for the next number, and a loop over all of them for every total. The old entries would stay in the
registry for good.
Several scripts adding to one counter
Section titled “Several scripts adding to one counter”Several scripts, one per client, count kills in one shared total. With a * variable:
set *kills *kills + 1 ; reads the value, adds one, writes it backdisplay ok Kills counted by every script: *killshaltReading and writing are two separate steps. If two scripts read 41 at the same moment, both write 42
and a kill is lost. It is rare, but it happens more often as the number of scripts grows.
With SQL, the database adds one in a single statement, so no other script can change the value in the
middle. A script that finds the file busy waits for its turn (up to 5 seconds):
sql open shared.dbsql exec CREATE TABLE IF NOT EXISTS counters(name TEXT PRIMARY KEY, n INTEGER)sql exec INSERT OR IGNORE INTO counters VALUES('kills', 0)sql exec UPDATE counters SET n = n + 1 WHERE name = 'kills'sql query SELECT n AS kills FROM counters WHERE name = 'kills'display ok Kills counted by every script: %killshaltEvery script has to open the same file. A file name without a folder starts from
#CurPath, the folder of EasyUO Reforged, so shared.db is the same file for all
scripts.
Moving * variables into a database
Section titled “Moving * variables into a database”Copy each value into a % variable and save it:
sql open mydata.dbset %runs *runs ; one line for each value you want to keepset %kills *killssql save %runs %killsif #SqlRes = OK display ok Copied to mydata.dbhaltFrom then on, the script uses sql load and sql save instead of the * variables.
The * variables stay in the registry, because no script command deletes one. To remove them, open
regedit, go to HKEY_CURRENT_USER\Software\EasyUO and delete the values whose names start with *
(set writes the names in capitals, such as *RUNS). Leave the key and its other values alone: EasyUO
keeps its own settings there.