Destructuring
Before this: Tuples
Tuples took a mod’s outputs apart with let (lo, hi) = ....
Records come apart the same way, by field name instead of by position. This
works in a let, in a mod’s parameter list and in an event’s data.
Contents
zone "Zone Ref" -> chip room
chip text -> decal Text
Code
import { escape } from "sanitize"
type Visit = { name: string, seconds: int }
mod describe({ name, seconds }: Visit) -> string {
return "${escape(name)} stayed ${seconds} seconds"
}
@left in room: zone
var entered: Map<string, int>
var last: Visit = { name: "Nobody", seconds: 0 }
@right out text = describe(last)
on ZoneEntered(zone = room) -> { character: who } {
entered.set(who.GetUserId(), GetUnixTime())
}
on ZoneLeft(zone = room) -> { character: who } {
let { Value: since, Found } = entered.get(who.GetUserId())
if Found {
last = { name: who.GetDisplayName(), seconds: GetUnixTime() - since }
}
}
ZoneLeft is the opposite of ZoneEntered. It runs when a player walks out.
GetUnixTime() is the current time as a whole number of seconds, so the
difference between two readings is a time in seconds.
The code uses three kinds of destructuring:
-> { character: who }takes the event’s data by field name. The zone events have one field,character, andcharacter: whonames itwhohere.entered.get(...)gives back a record with two fields,ValueandFound.let { Value: since, Found } = ...takes both out, renamingValuetosinceand keepingFoundunder its own name.mod describe({ name, seconds }: Visit)takes aVisitand names its fields straight away, so the body usesnameandsecondswith novisit.in front.
Walk into the zone, wait ten seconds, and walk out. What does the sign say? What happens to a player whose entry time was never stored?
Run
- Compile the chip and paste it in-game. Give a brick an Attached Zone, and place a brick with a Text Decal.
- Wire the Attached Zone’s Zone Ref to
room, andtextto the Text Decal’s Text. - The sign starts as “Nobody stayed 0 seconds”. When you walk in, wait and walk out, it shows your name and how long you stayed.
Under the Hood
Open the chip. Destructuring builds no gates. The Get Map Element in the
ZoneLeft chain has a Value output and a Found output, and the two
names are those wires. Found goes into a Branch, and since into the
Subtract that works out the stay.
describe(last) is a Replace in String (from escape) and a Format
String, wired from the last.name and last.seconds Var gates. Passing the
record to the mod and taking it apart again costs nothing.
A pattern can only name fields the value has:
type Visit = { name: string, seconds: int }
var last: Visit = { name: "Nobody", seconds: 0 }
let { name, time } = last
@right out text = name
Error: [WS002] no field `time` on this value; available fields: name, seconds
Modify
- Destructure a record in a
let. In theZoneLefthandler, after settinglast, addlet { seconds } = lastand send the player their own time withwho.ShowChatMessage("You stayed ${seconds} seconds"). - Keep the longest stay. Add
var longest: Visit = { name: "Nobody", seconds: 0 }and a second sign. Replace it whenever a stay beats it. - Write the events with tuple capture instead,
-> (who). Both forms name the same output. Record capture can also pick fields out by name when an event has several.
Make
Make a “hold the hill” zone. Keep each player’s total time inside across
visits, in a Map<string, Visit> keyed by user id, and show who has held it
longest. Write one mod that takes a Visit apart in its parameter list to
build the sign’s text.
zone "Zone Ref" -> chip hill
chip text -> decal Text
Good to Know
ZoneLeftmay fire for a player with no stored entry time, for example one who was already inside when the chip was pasted.Foundis then false, and the sign keeps the last real visit. Over a long game a zone event can also be missed, which loses that one visit the same way.GetUnixTime()counts whole seconds, so a short stay can show as 0 or 1.- A display name is chosen by the player.
describeescapes it before it reaches the sign.
See Record Destructuring, Destructured Parameters and Binding Event Data.
Next: pick a lesson from the tree on the Learn page.