The .bot language just grew a UI system and a type system
Two big things landed in the script engine this update, plus a pile of new commands. Here's the whole picture.
Until now a script talked to you through
The controls:
You read the interactive ones back with
Two design points that make this safe rather than a footgun:
And the button callback is checked when you write it:
Each enum is a type of its own. A
It's deliberately small: no iterating the members, no numbers behind them, no lists of them. An enum is a set of names, nothing more — which is exactly what makes it safe.
Two big things landed in the script engine this update, plus a pile of new commands. Here's the whole picture.
1. Scripts can build their own interface
Until now a script talked to you through
print()and the settings panel. Now a running script can put its own tab on the launcher's rail and fill it with real controls — and read them back live.
The controls:
uiTab("Miner")— name your tabuiHeader("Totals")— a section headeruiLabel("status", "Mining...")— a line of text you can updateuiProgress("trips", 4, 28)— a progress baruiButton("Drop all", "onDrop")— a button that runs a functionuiToggle("pause", "Pause", false)— an on/off switchuiChoice("mode", "Mode", Mode.POWER)— a dropdown over an enumuiInput("search", "Search", "")— a text field
You read the interactive ones back with
uiToggled(key),
uiChosen(key)and
uiText(key), and there's
uiHas(key)to check a row exists,
uiRemove(key)and
uiClear()to tidy up.
Two design points that make this safe rather than a footgun:
- Rows are an upsert by key. Call
uiLabel("status", ...)every pass inon loop
and it updates the same row — it doesn't grow a new one each time. - Button clicks run between passes, on your script's thread. A click never interrupts your loop half-way and never runs two things at once. It's the same safe hand-off
on message
uses.
And the button callback is checked when you write it:
uiButton("Go", "onGo") only compiles if a fun onGo()with no arguments actually exists. Typo the name and it's a red squiggle in the editor, not a dead button you discover in-game.
2. Enums — your own type
enum Mode { POWER, BANK, SELL }
setting Mode mode = Mode.POWER "What to do with ores"
if mode == Mode.BANK { become banking }
print(mode) # Mode.POWER
print(mode.name) # POWEREach enum is a type of its own. A
Modenever equals a string or a member of another enum — the checker refuses the comparison with a hint, so
if mode == "bank"is caught before you ever run it. A
settingtyped with an enum becomes a dropdown on the settings panel automatically.
.namegives you the member back as a string.
It's deliberately small: no iterating the members, no numbers behind them, no lists of them. An enum is a set of names, nothing more — which is exactly what makes it safe.
3. New commands
itemDefCount()
— how many item definitions the cache holds, so you can sweep every id withitemDef(id)
replace(text, find, with)
— literal string replace