Reading a Variable
There are two ways to read a variable, and they can give different answers in the same moment. This lesson shows when each one sees a new value.
Contents
button Held -> chip pressed
chip text -> decal Text
Code
@left in pressed: exec
var count: int = 0
var before: int = 0
var after: int = 0
@right out text = "before ${before.Value}, after ${after.Value}, now ${count.Value}"
on pressed {
before = count
count += 1
after = count
}
Inside the handler, the bare name count reads the variable at that step of
the chain. before = count runs before the add, and after = count runs
after it. Outside the handler, count.Value is a pure wire from the Variable
gate.
What does the sign say after the first press? After the second?
Run
- Compile the chip and paste it in-game. Place a Button and a brick with a Text Decal.
- Wire the Button’s Held to
pressed, andtextto the Text Decal’s Text. - Press once. The sign reads “before 0, after 1, now 1”. Each press moves all three along by one.
Under the Hood
Open the chip. The handler’s chain has two Get Variable gates for count: one
before the Increment Variable and one after it. Each Get Variable reads the
variable when the chain reaches it, so the second one sees the new value.
The text has no Get Variable at all. Its Format String gate is wired straight from the Variable gates’ value outputs.
The game updates every wire about 60 times a second. Each update is a tick. A
handler’s steps all run inside one tick, one after another. Pure gates, and
the .Value wires they read, settle once per tick, so while a handler runs
they still show what the variable held when the tick began. The sign shows the
new count one tick after the press, far too soon to notice.
Modify
-
Swap the first two lines of the handler so
count += 1comes first. Nowbeforeandafteralways match. -
Build some text from
count.Valuein alet, and copy it in the handler:@left in pressed: exec var count: int = 0 var copied: string = "" let label = "count is ${count.Value}" @right out text = copied.Value on pressed { count += 1 copied = label }Press once: the sign says “count is 0”.
labelis a pure wire, and at the moment the handler copies it, it has not caught up with the add yet. Each press shows the count from before that press. -
Fix it by building the text inside the handler, where the bare name reads the new value:
@left in pressed: exec var count: int = 0 var copied: string = "" @right out text = copied.Value on pressed { count += 1 copied = "count is ${count}" }When the text only shows the count, it needs no copy at all:
@right out text = "count is ${count.Value}"builds it outside the handler, with no extra variable, and follows each press a tick later.
Make
Make a dice sign. Each press of a button rolls a new number with
Random(1, 6), which gives a whole number from 1 to 6 and, like a variable
write, runs as a step inside a handler. The sign shows this roll and the one
before it: “now 4, before 2”. Think about which line has to come first.
button Held -> chip roll
chip text -> decal Text
Good to Know
- Outside a handler,
count.Valueis the value as of the start of this tick. You will also see a barecountused outside a handler: it is the same read. These lessons write.Valueso the delay is visible in the code. - Inside a handler,
count.Valueis still that same pure wire, so after a write it shows the old value. Read the bare name,count, instead. - Text built in a
letand used by a handler that has just written one of its variables shows the value from before the write. It looks like a display that lags one press behind.
Next: Buffers.