Login

Fancade Wiki

Created "control flow" page with greater detail about control flow than is found on the "Execution order" page

... ...
@@ -0,0 +1,104 @@
1
**Control flow** is a programming term that means the order that the steps of a computer program are executed, and the ways a programmer can control that order to do things like loops, if/then branches, or more advanced patterns like event handlers. This page describes how control flow works in Fancade scripting.
2
3
# Statements and expressions
4
5
For purposes of control flow, it's useful to think of script blocks as belonging to one of two categories:
6
7
## Statements
8
9
**Statements** are script blocks that make changes to the game's state (or as we sometimes say in programming, they have "side effects"). A statement might [[play a sound|Blocks/Play Sound]], [[write a value|Blocks/Set Variable]] to a variable, [[change the position|Blocks/Set Position]] of an object, [[cause another statement to run|Blocks/If]], etc.
10
11
Statements are easy to recognize — **they always have yellow "before" and "after" wires** at top and bottom.
12
13
Only statements are subject to control flow. Because they have side effects, their order of execution is important!
14
15
## Expressions
16
17
**Expressions** are script blocks that _do not_ make changes to the game's state. Instead, they provide data values which can be inputs to statements or other expressions. An expression might add two numbers together, [[read a value|Blocks/Get Variable]] from a variable, [[measure|Blocks/Get Position]] an object's position, etc.
18
19
Expressions are only evaluated when they're an input to the currently executing statement (or an input to an input, etc...). When that happens, they're evaluated against the game's _current state_. An expression can be an input to multiple statements, in which case it'll be evaluated again for each of them, against the current game state each time.
20
21
# The tick cycle
22
23
The basic unit of time in Fancade is the "tick". There are 60 ticks to a second, and the script blocks get a chance to run in every tick. The physics engine also updates the state of physics-enabled objects once per tick (and scripts can execute after the physics update, using the [[Late Update|Blocks/Late Update]] block.)
24
25
During the script execution phase of a tick, statements are executed synchronously, one at a time. Even though the wires may make it look like things are multi-threaded, they are not!
26
27
# Instruction sequencing
28
29
There are two basic ways to determine the sequence that statements get executed: **Execution order** wires, and script block **positioning** (See also: [[Execution Order]])
30
31
## 1. "Execution order" wires
32
33
The **<font color="ffe043">yellow</font>** "before" and "after" wires that all statements have, are called "execution order" wires.
34
35
* After a statement executes, it sends a run signal to its **"after"** wire.
36
* If a statement block has its **"before"** wire attached to another block, it will run each time a run signal is sent down that wire
37
* (If its "before" wire isn't attached to anything, it'll run **once per tick** according to its position, as described in the next section.)
38
39
Some things to be aware of:
40
41
* These connections can be many-to-many &mdash; a statement can send its "run" signal to multiple recipients, or it can receive "run" signals from multiple senders
42
* A statement can run many times in a single tick, if it receives multiple "run" signals. This is usually caused by Control statements (see below), though it can also be from having multiple "before" connections.
43
* A statement will not run at all in a tick, if its "before" wire is connected but it receives no "run" signal. This can only happen due to Control statements.
44
45
## 2. Positioning
46
47
If a statement block does **not** have a wire attached to its "before" input, it will be executed **once on every tick\***. These disconnected statements are sequenced according to their position in the game field. Statements are executed top to bottom, left to right, like words on a page.
48
49
Specifically, they're ordered like so:
50
51
1. Z axis, descending
52
2. X axis, ascending
53
3. Y axis, descending
54
55
This same ordering also controls the order of execution when multiple statements have their "before" wires attached to the same "after" wire.
56
57
**\* Note:** As an exception to the rule, the [[Play Sound|Blocks/Play Sound]] and [[Stop Sound|Blocks/Stop Sound]] blocks will **not** run at all if their "before" wire isn't attached to anything. But all other statement blocks will execute once per tick if their "before" wire is unattached.
58
59
## Working together
60
61
With positioning and execution order wires together, the full ordering sequence is something like this:
62
63
1. The uppermost, leftmost statement with no "before" input gets executed first.
64
2. Any blocks connected to its "after" wire get executed next, followed by any blocks connected to _their_ "after" wire, and so on.
65
3. The next statement with no "before" input gets executed, followed by any blocks connected to its "after" wire.
66
67
# Control statements
68
69
Blocks in the "Control" category are the main way you can modify the control flow beyond simple before/after sequencing. Control statement blocks are colored yellow, the same as execution order wires, and they all have one or more additional execution order wires sticking out of their right side (along with the normal "before" and "after" wires).
70
71
When a control block executes, it may send a run signal down its "third wire" (or multiple run signals, for the [[Loop block|Blocks/Loop]]). The same as an "after" wire, the "third wire" can be attached to another statement's "before" wire, and it will cause that block to execute each time the control block sends a run signal.
72
73
Control blocks also have the same "before" and "after" wires as other statement blocks, and these work alongside the "third wire":
74
75
* If a control block's "before" wire is connected, the control block won't signal along its "after" wire or its "third wire" unless and until it receives a run signal.
76
* And it can send a pulse down its "third wire" every time it receives a run signal
77
* When a control block executes, it sends any "third wire" run signals **before** it sends its "after" wire's run signal.
78
* So all the blocks connected to the third wire will execute before any blocks connected to the "after" wire.
79
* After a control block executes, it sends a run signal down its "after" wire. This happens whether or not it sent a signal down its "third wire".
80
81
There are a few general types of control blocks:
82
83
## Branching and looping
84
85
These blocks give you basic control structures that you'd find in most programming languages.
86
87
* [[If|Blocks/If]] takes a boolean value as an input, and sends a run signal down its "True" wire or its "False" wire
88
* [[Loop|Blocks/Loop]] acts like a [https://en.wikipedia.org/wiki/For_loop for loop]. It takes a numeric "start" value and "end" value, and it sends a run signal down its third wire once for every number from "start" to "end".
89
90
## Event handling
91
92
These blocks act something like [event handlers](https://en.wikipedia.org/wiki/Event-driven_programming#Event_handlers). They send a run signal down their third wire in response to an event from an outside source (user input, or the physics engine).
93
94
* [[Touch Sensor|Blocks/Touch Sensor]]
95
* [[Swipe Sensor|Blocks/Swipe Sensor]]
96
* [[Collision Sensor|Blocks/Collision]]
97
98
Although they're somewhat like event handlers, they're still governed by the execution ordering rules. Basically, if their triggering event happened during this tick, then the block will send a run signal down its third wire when (or if) the block executes during this tick.
99
100
## Timing modifiers
101
102
* [[Play Sensor|Blocks/Play Sensor]] sends a run signal down its third wire only on the game's first tick. It's used for initial setup tasks that should only run once.
103
* [[Box Art Sensor|Blocks/Box Art Sensor]] sends a run signal down its third wire only when the game is being executed to take a picture for box art. It's used to customize a game's box art imagery.
104
* [[Late Update|Blocks/Late Update]] sends a run signal down its third wire in a special final phase of the tick, after the physics engine has run. It's used to provide same-tick response to physics changes.
... ...
\ No newline at end of file
Fancade Wiki