Edit Mode Automations - ArnoldSmith86/virtualtabletop GitHub Wiki
Automations is the section of the Edit Widgets panel in which a widget's routines are written. It is its own complete editor rather than a list of fields: a routine is built here as a stack of cards, each of which reads as a sentence saying what that step does, instead of as the JSON the room actually stores.
Everything the section can do can also be done in the JSON editor, and both edit the same properties β every card has a button that opens the routine there, and every change made here lands in the room immediately (use History or Ctrl+Z to undo). See [Functions]] for what the operations mean, [Dynamic Expressions for ${...} values and Computations for what a var statement can work out.
The section has two groups: Routines, the routines of the widget, and Property sets, the properties a widget applies to other widgets without a routine at all.
Links to sections:
- The sentence
- The colors
- Changing a value
- Moving operations around
- Blocks and dialogs
- When the editor cannot know
Full size
Writing a routine is what the panel is for while you are doing it, so the section bar carries a Full size switch: it folds every other section of the Edit Widgets panel away and gives the Automations section the height of the whole sidebar. The choice is remembered across widgets (it is a preference of whoever edits, not part of the game), but adding the first routine to a widget never takes the panel over by itself β the switch only becomes usable, turning it on is a click of its own. A widget with no routine and no property set has nothing to give the panel to, so the switch is greyed out and says so.
Routines
Each routine of the widget is one card. The header says what runs it in plain words β click, double-click, property changed, widget enters, widget leaves, game starts, any widget changed β followed by the property name it is stored under (clickRoutine, enterRoutine, β¦), an β button explaining exactly when it runs, a π¨ button showing the color key, a {} button that opens the routine in the JSON editor and a π button that removes it. Click the header to fold the routine open or closed; which ones were open is remembered per widget, so re-selecting a widget comes back to what you were working on.
A routine whose name the editor does not recognise is listed under the name it has, with the note that only the Run the routine operation (CALL) starts it. Names like fooChangeRoutine and fooGlobalUpdateRoutine are recognised and described in terms of the property foo.
Adding a routine
add routine offers the Predefined Routines β the ones above, minus those the widget already has, each with a line saying when it runs β and a Custom Routine field for a name of your own. A name that does not end in Routine gets the suffix added.
Routines of a deck
A deck is two things in one place: the widget on the table, which nobody clicks, and the cards it hands out, whose properties come from cardDefaults. Adding a routine to a deck therefore asks which of the two it is for, with on every card of this deck preselected β for the cards to act on a routine it has to be in cardDefaults, and a routine on the deck itself only ever runs on the deck widget.
Both places are listed, each card carrying a badge saying which of the two runs it (every card / the deck itself) and the name it has in the JSON (cardDefaults β¦ clickRoutine). The same routine in both places is two cards next to each other, each pointing at the other; they are separate routines and are edited, opened and removed on their own. Removing a card routine leaves the other card defaults alone, and the last one takes the empty cardDefaults with it.
A pile follows the rule the rest of its panel follows: its routines belong to the deck's pile template rather than to the pile, since the pile itself is temporary.
The routine editor
An open routine is a column of operation cards in the order they run, with add operation at the bottom. The operation list is searchable β by the name of the operation and by what its sentence says β and a new operation is inserted right after the card you last worked on, so a routine is built in the order it runs.
Each card has the name of the operation on its own line (MOVE, SET, IF, β¦) with an β button carrying its wiki text; clicking the name exchanges the operation for another one.
The sentence
Below the name, the operation is written as a sentence: Move 1 card from deck1 to hand1, face up. The parts of the sentence are what you click to change it:
- The sentence starts with a drop-down naming the way the operation works β
FLIPturns things face down, face up or onwards;SETreads Set / Increase / Decrease / Multiply / Divide / Toggle / Append. Picking another entry rewrites the parameters that tell the ways apart together with the wording. - Optional parts are only in the sentence while they are in use. Each carries a β that takes it back out, and add option at the end offers the rest β as the phrase they would add (
n times,ignore something) rather than as a parameter name. Switching one on usually leaves a further drop-down in the sentence for the detail it is about. - A blank says what belongs in it, in red: a fresh
SETreads Set property of the picked widgets to number or text. - Values a game usually says in seconds (a
TIMER, stopping a sound early) are said in seconds here, with the milliseconds the engine stores converted behind the sentence.
Anything the sentence cannot express (although this should be very rare and comes with a warning icon) is still reachable: the {} button in the corner of a card edits the whole operation as raw JSON.
The colors
Every value in a sentence is colored by the kind of thing it is. The π¨ button in the header of every routine holds the key:
| Example | Means |
|---|---|
| Pick | what the operation does β the words a sentence starts with |
card1 |
one widget of the game, named by its id |
| the picked widgets | a group of widgets: what an earlier operation picked, or a group it named |
score |
a value the routine remembers, under the name it gave it |
activeFace |
the name of a widget property |
3 |
a number |
"Hello" |
everything else: a text, a setting from a list, or a value written as JSON |
| number or text | a blank the operation still needs β the word says what belongs there |
Changing a value
Clicking a value opens a popup that starts with the value itself as an editable text field, next to a use default button that removes the explicit value again. Below that, one section per kind of thing you could put there instead β only one open at a time:
- Widgets in the room β search by id, filter by type, or pick the widget on the table; the type filter also applies to picking (with the type set to holder, a click on a card selects the holder it lies on).
- Values the routine has β what earlier operations remember (
COUNT,GET,VAR,CALL) and the values every routine has, inserted as${name}. - Groups of widgets the routine has β the collections an earlier
SELECTpicked out, plus the ones every routine has. - A property of a widget in the room β a Property
nameofwidgetbuilder. It defaults to the current widget, but that can be changed, and the name field suggests the properties the chosen widget actually has.
A drop-down in the sentence always ends in something elseβ¦, which is the way to create a value the routine only works out while it runs.
Popups can be stacked (an β inside a parameter popup opens another one) and every one of them has a β; Escape closes only the top-most one. While a popup is open, the chip it belongs to is outlined, and the popup keeps to the space above or below it so the sentence it is about stays readable.
A popup belongs to the widget being edited, so it also closes as soon as the editor moves on to another one β you click a different widget in the room, the edited widget is deleted or undone, or another game is loaded. The pickers that only write their value when the popup goes away (color, icon, sound, key/value pairs, lists of strings) still apply what was picked, to the widget it was picked on; the editor says so with a short note in the corner of the panel, which also tells you where the value was dropped because that widget is gone. Pick in the room is not the editor moving on: while it is armed the button reads Click a widget in the roomβ¦ and a click in the room fills the parameter with the popup still open.
Moving operations around
Each card has a grip that drags it to another position β including into an IF or FOREACH block. Ctrl+click (long press on touch) selects several cards to move at once. Next to the grip, arrows move the card one step up or down, move it into the block above or below, or take it out of the block it is in; the π removes it.
Blocks and dialogs
IF draws its THEN and, once add else is clicked, its ELSE block as a routine of its own below the condition, and so does FOREACH with its loop body. Each block is a full routine editor with its own add operation.
An INPUT dialog is a form, and its fields are drawn the same way: one card per line of the dialog below the sentence, added with add line and described by the same chips, drop-downs and options one level down. Every kind of line says what its answer will be and under which name it is remembered β and that a line without a name throws its answer away, which is why typing the question proposes a name.
When the editor cannot know
Any value of an operation may be a ${...}, including the ones that decide what the operation does. Where the answer would change with what the reference comes out as, the card says so instead of guessing: an orange ! names the reference, the parameter it would have been decided from stays visible as a value of its own. Nothing is hidden as unused, and every entry of the drop-down says which reference picking it would write over. A parameter the engine no longer wants (a deprecated one) is shown with an orange ! while a game has it, but is never offered as something to add.
Property sets
Below the routines, a widget can automate other widgets without a routine at all. Each of these is a set of property: value pairs applied at a given moment, and each is edited as one row per entry β the property name, its value, and a button removing it β with the property names of the room proposed for a new entry:
- set properties on enter (
onEnter) and set properties on leave (onLeave) β offered for holders and for lines. A line takes widgets in the same way a holder does (whatever matches itsdropTargetbecomes one of its stops) and applies the same sets to them.activeFace: 1on enter flips cards face up,rotation: 0straightens them, and custom properties set here can be reacted to in routines. - reset properties (
resetProperties) β offered for every widget, and applied to the widget itself by theRESETfunction, typically from a reset button. Apply values now applies the set immediately, and Record current state copies the widget's current values (including defaults likex,yandrotation) into it, soRESETrestores exactly the state the widget is in.
What a typed value is stored as follows one rule, which the editor states under the rows: true, 12, null and [ 1, 2 ] are stored as values, anything else as text β and "12" in quotes is the text 12. Removing the last row removes the property altogether.