Besiege's Level Logic allows writing to variables with one event. However, it does not allow directly reading from variables for anything other than comparisons in a single event.
The SetGet logical system (designed by Nice Name) provides one-event functionality for reading variables for transformations, calculations, and more.
Reading and Writing[]
Writing to a variable is easy; only one "Modify Variable" event is necessary.
To read from a variable, however, the only way to do so is by repeatedly decreasing the variable by 1 and performing an action until the variable reaches 0; this is a loop (and all programming languages have them in some form). In this way, a number of actions will be performed equal to the variable's value.
On Variable “i > 0” (Place your logic here) Modify Variable “i - 1”
This operation is destructive; the value of the variable will be lost in reading it.
To recover the value, the loop will increase another variable (CopyA) in the opposite direction. At the end of the loop, CopyA will contain the original value, and another loop will be run to reset the variable to the original value.
On Variable “i > 0” (Place your logic here) Deactivate Variable “CopyA + 1” Activate Variable “i - 1”
The "Deactivate" and "Activate" events prevent event triggers checking CopyA from triggering while the loop is running.
Applications[]
Some examples of what the system can be used for:
- Moving entities - a "Transform Entity" event in the loop will move the entity by a distance equal to the variable's value.
- For example: if the "Transform Entity" event moves the entity by 1 metre in a direction, and i is 35, then the SetGet system will move it 35 metres.
- Calculations - a "Modify Variable" event allows for duplicating and multiplying variables.
- Setting the "Modify Variable" event to (+ 1) will set the output variable to i + 1.
- SetGet v6 itself cannot multiply numbers, but you can build a multiplier with it. Example level: Multiplier v6
Digit System[]
It's not all fun and games, though; Besiege will not run single-frame loops for more than 37 steps (for performance or game-crashing reasons).
To overcome this, a base-38 digit system is required, and it should automatically carry over to the next digit group. We will call the first digit group “DG1" (Digit Group #1).
In order to not trigger the read system while writing, the object is deactivated - no event triggers checking DG1 will be triggered, which means that the carry system will not work. A second variable (SG1) solely for this purpose is required to make it work, which is set equal to DG1:
On Variable “SG1 > 37” Deactivate Variable “DG2 + 1” Variable “DG1 - 37” Activate Variable “SG2 + 1” Variable “SG1 - 37”
Once SG1 exceeds 37, DG1 will carry over to DG2. This allows the carry system to work without triggering events checking DG1.
Due to needing digit groups, the system cannot handle infinite values; it does have limits, and it will break when those are exceeded (with two digit groups, the limit is 37 x 38 (1406)).
To handle this, the input must be clamped. This is achieved by tracking the input with a variable "limit"; if limit reaches the assigned bounds (±1406), it will cancel input.
On Variable “limit > 1406” Variable “SG - 1”
On writing, the input (SG) is fed into SG1, DG1, and DG2, triggering the carry system as necessary.
On Variable “SG > 0” Variable “limit + 1” Deactivate Variable “DG1 + 1” Activate Variable “SG1 + 1” Variable “SG - 1”
It is possible to add more digit groups, if you know what you're doing and/or have need of it.
Usage[]
To start reading:
Variable “DG1 + 0”
This triggers the loops checking DG1, which are all disabled during input processing.
To start writing:
Modify Variable “SG + (-37 < i < 37)”
This starts input processing. The input must be between -37 and +37 for a single event, to avoid crashing the program.
Logic Overview[]
Bringing the above sections together, the complete program is outlined below:
References[]
Steam Workshop :: SetGet v6
Steam Guide :: SetGet v6
SetGet v6 Logic Diagram