TutorialsPush Lab

Appendix A — Logic Reference

Every Logic Component and Function in Push Lab - Discovery Workshop, as it is in the finished game. Each entry stands on its own: read what it does, see what it needs, and build it from its card into your own game. A card’s Shared Variables and Per Instance Variables are the values you can change. A Shared Variable holds one value for the whole Object, under Variables in its Properties. A Per Instance Variable holds one for each placement in the Scene.

A.1 Listen for Control Press

Built in Chapter 2, Place the carts.

Logic ComponentListen for Control PressAttach to: Return Button, Push Button, Impulse Dial, Impulse Direction Lever, One Kilogram Weight, Two Kilogram Weight, Five Kilogram Weight, Help Control, Reading Ticket, Printer Reading, Reset Experiment Label, Restore Defaults Label, Store Copper Label, Link Both Label, Match Goal Label, Brake Goal Label, Target Goal Label, Stop Goal Label, Workshop Goal Result, Open Goals Label, Save Setup Label, Open Setup Label, Setup Page Label

Remembers the exact control pressed, before the pointer can move. Responses run in native Mouse Press Events.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When Created
WhenCreate
1Start Recurring Timer
Timer Name
"controlInputReady"
Repeat Every (s)
0.02
Ring Once
Yes
On the Control Input Ready Timer
WhenRecurring TimerTimer name: controlInputReady
1Execute Script
Script
Capture Control Press
On Load:succeeded
Whenload:succeededCustom Event
1Execute Script
Script
Capture Control Press

A.2 Place Cart on Rail

Built in Chapter 2, Place the carts.

Logic ComponentPlace Cart on RailAttach to: Blue Cart, Copper Cart

Place one exact cart along its rail with the pointer, release it from rest, or return it home.

Attach toAny Object
COMPONENTS
self.colliderCollider
SHARED VARIABLES
NameTypeKindStarting Value
homeXNumberConstant6.75
laneYNumberConstant10.975
leftLimitNumberConstant5.975
rightLimitNumberConstant20.875
PER INSTANCE VARIABLES
NameTypeStarting Value
grabOffsetNumber0
handXNumber0
pressSelectedBooleanNo
When Created
WhenCreate
1Start Recurring Timer
Timer Name
"cartInputReady"
Repeat Every (s)
0.02
Ring Once
Yes
On the Cart Input Ready Timer
WhenRecurring TimerTimer name: cartInputReady
1Execute Script
Script
Capture Cart Press
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true && dataFind("Workshop Weights","cart",-1) < 0
Then
2Set Velocity
X Velocity
0
Y Velocity
0
3Change Component Value
Component Value
self.collider.fixed
Value
true
4Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Holding
While the Left Mouse Button Is Held
WhenMouse HeldMouse button: left
ModeReleased (Starting Mode)
(no Actions)
While the Left Mouse Button Is Held
WhenMouse HeldMouse button: left
ModeHolding
1Change Variable
Variable
handX
Value
valueMember(event.position,"x") - self.grabOffset
2Set Position
X
clamp(self.handX, @self.leftLimit, @self.rightLimit)
Y
@self.laneY
When the Left Mouse Button Is Released
WhenMouse ReleaseMouse button: left
1Release CartFunction
cart
self
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Focus Lost
WhenFocus Lost
1Release CartFunction
cart
self
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Touch Cancelled
WhenTouch Cancelled
1Release CartFunction
cart
self
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Load:succeeded
Whenload:succeededCustom Event
1Release CartFunction
cart
self
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
3Execute Script
Script
Capture Cart Press
When Return Carts Is Pressed
WhenCommand PressedCommand: Return Carts
1Return Cart HomeFunction
cart
self
homeX
@self.homeX
laneY
@self.laneY
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Return Carts
WhenreturnCartsCustom Event
1Return Cart HomeFunction
cart
self
homeX
@self.homeX
laneY
@self.laneY
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1If$detailsOpen
Then
2Release CartFunction
cart
self
3Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released

A.3 Play Workshop Click (Function)

Built in Chapter 2, Place the carts.

FunctionPlay Workshop Click

Plays the quiet workshop click for an accepted input request. Reset, setup import and canceled hands stay silent.

PARAMETERS
NameTypeStarts at
acceptedBooleanYes
ACTIONS
1Ifaccepted == true
Then
2Control Sound
Sound
Workshop Click

A.4 Release Cart (Function)

Built in Chapter 2, Place the carts.

FunctionRelease Cart

Returns a held cart to native physics without throwing it. Released carts keep their existing velocity.

PARAMETERS
NameTypeStarts at
cartObject
Compatibility ModeStructural
Required Components
Slot Nametransform
Component TypeTransform
Slot Namecollider
Component TypeCollider
ACTIONS
1Ifcart.collider.fixed == true
Then
2Set Velocity
Applies to
cart
X Velocity
0
Y Velocity
0
3Set Spin
Applies to
cart
Spin
0
4Change Component Value
Applies to
cart
Component Value
cart.collider.fixed
Value
false

A.5 Return Button Response

Built in Chapter 2, Place the carts.

Logic ComponentReturn Button ResponseAttach to: Return Button

The orange button asks the apparatus to return. The button and Home request share one quiet click.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2Trigger Custom Event
Custom Event
returnCarts
3Play Workshop ClickFunction
accepted
Yes
When Return Carts Is Pressed
WhenCommand PressedCommand: Return Carts
1Play Workshop ClickFunction
accepted
Yes

A.6 Return Cart Home (Function)

Built in Chapter 2, Place the carts.

FunctionReturn Cart Home

Stops one cart and returns it to its chosen lane start without changing mass.

PARAMETERS
NameTypeStarts at
cartObject
Compatibility ModeStructural
Required Components
Slot Nametransform
Component TypeTransform
Slot Namecollider
Component TypeCollider
homeXNumber6.75
laneYNumber10.975
ACTIONS
1Release CartFunction
cart
cart
2Set Velocity
Applies to
cart
X Velocity
0
Y Velocity
0
3Set Position
Applies to
cart
X
homeX
Y
laneY

A.7 Apply Cart Impulse (Function)

Built in Chapter 3, Deliver an impulse.

FunctionApply Cart Impulse

Measures native mass and velocity, applies one signed impulse, then measures the immediate new velocity. Outputs describe this push, not later motion.

PARAMETERS
NameTypeStarts at
cartInstance Setundefined
impulseNumber4
RETURN TYPEImpulse Reading (a Data Structure)
ACTIONS
1Declare Variable
Name
mass
Value
param:cart.transform.mass
2Declare Variable
Name
before
Value
param:cart.transform.velocity.x
3Apply Impulse
Applies to
cart
Strength
impulse
Direction
0
4Declare Variable
Name
after
Value
param:cart.transform.velocity.x
5Return
mass
mass
before
before
after
after

A.8 Choose Impulse Direction

Built in Chapter 3, Deliver an impulse.

Logic ComponentChoose Impulse DirectionAttach to: Impulse Direction Lever

Click the lever to reverse the next push direction. Carts and old readings keep their current state.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2Change Variable
Variable
$impulseDirection
Operator
*=
Value
-1
3Play Workshop ClickFunction
accepted
Yes
When Created
WhenCreate
1Set Rotation
Degrees
$impulseDirection * 24
On Variable Changed · Impulse Direction
WhenVariable ChangedGlobal Variable: impulseDirection
1Set Rotation
Degrees
$impulseDirection * 24
On Load:succeeded
Whenload:succeededCustom Event
1Set Rotation
Degrees
$impulseDirection * 24

A.9 Choose Next Impulse

Built in Chapter 3, Deliver an impulse.

Logic ComponentChoose Next ImpulseAttach to: Game Rules

Arrow keys choose the shared next impulse and its direction. End chooses the maximum; 0 chooses zero.

Attach toAny Object
When Increase Impulse Is Pressed
WhenCommand PressedCommand: Increase Impulse
1Select Shared ImpulseFunction
magnitude
$impulseMagnitude + data("Impulse Settings","Shared","increment")
When Decrease Impulse Is Pressed
WhenCommand PressedCommand: Decrease Impulse
1Select Shared ImpulseFunction
magnitude
$impulseMagnitude - data("Impulse Settings","Shared","increment")
When Maximum Impulse Is Pressed
WhenCommand PressedCommand: Maximum Impulse
1Select Shared ImpulseFunction
magnitude
data("Impulse Settings","Shared","maximum")
When Zero Impulse Is Pressed
WhenCommand PressedCommand: Zero Impulse
1Select Shared ImpulseFunction
magnitude
0
When Left Impulse Is Pressed
WhenCommand PressedCommand: Push Left
1Change Variable
Variable
$impulseDirection
Value
-1
When Right Impulse Is Pressed
WhenCommand PressedCommand: Push Right
1Change Variable
Variable
$impulseDirection
Value
1
When Created
WhenCreate
1Select Shared ImpulseFunction
magnitude
$impulseMagnitude
On Load:succeeded
Whenload:succeededCustom Event
1Select Shared ImpulseFunction
magnitude
$impulseMagnitude
On Data Table Changed · Impulse Settings
WhenData Table ChangedData Table: Impulse Settings
1Select Shared ImpulseFunction
magnitude
$impulseMagnitude

A.10 Identify Workshop Cart

Built in Chapter 3, Deliver an impulse.

Logic ComponentIdentify Workshop CartAttach to: Blue Cart, Copper Cart

Registers the first valid cart in each workshop slot once. A later copy never replaces an original that has disappeared.

Attach toAny Object
COMPONENTS
self.colliderCollider
SHARED VARIABLES
NameTypeKindStarting Value
cartNumberNumberConstant1
When Created
WhenCreate
1If@self.cartNumber == 1 && $blueCartRegistered == false
Then
2If$blueCart.count == 0
Then
3Set Instance Set
Instance Set
$blueCart
To
self
4If$blueCart.count == 1
Then
5Change Variable
Variable
$blueCartRegistered
Value
true
6If@self.cartNumber == 2 && $copperCartRegistered == false
Then
7If$copperCart.count == 0
Then
8Set Instance Set
Instance Set
$copperCart
To
self
9If$copperCart.count == 1
Then
10Change Variable
Variable
$copperCartRegistered
Value
true

A.11 Open Workshop Readings

Built in Chapter 3, Deliver an impulse.

Logic ComponentOpen Workshop ReadingsAttach to: Help Control

H or the bench Help control opens and closes the optional live readings and instructions without changing physics.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When Workshop Help Is Pressed
WhenCommand PressedCommand: Workshop Help
1Toggle Workshop ReadingsFunction
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2Toggle Workshop ReadingsFunction

A.12 Prepare Impulse Settings (Function)

Built in Chapter 3, Deliver an impulse.

FunctionPrepare Impulse Settings

Repairs a missing Shared tuning row or a nonpositive range/increment. A step larger than the range becomes one whole-range step.

ACTIONS
1Check Data Row Exists
Action Name
sharedRow
Table
Impulse Settings
Row
"Shared"
2IfsharedRow.value
Then
3Ifdata("Impulse Settings","Shared","maximum") <= 0
Then
4Set Data Cell
Table
Impulse Settings
Row
"Shared"
Column
"maximum"
Value
40
5Ifdata("Impulse Settings","Shared","increment") <= 0
Then
6Set Data Cell
Table
Impulse Settings
Row
"Shared"
Column
"increment"
Value
0.1
7Ifdata("Impulse Settings","Shared","increment") > data("Impulse Settings","Shared","maximum")
Then
8Set Data Cell
Table
Impulse Settings
Row
"Shared"
Column
"increment"
Value
data("Impulse Settings","Shared","maximum")
9Otherwise
10Control Data Row
Action Name
addedRow
Table
Impulse Settings
Row
"Shared"
Values > maximum
40
Values > increment
0.1

A.13 Push Button Response

Built in Chapter 3, Deliver an impulse.

Logic ComponentPush Button ResponseAttach to: Push Button

The blue button requests one native pair push.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2Trigger Custom Event
Custom Event
pushRequested

A.14 Push Workshop Pair (Function)

Built in Chapter 3, Deliver an impulse.

FunctionPush Workshop Pair

Pushes the released original pair, records their immediate measurements, then checks that exact pair against the selected optional goal.

PARAMETERS
NameTypeStarts at
blueInstance Setundefined
copperInstance Setundefined
blueImpulseNumber4
copperImpulseNumber4
ACTIONS
1Ifparam:blue.count == 1 && param:copper.count == 1
Then
2Ifparam:blue.collider.fixed == false && param:copper.collider.fixed == false && dataFind("Workshop Weights","cart",-1) < 0
Then
3Apply Cart ImpulseFunction
Action Name
bluePush
cart
blue
impulse
blueImpulse
4Change Variable
Variable
$blueMass
Value
bluePush.mass
5Change Variable
Variable
$blueBefore
Value
bluePush.before
6Change Variable
Variable
$blueAfter
Value
bluePush.after
7Change Variable
Variable
$blueAppliedImpulse
Value
blueImpulse
8Change Variable
Variable
$blueDelta
Value
$blueAfter - $blueBefore
9Apply Cart ImpulseFunction
Action Name
copperPush
cart
copper
impulse
copperImpulse
10Change Variable
Variable
$copperMass
Value
copperPush.mass
11Change Variable
Variable
$copperBefore
Value
copperPush.before
12Change Variable
Variable
$copperAfter
Value
copperPush.after
13Change Variable
Variable
$copperAppliedImpulse
Value
copperImpulse
14Change Variable
Variable
$copperDelta
Value
$copperAfter - $copperBefore
15Change Variable
Variable
$blueReadingValid
Value
true
16Change Variable
Variable
$copperReadingValid
Value
true
17Change Variable
Variable
$pushBatch
Operator
+=
Value
1
18Change Variable
Variable
$pushStatus
Value
'Impulse applied to both carts.'
19Record Pair ReadingFunction
20Evaluate Workshop GoalFunction
21Play Workshop ClickFunction
accepted
Yes
22Otherwise
23Change Variable
Variable
$pushStatus
Value
'Release the apparatus before pushing.'
24Otherwise
25Change Variable
Variable
$pushStatus
Value
'Both workshop carts are needed for Push Both.'

A.15 Request Pair Push

Built in Chapter 3, Deliver an impulse.

Logic ComponentRequest Pair PushAttach to: Game Rules

Routes keyboard and button push requests to the exact workshop pair, with a visible missing-cart response.

Attach toAny Object
When Push Carts Is Pressed
WhenCommand PressedCommand: Push Both
1Push Selected ImpulsesFunction
On Push Requested
WhenpushRequestedCustom Event
1Push Selected ImpulsesFunction

A.16 Select Shared Impulse (Function)

Built in Chapter 3, Deliver an impulse.

FunctionSelect Shared Impulse

Limits and rounds a requested next impulse magnitude. It changes neither motion nor past readings.

PARAMETERS
NameTypeStarts at
magnitudeNumber4
ACTIONS
1Prepare Impulse SettingsFunction
2Declare Variable
Name
selected
Value
magnitude
3Ifselected >= data("Impulse Settings","Shared","maximum")
Then
4Change Variable
Variable
selected
Value
data("Impulse Settings","Shared","maximum")
5Otherwise
6Change Variable
Variable
selected
Value
round(selected / data("Impulse Settings","Shared","increment")) * data("Impulse Settings","Shared","increment")
7Ifselected < 0
Then
8Change Variable
Variable
selected
Value
0
9Ifselected > data("Impulse Settings","Shared","maximum")
Then
10Change Variable
Variable
selected
Value
data("Impulse Settings","Shared","maximum")
11Change Variable
Variable
$impulseMagnitude
Value
selected

A.17 Set Reading Visibility (Function)

Built in Chapter 3, Deliver an impulse.

FunctionSet Reading Visibility

Shows a genuine measured push only in the optional reading sheet; zero impulse is a measurement, the opening workshop is not.

PARAMETERS
NameTypeStarts at
captionInstance Setundefined
validBooleanYes
ACTIONS
1If$inspectedPush == 0 && ($detailsOpen && $pushBatch > 0 && valid)
Then
2Set Visible
Applies to
caption
Visible
true
3Otherwise
4Set Visible
Applies to
caption
Visible
false

A.18 Show Measured Reading

Built in Chapter 3, Deliver an impulse.

Logic ComponentShow Measured ReadingAttach to: Blue Push Reading, Copper Push Reading

Refreshes measurement visibility when the workshop opens, captures a push or finishes Load.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
readingCartNumberNumberConstant1
When Created
WhenCreate
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)
On Variable Changed · Push Batch
WhenVariable ChangedGlobal Variable: pushBatch
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)
On Load:succeeded
Whenload:succeededCustom Event
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)
On Variable Changed · Blue Reading Valid
WhenVariable ChangedGlobal Variable: blueReadingValid
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)
On Variable Changed · Copper Reading Valid
WhenVariable ChangedGlobal Variable: copperReadingValid
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)
On Variable Changed · Inspected Push
WhenVariable ChangedGlobal Variable: inspectedPush
1Set Reading VisibilityFunction
caption
self
valid
(@self.readingCartNumber == 1 && $blueReadingValid) || (@self.readingCartNumber == 2 && $copperReadingValid)

A.19 Show Workshop Detail

Built in Chapter 3, Deliver an impulse.

Logic ComponentShow Workshop DetailAttach to: Reading Sheet, Reading Sheet Title, Reset Experiment Label, Restore Defaults Label, Impulse Dial Face

Shows either a bench label or a reading-sheet element in its chosen view.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
showOnOpenBooleanConstantYes
When Created
WhenCreate
1Set Visible
Visible
$detailsOpen == @self.showOnOpen
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen == @self.showOnOpen
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen == @self.showOnOpen

A.20 Toggle Workshop Readings (Function)

Built in Chapter 3, Deliver an impulse.

FunctionToggle Workshop Readings

Toggles only the saved reading-sheet view. The experiment continues unchanged.

ACTIONS
1If$detailsOpen
Then
2Change Variable
Variable
$detailsOpen
Value
false
3Otherwise
4Change Variable
Variable
$detailsOpen
Value
true
5If$detailsOpen
Then
6Change Variable
Variable
$inspectedPush
Value
0

A.21 Turn Impulse Dial

Built in Chapter 3, Deliver an impulse.

Logic ComponentTurn Impulse DialAttach to: Impulse Dial

Drag the dial horizontally to select from zero to the tuned maximum (40 N s by default). Release, cancellation, focus loss and Load end the hand.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
dialLeftNumberConstant7.1
dialWidthNumberConstant2.05
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
ModeReleased (Starting Mode)
1Ifself.pressSelected == true
Then
2Select Shared ImpulseFunction
magnitude
(valueMember(event.position,"x") - @self.dialLeft) / @self.dialWidth * data("Impulse Settings","Shared","maximum")
3Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Turning
When the Left Mouse Button Is Pressed
WhenMouse HeldMouse button: left
ModeTurning
1Select Shared ImpulseFunction
magnitude
(valueMember(event.position,"x") - @self.dialLeft) / @self.dialWidth * data("Impulse Settings","Shared","maximum")
When the Left Mouse Button Is Released
WhenMouse ReleaseMouse button: left
1Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released
On Focus Lost
WhenFocus Lost
1Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released
On Touch Cancelled
WhenTouch Cancelled
1Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released
On Load:succeeded
Whenload:succeededCustom Event
1Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released
2Set Rotation
Degrees
135 - $impulseMagnitude / data("Impulse Settings","Shared","maximum") * 270
When Created
WhenCreate
1Set Rotation
Degrees
135 - $impulseMagnitude / data("Impulse Settings","Shared","maximum") * 270
On Variable Changed · Impulse Magnitude
WhenVariable ChangedGlobal Variable: impulseMagnitude
1Set Rotation
Degrees
135 - $impulseMagnitude / data("Impulse Settings","Shared","maximum") * 270
On Mouse Wheel · Up
WhenMouse WheelWheel direction: up
1If$detailsOpen == false && (abs(valueMember(event.position,"x") - self.transform.position.x) <= @self.dialWidth / 2 && abs(valueMember(event.position,"y") - self.transform.position.y) <= @self.dialWidth / 2)
Then
2Select Shared ImpulseFunction
magnitude
$impulseMagnitude + 5 * data("Impulse Settings","Shared","increment")
On Mouse Wheel · Down
WhenMouse WheelWheel direction: down
1If$detailsOpen == false && (abs(valueMember(event.position,"x") - self.transform.position.x) <= @self.dialWidth / 2 && abs(valueMember(event.position,"y") - self.transform.position.y) <= @self.dialWidth / 2)
Then
2Select Shared ImpulseFunction
magnitude
$impulseMagnitude - 5 * data("Impulse Settings","Shared","increment")
On Data Table Changed · Impulse Settings
WhenData Table ChangedData Table: Impulse Settings
1Set Rotation
Degrees
135 - $impulseMagnitude / data("Impulse Settings","Shared","maximum") * 270
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1If$detailsOpen
Then
2Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released
On Return Carts
WhenreturnCartsCustom Event
1Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released
When Return Carts Is Pressed
WhenCommand PressedCommand: Return Carts
1Switch Mode
Event
When the Left Mouse Button Is Pressed
Mode
Released

A.22 Calculate Cart Load (Function)

Built in Chapter 4, Load and measure.

FunctionCalculate Cart Load

Returns the base cart mass plus registered weights attached to cartNumber. A nonpositive base uses 1 kg. Callers decide whether to retain motion or start a new comparison.

PARAMETERS
NameTypeStarts at
cartNumberNumber1
baseMassNumber1
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
loadedMass
Value
baseMass
2IfloadedMass <= 0
Then
3Change Variable
Variable
loadedMass
Value
1
4For Each Row
Table
Workshop Weights
Variable Name
"load"
5Ifload.cart == cartNumber
Then
6Change Variable
Variable
loadedMass
Operator
+=
Value
load.mass
7Return
Value
loadedMass

A.23 Calibrate Recorded Gauge (Function)

Built in Chapter 4, Load and measure.

FunctionCalibrate Recorded Gauge

Chooses the scale for one real paired observation, or the selected starting impulse when no observation exists. This never changes motion or a measurement.

PARAMETERS
NameTypeStarts at
cartNumberNumber1
minimumRangeNumber0.5
headroomNumber1.25
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
observedSpeed
Value
0
2IfcartNumber == 1
Then
3If$pushBatch > 0
Then
4Change Variable
Variable
observedSpeed
Value
max(abs($blueBefore), abs($blueAfter))
5Otherwise
6Change Variable
Variable
observedSpeed
Value
$impulseMagnitude / max(0.001, $blueCart.transform.mass)
7Otherwise
8If$pushBatch > 0
Then
9Change Variable
Variable
observedSpeed
Value
max(abs($copperBefore), abs($copperAfter))
10Otherwise
11If$copperImpulseLinked
Then
12Change Variable
Variable
observedSpeed
Value
$impulseMagnitude / max(0.001, $copperCart.transform.mass)
13Otherwise
14Change Variable
Variable
observedSpeed
Value
$copperNextImpulse / max(0.001, $copperCart.transform.mass)
15Choose Gauge CalibrationFunction
Action Name
recordedScale
speed
observedSpeed
minimumRange
minimumRange
headroom
headroom
16Return
Value
recordedScale.value

A.24 Change Native Cart Load

Built in Chapter 4, Load and measure.

Logic ComponentChange Native Cart LoadAttach to: Blue Cart, Copper Cart

Changes this exact native cart mass and stops its affected comparison; the other cart and historical records stay unchanged.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
cartNumberNumberConstant1
baseMassNumberConstant1
On Cart Load Changed
WhencartLoadChangedCustom Event
1Calculate Cart LoadFunction
Action Name
changedMass
cartNumber
@self.cartNumber
baseMass
@self.baseMass
2Change Component Value
Component Value
self.transform.mass
Value
changedMass.value
3Set Velocity
X Velocity
0
Y Velocity
0
4If@self.cartNumber == 1
Then
5Change Variable
Variable
$blueReadingValid
Value
false
6Otherwise
7Change Variable
Variable
$copperReadingValid
Value
false

A.25 Choose Gauge Calibration (Function)

Built in Chapter 4, Load and measure.

FunctionChoose Gauge Calibration

Chooses a signed velocity scale from the readable 1, 2, 5 sequence, with headroom above the measured speed. All inputs and the result are m/s except the headroom ratio.

PARAMETERS
NameTypeStarts at
speedNumber0
minimumRangeNumber0.5
headroomNumber1.25
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
wantedRange
Value
max(0.5, minimumRange, abs(speed) * max(1, headroom))
2Declare Variable
Name
decade
Value
pow(10, floor(log(wantedRange) / log(10)))
3Declare Variable
Name
calibration
Value
decade
4Ifcalibration < wantedRange - 0.000000001
Then
5Change Variable
Variable
calibration
Value
decade * 2
6Ifcalibration < wantedRange - 0.000000001
Then
7Change Variable
Variable
calibration
Value
decade * 5
8Ifcalibration < wantedRange - 0.000000001
Then
9Change Variable
Variable
calibration
Value
decade * 10
10Return
Value
calibration

A.26 Choose Historical Ticket

Built in Chapter 4, Load and measure.

Logic ComponentChoose Historical TicketAttach to: Game Rules

T opens the oldest pinned reading, then cycles through the retained three. H closes the sheet; reopening Help returns to the latest page.

Attach toAny Object
When Inspect Ticket Is Pressed
WhenCommand PressedCommand: Inspect Ticket
1IfdataCount("Push Readings") > 0
Then
2Declare Variable
Name
ticketIndex
Value
dataFind("Push Readings","batch",$inspectedPush) + 1
3IfticketIndex < max(0,dataCount("Push Readings") - 3) || ticketIndex >= dataCount("Push Readings")
Then
4Change Variable
Variable
ticketIndex
Value
max(0,dataCount("Push Readings") - 3)
5Inspect Recorded PushFunction
batch
data("Push Readings",ticketIndex,"batch")
On Data Table Changed · Push Readings
WhenData Table ChangedData Table: Push Readings
1Validate Inspected PushFunction
On Load:succeeded
Whenload:succeededCustom Event
1Validate Inspected PushFunction

A.27 Choose Next Weight

Built in Chapter 4, Load and measure.

Logic ComponentChoose Next WeightAttach to: Game Rules

N selects the next remaining generated weight in creation order using Workshop Weights, wrapping at the end. Destroy removes a weight from the list; Load restores it. An empty bench gives clear feedback.

Attach toAny Object
When Next Weight Is Pressed
WhenCommand PressedCommand: Next Weight
1Declare Variable
Name
nextNumber
Value
0
2Declare Variable
Name
firstNumber
Value
0
3For Each Row
Table
Workshop Weights
Variable Name
"weight"
4Declare Variable
Name
candidateNumber
Value
weight.number
5IffirstNumber == 0 || candidateNumber < firstNumber
Then
6Change Variable
Variable
firstNumber
Value
candidateNumber
7IfcandidateNumber > $selectedWeightNumber
Then
8IfnextNumber == 0 || candidateNumber < nextNumber
Then
9Change Variable
Variable
nextNumber
Value
candidateNumber
10IfnextNumber > 0
Then
11Change Variable
Variable
$selectedWeightNumber
Value
nextNumber
12Otherwise
13Change Variable
Variable
$selectedWeightNumber
Value
firstNumber
14IffirstNumber == 0
Then
15Change Variable
Variable
$pushStatus
Value
'No workshop weights remain.'

A.28 Drag Workshop Weight

Built in Chapter 4, Load and measure.

Logic ComponentDrag Workshop WeightAttach to: One Kilogram Weight, Two Kilogram Weight, Five Kilogram Weight

Grabs the exact weight with its pointer offset. A held weight leaves its old load; release chooses the nearest available seat, and interruptions restore the previous place.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
weightNumberNumber0
rackXNumber0
rackYNumber0
weightHeightNumber0
weightGrabOffsetXNumber0
weightGrabOffsetYNumber0
previousCartNumber0
previousSeatNumber0
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true && dataFind("Workshop Weights","cart",-1) < 0 && ($blueCart.count == 0 || $blueCart.collider.fixed == false) && ($copperCart.count == 0 || $copperCart.collider.fixed == false)
Then
2Change Variable
Variable
previousCart
Value
data("Workshop Weights","Weight " + self.weightNumber,"cart")
3Change Variable
Variable
previousSeat
Value
data("Workshop Weights","Weight " + self.weightNumber,"seat")
4Declare Variable
Name
startX
Value
self.transform.position.x
5Declare Variable
Name
startY
Value
self.transform.position.y
6Transfer Workshop WeightFunction
Action Name
transferWorkshopWeightResult
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
0
7Set Data Cell
Table
Workshop Weights
Row
"Weight " + self.weightNumber
Column
"cart"
Value
-1
8Set Position
X
startX
Y
startY
9Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Holding
While the Left Mouse Button Is Held
WhenMouse HeldMouse button: left
ModeReleased (Starting Mode)
(no Actions)
While the Left Mouse Button Is Held
WhenMouse HeldMouse button: left
ModeHolding
1Set Position
X
clamp(valueMember(event.position,"x") - self.weightGrabOffsetX,.6,23.4)
Y
clamp(valueMember(event.position,"y") - self.weightGrabOffsetY,.6,15.4)
When the Left Mouse Button Is Released
WhenMouse ReleaseMouse button: left
1Ifdata("Workshop Weights","Weight " + self.weightNumber,"cart") == -1
Then
2Declare Variable
Name
dropCart
Value
0
3Declare Variable
Name
dropSeat
Value
0
4If$blueCart.count == 1 && abs(valueMember(event.position,"x") - $blueCart.transform.position.x) < data("Cart Load Settings","cart","dropHalfWidth") && abs(valueMember(event.position,"y") - $blueCart.transform.position.y - data("Cart Load Settings","cart","dropRise")) < data("Cart Load Settings","cart","dropHalfHeight")
Then
5Change Variable
Variable
dropCart
Value
1
6Change Variable
Variable
dropSeat
Value
clamp(round((valueMember(event.position,"x") - $blueCart.transform.position.x - data("Cart Load Settings","cart","firstSeatX")) / data("Cart Load Settings","cart","spacing")) + 1,1,data("Cart Load Settings","cart","capacity"))
7Otherwise
8If$copperCart.count == 1 && abs(valueMember(event.position,"x") - $copperCart.transform.position.x) < data("Cart Load Settings","cart","dropHalfWidth") && abs(valueMember(event.position,"y") - $copperCart.transform.position.y - data("Cart Load Settings","cart","dropRise")) < data("Cart Load Settings","cart","dropHalfHeight")
Then
9Change Variable
Variable
dropCart
Value
2
10Change Variable
Variable
dropSeat
Value
clamp(round((valueMember(event.position,"x") - $copperCart.transform.position.x - data("Cart Load Settings","cart","firstSeatX")) / data("Cart Load Settings","cart","spacing")) + 1,1,data("Cart Load Settings","cart","capacity"))
11Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
dropCart
preferredSeat
dropSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
Yes
12Change Variable
Variable
$selectedWeightNumber
Value
self.weightNumber
13Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Focus Lost
WhenFocus Lost
1Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
self.previousCart
preferredSeat
self.previousSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
No
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Touch Cancelled
WhenTouch Cancelled
1Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
self.previousCart
preferredSeat
self.previousSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
No
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Load:succeeded
Whenload:succeededCustom Event
1Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
self.previousCart
preferredSeat
self.previousSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
No
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
When Return Carts Is Pressed
WhenCommand PressedCommand: Return Carts
1Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
self.previousCart
preferredSeat
self.previousSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
No
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Return Carts
WhenreturnCartsCustom Event
1Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
self.previousCart
preferredSeat
self.previousSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
No
2Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1If$detailsOpen
Then
2Place Weight From HandFunction
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
self.previousCart
preferredSeat
self.previousSeat
previousCart
self.previousCart
previousSeat
self.previousSeat
playClick
No
3Switch Mode
Event
While the Left Mouse Button Is Held
Mode
Released

A.29 Follow Native Velocity

Built in Chapter 4, Load and measure.

Logic ComponentFollow Native VelocityAttach to: Blue Live Gauge, Copper Live Gauge

Shows one exact workshop cart's signed native velocity on its stationary calibrated instrument face. Native Text shows live speed and scale values; only its named needle rotates. Reads continuously because native velocity changes continuously.

Attach toAny Object
COMPONENTS
self.spriteSprite
SHARED VARIABLES
NameTypeKindStarting Value
cartNumberNumberConstant1
minimumRangeNumberConstant10
needleSweepNumberConstant65
scaleHeadroomNumberConstant1.25
PER INSTANCE VARIABLES
NameTypeStarting Value
gaugeRangeNumber0.5
Every Step
WhenStep
1If@self.cartNumber == 1
Then
2Update Velocity GaugeFunction
Action Name
followBlueCalibration
cart
$blueCart
gauge
self
oldRange
self.gaugeRange
minimumRange
@self.minimumRange
needleSweep
@self.needleSweep
headroom
@self.scaleHeadroom
3Change Variable
Variable
gaugeRange
Value
followBlueCalibration.value
4Otherwise
5Update Velocity GaugeFunction
Action Name
followCopperCalibration
cart
$copperCart
gauge
self
oldRange
self.gaugeRange
minimumRange
@self.minimumRange
needleSweep
@self.needleSweep
headroom
@self.scaleHeadroom
6Change Variable
Variable
gaugeRange
Value
followCopperCalibration.value
When Created
WhenCreate
1Calibrate Recorded GaugeFunction
Action Name
calibrateOpeningScale
cartNumber
@self.cartNumber
minimumRange
@self.minimumRange
headroom
@self.scaleHeadroom
2Change Variable
Variable
gaugeRange
Value
calibrateOpeningScale.value
On Variable Changed · Push Batch
WhenVariable ChangedGlobal Variable: pushBatch
1Calibrate Recorded GaugeFunction
Action Name
calibratePushScale
cartNumber
@self.cartNumber
minimumRange
@self.minimumRange
headroom
@self.scaleHeadroom
2Change Variable
Variable
gaugeRange
Value
calibratePushScale.value

A.30 Inspect Recorded Push (Function)

Built in Chapter 4, Load and measure.

FunctionInspect Recorded Push

Opens the retained push identified by its batch number. Missing or trimmed rows leave the current sheet unchanged.

PARAMETERS
NameTypeStarts at
batchNumber0
ACTIONS
1Check Data Row Exists
Action Name
recordedPush
Table
Push Readings
Row
"Push " + batch
2IfrecordedPush.value
Then
3Change Variable
Variable
$inspectedPush
Value
batch
4Change Variable
Variable
$detailsOpen
Value
true

A.31 Move Selected Weight

Built in Chapter 4, Load and measure.

Logic ComponentMove Selected WeightAttach to: One Kilogram Weight, Two Kilogram Weight, Five Kilogram Weight

Moves this weight only when its saved number is selected. Keys 1 and 2 choose a cart; Delete returns it to the rack.

Attach toAny Object
COMPONENTS
self.spriteSprite
PER INSTANCE VARIABLES
NameTypeStarting Value
weightNumberNumber0
pressSelectedBooleanNo
rackXNumber0
rackYNumber0
weightHeightNumber0
When Load Blue Is Pressed
WhenCommand PressedCommand: Load Blue
1If$selectedWeightNumber > 0 && $selectedWeightNumber == self.weightNumber && dataFind("Workshop Weights","cart",-1) < 0
Then
2Transfer Workshop WeightFunction
Action Name
blueWeightRequest1
weight
self
number
self.weightNumber
destination
1
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
3Play Workshop ClickFunction
accepted
blueWeightRequest1.value
When Load Copper Is Pressed
WhenCommand PressedCommand: Load Copper
1If$selectedWeightNumber > 0 && $selectedWeightNumber == self.weightNumber && dataFind("Workshop Weights","cart",-1) < 0
Then
2Transfer Workshop WeightFunction
Action Name
copperWeightRequest2
weight
self
number
self.weightNumber
destination
2
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
3Play Workshop ClickFunction
accepted
copperWeightRequest2.value
When Rack Weight Is Pressed
WhenCommand PressedCommand: Return Weight
1If$selectedWeightNumber > 0 && $selectedWeightNumber == self.weightNumber && dataFind("Workshop Weights","cart",-1) < 0
Then
2Transfer Workshop WeightFunction
Action Name
rackWeightRequest3
weight
self
number
self.weightNumber
destination
0
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
3Play Workshop ClickFunction
accepted
rackWeightRequest3.value
When Destroyed
WhenDestroy
1Declare Variable
Name
oldCart
Value
data("Workshop Weights","Weight " + self.weightNumber,"cart")
2Control Data Row
Action Name
addedRow
Operation
Remove
Table
Workshop Weights
Row
"Weight " + self.weightNumber
3IfoldCart == 1
Then
4Trigger Custom Event on Object
Applies to
$blueCart
Custom Event
cartLoadChanged
5IfoldCart == 2
Then
6Trigger Custom Event on Object
Applies to
$copperCart
Custom Event
cartLoadChanged

A.32 Place Weight From Hand (Function)

Built in Chapter 4, Load and measure.

FunctionPlace Weight From Hand

Places a released weight at its requested seat or restores its previous place. Only a deliberate drop opts into the quiet click; interruption recovery is silent.

PARAMETERS
NameTypeStarts at
weightInstance Setundefined
numberNumber0
destinationNumber0
rackXNumber0
rackYNumber0
heightNumber0
preferredSeatNumber0
previousCartNumber0
previousSeatNumber0
playClickBooleanNo
ACTIONS
1Ifdata("Workshop Weights","Weight " + number,"cart") == -1
Then
2Transfer Workshop WeightFunction
Action Name
placedWeightRequest1
weight
weight
number
number
destination
destination
rackX
rackX
rackY
rackY
height
height
preferredSeat
preferredSeat
3Play Workshop ClickFunction
accepted
placedWeightRequest1.value && playClick
4Ifdata("Workshop Weights","Weight " + number,"cart") == -1
Then
5Transfer Workshop WeightFunction
Action Name
placedWeightRequest2
weight
weight
number
number
destination
previousCart
rackX
rackX
rackY
rackY
height
height
preferredSeat
previousSeat
6Play Workshop ClickFunction
accepted
placedWeightRequest2.value && playClick
7Ifdata("Workshop Weights","Weight " + number,"cart") == -1
Then
8Transfer Workshop WeightFunction
Action Name
rackWeightRequest3
weight
weight
number
number
destination
0
rackX
rackX
rackY
rackY
height
height
preferredSeat
0
9Play Workshop ClickFunction
accepted
rackWeightRequest3.value && playClick

A.33 Prepare Reading Tickets

Built in Chapter 4, Load and measure.

Logic ComponentPrepare Reading TicketsAttach to: Game Rules

Creates the three regularly spaced paper controls once. Native Load restores them and their saved slot identities without creating more.

Attach toAny Object
When Created
WhenCreate
1Repeat3times
Each time
2Change Variable
Variable
$preparingTicketSlot
Value
local.index + 1
3Create Instance
Object to Create
data("Reading Ticket Settings","papers","object")
X
data("Reading Ticket Settings","papers","firstX") + data("Reading Ticket Settings","papers","spacing") * local.index
Y
data("Reading Ticket Settings","papers","paperY")

A.34 Prepare Workshop Weights

Built in Chapter 4, Load and measure.

Logic ComponentPrepare Workshop WeightsAttach to: Game Rules

Starts the workshop weight pattern once after the placed exact carts have registered. Saved generated weights are restored by native Load, so Load never generates a second set.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
stackCopyLimitNumberConstant4
When Created
WhenCreate
1Start Recurring Timer
Timer Name
"weightPatternReady"
Repeat Every (s)
0.02
Ring Once
Yes
On the Weight Pattern Ready Timer
WhenRecurring TimerTimer name: weightPatternReady
1Check Data Row Exists
Action Name
seatSettings
Table
Cart Load Settings
Row
"cart"
2IfseatSettings.value
Then
3Set Data Cell
Table
Cart Load Settings
Row
"cart"
Column
"capacity"
Value
round(data("Cart Load Settings","cart","capacity"))
4Ifdata("Cart Load Settings","cart","capacity") < 1
Then
5Set Data Cell
Table
Cart Load Settings
Row
"cart"
Column
"capacity"
Value
1
6Ifdata("Cart Load Settings","cart","capacity") > 4
Then
7Set Data Cell
Table
Cart Load Settings
Row
"cart"
Column
"capacity"
Value
4
8Otherwise
9Control Data Row
Action Name
addedRow
Table
Cart Load Settings
Row
"cart"
Values > capacity
4
Values > firstSeatX
-1.125
Values > spacing
0.75
Values > cartTop
0.35
Values > dropHalfWidth
2.1
Values > dropHalfHeight
1.3
Values > dropRise
0.7
10Declare Variable
Name
seatsUsed
Value
0
11For Each Row
Table
Weight Pattern
Variable Name
"denomination"
12Declare Variable
Name
copyCount
Value
round(denomination.copies)
13IfcopyCount < 0
Then
14Change Variable
Variable
copyCount
Value
0
15IfcopyCount > @self.stackCopyLimit
Then
16Change Variable
Variable
copyCount
Value
@self.stackCopyLimit
17Set Data Cell
Table
Weight Pattern
Row
denomination.index
Column
"copies"
Value
copyCount
18Declare Variable
Name
placedCount
Value
0
19Declare Variable
Name
loadCount
Value
round(denomination.initialCopper)
20IfloadCount < 0
Then
21Change Variable
Variable
loadCount
Value
0
22IfloadCount > copyCount
Then
23Change Variable
Variable
loadCount
Value
copyCount
24IfloadCount > data("Cart Load Settings","cart","capacity") - seatsUsed
Then
25Change Variable
Variable
loadCount
Value
data("Cart Load Settings","cart","capacity") - seatsUsed
26Ifdenomination.mass <= 0
Then
27Set Data Cell
Table
Weight Pattern
Row
denomination.index
Column
"mass"
Value
1
28Repeatdenomination.copiestimes
Each time
29Change Variable
Variable
$preparingWeightMass
Value
denomination.mass
30Change Variable
Variable
$preparingRackX
Value
denomination.rackX
31Change Variable
Variable
$preparingRackY
Value
denomination.rackY + (copyCount - 1 - local.index) * denomination.stackRise
32Change Variable
Variable
$preparingHeight
Value
denomination.height
33Create Instance
Object to Create
denomination.object
X
denomination.rackX
Y
denomination.rackY + (copyCount - 1 - local.index) * denomination.stackRise
Variable Name
newWeight
34Check Exists
Action Name
weightExists
Applies to
newWeight
35IfweightExists.value && local.index < loadCount && $copperCart.count == 1
Then
36Attach to Parent
Applies to
newWeight
Parent
$copperCart
Keep World Position
No
Local X
data("Cart Load Settings","cart","firstSeatX") + seatsUsed * data("Cart Load Settings","cart","spacing")
Local Y
data("Cart Load Settings","cart","cartTop") + denomination.height / 2
Destroy with Parent
No
37Set Data Cell
Table
Workshop Weights
Row
"Weight " + $weightCount
Column
"cart"
Value
2
38Set Data Cell
Table
Workshop Weights
Row
"Weight " + $weightCount
Column
"seat"
Value
seatsUsed + 1
39Change Variable
Variable
seatsUsed
Operator
+=
Value
1
40Change Variable
Variable
placedCount
Operator
+=
Value
1
41IfweightExists.value == false
Then
42Change Variable
Variable
$pushStatus
Value
'A weight is unavailable; check Weight Pattern.'
43Set Data Cell
Table
Weight Pattern
Row
denomination.index
Column
"initialCopper"
Value
placedCount
44Trigger Custom Event
Custom Event
weightsPrepared

A.35 Read Latest Print

Built in Chapter 4, Load and measure.

Logic ComponentRead Latest PrintAttach to: Printer Reading

Prints the latest retained numerical measurement on the printer paper; an exact press opens its optional enlarged reading.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When Created
WhenCreate
1Set Visible
Visible
$detailsOpen == false && dataCount("Push Readings") > 0
On Variable Changed · Push Batch
WhenVariable ChangedGlobal Variable: pushBatch
1Set Visible
Visible
$detailsOpen == false && dataCount("Push Readings") > 0
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen == false && dataCount("Push Readings") > 0
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen == false && dataCount("Push Readings") > 0
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen == false && dataCount("Push Readings") > 0
Then
3Inspect Recorded PushFunction
batch
data("Push Readings",dataCount("Push Readings") - 1,"batch")
On Data Table Changed · Push Readings
WhenData Table ChangedData Table: Push Readings
1Set Visible
Visible
$detailsOpen == false && dataCount("Push Readings") > 0

A.36 Read Pinned Ticket

Built in Chapter 4, Load and measure.

Logic ComponentRead Pinned TicketAttach to: Reading Ticket

Prints one of the three newest immutable numerical measurements on its pinned paper; an exact press opens its optional enlarged reading.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
ticketSlotNumber0
pressSelectedBooleanNo
When Created
WhenCreate
1Change Variable
Variable
ticketSlot
Value
$preparingTicketSlot
2Set Z Order
Depth Amount
25
3Set Visible
Visible
$detailsOpen == false && self.ticketSlot <= dataCount("Push Readings")
On Variable Changed · Push Batch
WhenVariable ChangedGlobal Variable: pushBatch
1Set Visible
Visible
$detailsOpen == false && self.ticketSlot <= dataCount("Push Readings")
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen == false && self.ticketSlot <= dataCount("Push Readings")
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen == false && self.ticketSlot <= dataCount("Push Readings")
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen == false && self.ticketSlot <= dataCount("Push Readings")
Then
3Inspect Recorded PushFunction
batch
data("Push Readings",max(0,dataCount("Push Readings") - 3) + self.ticketSlot - 1,"batch")
On Data Table Changed · Push Readings
WhenData Table ChangedData Table: Push Readings
1Set Visible
Visible
$detailsOpen == false && self.ticketSlot <= dataCount("Push Readings")

A.37 Record Pair Reading (Function)

Built in Chapter 4, Load and measure.

FunctionRecord Pair Reading

Records one complete pair measurement, trims the oldest excess rows and reports how many are kept. Project Global readingCapacity (default 40) takes effect on the next accepted push.

ACTIONS
1If$readingCapacity < 1
Then
2Change Variable
Variable
$readingCapacity
Value
1
3Change Variable
Variable
$readingCapacity
Value
round($readingCapacity)
4Control Data Row
Action Name
addedRow
Table
Push Readings
Row
"Push " + $pushBatch
Values > batch
$pushBatch
Values > blueMass
$blueMass
Values > blueAppliedImpulse
$blueAppliedImpulse
Values > blueBefore
$blueBefore
Values > blueAfter
$blueAfter
Values > blueDelta
$blueDelta
Values > copperMass
$copperMass
Values > copperAppliedImpulse
$copperAppliedImpulse
Values > copperBefore
$copperBefore
Values > copperAfter
$copperAfter
Values > copperDelta
$copperDelta
5IfdataCount("Push Readings") > $readingCapacity
Then
6RepeatdataCount("Push Readings") - $readingCapacitytimes
Each time
7Control Data Row
Action Name
addedRow2
Operation
Remove
Table
Push Readings
Row
0
8Change Variable
Variable
$pushStatus
Value
"Impulse " + $pushBatch + " recorded (" + dataCount("Push Readings") + " kept)."
9Validate Inspected PushFunction

A.38 Select Workshop Weight

Built in Chapter 4, Load and measure.

Logic ComponentSelect Workshop WeightAttach to: One Kilogram Weight, Two Kilogram Weight, Five Kilogram Weight

Selects the exact pressed generated weight and shows the same saved selection on the bench. Selection does not change cart mass, motion or readings.

Attach toAny Object
COMPONENTS
self.spriteSprite
PER INSTANCE VARIABLES
NameTypeStarting Value
weightNumberNumber0
pressSelectedBooleanNo
rackXNumber0
rackYNumber0
weightHeightNumber0
When Created
WhenCreate
1Change Variable
Variable
$weightCount
Operator
+=
Value
1
2Change Variable
Variable
weightNumber
Value
$weightCount
3Control Data Row
Action Name
addedRow
Table
Workshop Weights
Row
"Weight " + self.weightNumber
Values > number
self.weightNumber
Values > cart
0
Values > seat
0
Values > mass
$preparingWeightMass
4Change Variable
Variable
rackX
Value
$preparingRackX
5Change Variable
Variable
rackY
Value
$preparingRackY
6Change Variable
Variable
weightHeight
Value
$preparingHeight
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2Change Variable
Variable
$selectedWeightNumber
Value
self.weightNumber
On Variable Changed · Selected Weight Number
WhenVariable ChangedGlobal Variable: selectedWeightNumber
1Show Weight SelectionFunction
weight
self
number
self.weightNumber
mass
data("Workshop Weights","Weight " + self.weightNumber,"mass")
On Load:succeeded
Whenload:succeededCustom Event
1Show Weight SelectionFunction
weight
self
number
self.weightNumber
mass
data("Workshop Weights","Weight " + self.weightNumber,"mass")
When Destroyed
WhenDestroy
1If$selectedWeightNumber == self.weightNumber
Then
2Change Variable
Variable
$selectedWeightNumber
Value
0
3Change Variable
Variable
$pushStatus
Value
'Selected weight removed. N selects another weight.'

A.39 Set Starting Cart Load

Built in Chapter 4, Load and measure.

Logic ComponentSet Starting Cart LoadAttach to: Blue Cart, Copper Cart

Derives native mass from baseMass and the saved live load arrangement at opening and after Load; keeps restored velocity.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
cartNumberNumberConstant1
baseMassNumberConstant1
On Weights Prepared
WhenweightsPreparedCustom Event
1Calculate Cart LoadFunction
Action Name
startingMass
cartNumber
@self.cartNumber
baseMass
@self.baseMass
2Change Component Value
Component Value
self.transform.mass
Value
startingMass.value
On Load:succeeded
Whenload:succeededCustom Event
1Calculate Cart LoadFunction
Action Name
restoredMass
cartNumber
@self.cartNumber
baseMass
@self.baseMass
2Change Component Value
Component Value
self.transform.mass
Value
restoredMass.value

A.40 Show Reading Page

Built in Chapter 4, Load and measure.

Logic ComponentShow Reading PageAttach to: Push Status, Workshop Instructions, Historical Blue Reading, Historical Copper Reading, History Note, Store Copper Label, Link Both Label, Setup Page Label

Shows a latest-page or historical-page caption inside the optional reading sheet. historyPage chooses the historical page.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
historyPageBooleanConstantNo
When Created
WhenCreate
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)
On Variable Changed · Inspected Push
WhenVariable ChangedGlobal Variable: inspectedPush
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)

A.41 Show Weight Selection (Function)

Built in Chapter 4, Load and measure.

FunctionShow Weight Selection

Shows one saved weight selection with a tunable Sprite tint and native status caption.

PARAMETERS
NameTypeStarts at
weightObject
Compatibility ModeStructural
Required Components
Slot Nametransform
Component TypeTransform
Slot Namesprite
Component TypeSprite
numberNumber0
massNumber1
selectedTintColor#8fdcff
ACTIONS
1If$selectedWeightNumber == number && number > 0
Then
2Change Component Value
Applies to
weight
Component Value
weight.sprite.tint
Value
selectedTint
3Change Variable
Variable
$pushStatus
Value
"Selected " + mass + " kg weight " + number + "."
4Otherwise
5Change Component Value
Applies to
weight
Component Value
weight.sprite.tint
Value
"#ffffff"

A.42 Transfer Workshop Weight (Function)

Built in Chapter 4, Load and measure.

FunctionTransfer Workshop Weight

Moves the exact weight to its requested cart or original rack place. A free preferred seat wins; otherwise the first free seat is used. Full or missing destinations leave its current place unchanged. Returns whether the requested placement was accepted; callers choose the feedback.

PARAMETERS
NameTypeStarts at
weightInstance Setundefined
numberNumber0
destinationNumber0
rackXNumber0
rackYNumber0
heightNumber0
preferredSeatNumber0
RETURN TYPEBoolean
ACTIONS
1Declare Variable
Name
accepted
Type
Boolean
Value
false
2Declare Variable
Name
oldCart
Value
data("Workshop Weights","Weight " + number,"cart")
3Declare Variable
Name
freeSeat
Value
0
4Declare Variable
Name
seatCount
Value
round(data("Cart Load Settings","cart","capacity"))
5Ifdestination == 0
Then
6Change Variable
Variable
freeSeat
Value
-1
7Otherwise
8RepeatseatCounttimes
Each time
9Declare Variable
Name
candidateSeat
Value
local.index + 1
10Declare Variable
Name
occupied
Value
0
11For Each Row
Table
Workshop Weights
Variable Name
"occupant"
12Ifoccupant.cart == destination && occupant.seat == candidateSeat
Then
13Change Variable
Variable
occupied
Value
1
14Ifoccupied == 0 && (freeSeat == 0 || candidateSeat == preferredSeat)
Then
15Change Variable
Variable
freeSeat
Value
candidateSeat
16IfoldCart == destination
Then
17Change Variable
Variable
$pushStatus
Value
'That weight is already there.'
18Change Variable
Variable
accepted
Value
true
19Otherwise
20IffreeSeat != 0 && (destination == 0 || (destination == 1 && $blueCart.count == 1) || (destination == 2 && $copperCart.count == 1))
Then
21Detach from Parent
Applies to
weight
22Ifdestination == 0
Then
23Set Position
Applies to
weight
X
rackX
Y
rackY
24Otherwise
25Ifdestination == 1
Then
26Attach to Parent
Applies to
weight
Parent
$blueCart
Keep World Position
false
Local X
data("Cart Load Settings","cart","firstSeatX") + (freeSeat - 1) * data("Cart Load Settings","cart","spacing")
Local Y
data("Cart Load Settings","cart","cartTop") + height / 2
Destroy with Parent
false
27Otherwise
28Attach to Parent
Applies to
weight
Parent
$copperCart
Keep World Position
false
Local X
data("Cart Load Settings","cart","firstSeatX") + (freeSeat - 1) * data("Cart Load Settings","cart","spacing")
Local Y
data("Cart Load Settings","cart","cartTop") + height / 2
Destroy with Parent
false
29Set Data Cell
Table
Workshop Weights
Row
"Weight " + number
Column
"cart"
Value
destination
30Ifdestination == 0
Then
31Set Data Cell
Table
Workshop Weights
Row
"Weight " + number
Column
"seat"
Value
0
32Otherwise
33Set Data Cell
Table
Workshop Weights
Row
"Weight " + number
Column
"seat"
Value
freeSeat
34IfoldCart == 1
Then
35Trigger Custom Event on Object
Applies to
$blueCart
Custom Event
cartLoadChanged
36IfoldCart == 2
Then
37Trigger Custom Event on Object
Applies to
$copperCart
Custom Event
cartLoadChanged
38Ifdestination == 1
Then
39Trigger Custom Event on Object
Applies to
$blueCart
Custom Event
cartLoadChanged
40Ifdestination == 2
Then
41Trigger Custom Event on Object
Applies to
$copperCart
Custom Event
cartLoadChanged
42Change Variable
Variable
$pushStatus
Value
'Load changed. Push for a fresh comparison.'
43Change Variable
Variable
accepted
Value
true
44Otherwise
45Change Variable
Variable
$pushStatus
Value
'That cart is full or unavailable.'
46Return
Value
accepted

A.43 Update Velocity Gauge (Function)

Built in Chapter 4, Load and measure.

FunctionUpdate Velocity Gauge

Updates one live velocity instrument from an exact native cart, preserving historical readings. Calibration and speed are m/s; needleSweep is degrees.

PARAMETERS
NameTypeStarts at
cartInstance Setundefined
gaugeObject
Compatibility ModeStructural
Required Components
Slot Nametransform
Component TypeTransform
Slot Namesprite
Component TypeSprite
oldRangeNumber10
minimumRangeNumber10
needleSweepNumber10
headroomNumber1.25
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
calibration
Value
oldRange
2Check Exists
Action Name
cartExists
Applies to
cart
3IfcartExists.value
Then
4Set Visible
Applies to
gauge
Visible
$detailsOpen == false
5Ifcalibration < minimumRange
Then
6Change Variable
Variable
calibration
Value
minimumRange
7Ifcalibration <= 0
Then
8Change Variable
Variable
calibration
Value
1
9Ifabs(param:cart.transform.velocity.x) > calibration
Then
10Choose Gauge CalibrationFunction
Action Name
expandedScale
speed
param:cart.transform.velocity.x
minimumRange
minimumRange
headroom
headroom
11Change Variable
Variable
calibration
Value
expandedScale.value
12Change Component Value
Component Value
gauge.sprite.transform.rotation.z
Value
-param:cart.transform.velocity.x / calibration * needleSweep
13Otherwise
14Set Visible
Applies to
gauge
Visible
false
15Return
Value
calibration

A.44 Validate Inspected Push (Function)

Built in Chapter 4, Load and measure.

FunctionValidate Inspected Push

Returns to the latest reading if the inspected historical row was removed or trimmed.

ACTIONS
1If$inspectedPush > 0
Then
2Check Data Row Exists
Action Name
inspectedRow
Table
Push Readings
Row
"Push " + $inspectedPush
3IfinspectedRow.value == false
Then
4Change Variable
Variable
$inspectedPush
Value
0

A.45 Apply Starting Setup (Function)

Built in Chapter 5, Compare and remix.

FunctionApply Starting Setup

Validates every imported field before returning from rest and restoring arrangement/controls. Values must survive numeric staging unchanged; incomplete or incompatible files leave the apparatus unchanged.

ACTIONS
1Set Data Cell
Table
Starting Setup Values
Row
"weightCount"
Column
"maximum"
Value
dataCount("Workshop Weights")
2Change Variable
Variable
$setupEmptyFields
Value
1
3Execute Script
Script
Check Setup Fields
4Declare Variable
Name
setupValid
Type
Boolean
Value
$setupEmptyFields == 0
5For Each Row
Table
Starting Setup Values
Variable Name
"setupField"
6Load Persistent Value
Action Name
setupValue
Key
"pushSetup." + setupField.name
Default
-999
7Declare Variable
Name
fieldValue
Value
setupValue.value
8Set Data Cell
Table
Starting Setup Values
Row
setupField.name
Column
"value"
Value
fieldValue
9IfsetupValue.value != fieldValue || (fieldValue < setupField.minimum || fieldValue > setupField.maximum)
Then
10Change Variable
Variable
setupValid
Value
false
11Ifdata("Starting Setup Values","weightCount","value") != dataCount("Workshop Weights") || data("Starting Setup Values","maximum","value") != data("Impulse Settings","Shared","maximum") || data("Starting Setup Values","increment","value") != data("Impulse Settings","Shared","increment") || data("Starting Setup Values","capacity","value") != data("Cart Load Settings","cart","capacity")
Then
12Change Variable
Variable
setupValid
Value
false
13If(data("Starting Setup Values","impulseDirection","value") != -1 && data("Starting Setup Values","impulseDirection","value") != 1) || (data("Starting Setup Values","copperLinked","value") != 0 && data("Starting Setup Values","copperLinked","value") != 1) || data("Starting Setup Values","impulseMagnitude","value") > data("Starting Setup Values","maximum","value") || abs(data("Starting Setup Values","copperImpulse","value")) > data("Starting Setup Values","maximum","value")
Then
14Change Variable
Variable
setupValid
Value
false
15Reset Data Table
Table
Starting Weight Setup
16For Each Row
Table
Workshop Weights
Variable Name
"openWeight"
17Control Data Row
Action Name
addedRow
Table
Starting Weight Setup
Row
openWeight.name
Values > number
openWeight.number
18Load Persistent Value
Action Name
loadedcart
Key
"pushSetup.weight." + openWeight.number + ".cart"
Default
-999
19Set Data Cell
Table
Starting Weight Setup
Row
openWeight.name
Column
"cart"
Value
loadedcart.value
20Ifloadedcart.value != data("Starting Weight Setup",openWeight.name,"cart")
Then
21Change Variable
Variable
setupValid
Value
false
22Load Persistent Value
Action Name
loadedseat
Key
"pushSetup.weight." + openWeight.number + ".seat"
Default
-999
23Set Data Cell
Table
Starting Weight Setup
Row
openWeight.name
Column
"seat"
Value
loadedseat.value
24Ifloadedseat.value != data("Starting Weight Setup",openWeight.name,"seat")
Then
25Change Variable
Variable
setupValid
Value
false
26Load Persistent Value
Action Name
loadedmass
Key
"pushSetup.weight." + openWeight.number + ".mass"
Default
-999
27Set Data Cell
Table
Starting Weight Setup
Row
openWeight.name
Column
"mass"
Value
loadedmass.value
28Ifloadedmass.value != data("Starting Weight Setup",openWeight.name,"mass")
Then
29Change Variable
Variable
setupValid
Value
false
30For Each Row
Table
Starting Weight Setup
Variable Name
"checkWeight"
31Declare Variable
Name
cart
Value
checkWeight.cart
32Declare Variable
Name
seat
Value
checkWeight.seat
33Ifcart != round(cart) || cart < 0 || cart > 2 || seat != round(seat) || (cart == 0 && seat != 0) || (cart > 0 && (seat < 1 || seat > data("Starting Setup Values","capacity","value"))) || checkWeight.mass != data("Workshop Weights",checkWeight.name,"mass")
Then
34Change Variable
Variable
setupValid
Value
false
35Declare Variable
Name
seatUses
Value
0
36For Each Row
Table
Starting Weight Setup
Variable Name
"otherWeight"
37Ifcart > 0 && otherWeight.cart == cart && otherWeight.seat == seat
Then
38Change Variable
Variable
seatUses
Operator
+=
Value
1
39Ifcart > 0 && seatUses != 1
Then
40Change Variable
Variable
setupValid
Value
false
41IfsetupValid && $blueCart.count == 1 && $copperCart.count == 1
Then
42Reset Workshop ExperimentFunction
43Trigger Custom Event
Custom Event
setupWeightsToRack
44Trigger Custom Event
Custom Event
setupWeightsToSeats
45Trigger Custom Event
Custom Event
setupCartPosition
46Change Variable
Variable
$impulseMagnitude
Value
data("Starting Setup Values","impulseMagnitude","value")
47Change Variable
Variable
$impulseDirection
Value
data("Starting Setup Values","impulseDirection","value")
48Change Variable
Variable
$copperNextImpulse
Value
data("Starting Setup Values","copperImpulse","value")
49Change Variable
Variable
$copperImpulseLinked
Value
data("Starting Setup Values","copperLinked","value") == 1
50Change Variable
Variable
$setupStatus
Value
'Setup opened from rest. Previous observations cleared.'
51Otherwise
52Change Variable
Variable
$setupStatus
Value
'Setup does not match this project or is incomplete. Nothing changed.'

A.46 Choose Copper Impulse

Built in Chapter 5, Compare and remix.

Logic ComponentChoose Copper ImpulseAttach to: Game Rules

V stores the selected dial and lever value for Copper; L links both carts to the dial again. These controls change only the next push.

Attach toAny Object
When Store Copper Impulse Is Pressed
WhenCommand PressedCommand: Store Copper Impulse
1Store Copper ImpulseFunction
When Link Workshop Impulses Is Pressed
WhenCommand PressedCommand: Link Workshop Impulses
1Link Workshop ImpulsesFunction

A.47 Choose Workshop Goal

Built in Chapter 5, Compare and remix.

Logic ComponentChoose Workshop GoalAttach to: Game Rules

C chooses Match, B chooses Brake, G chooses Target, X clears the goal and O opens its optional page. Each recorded push checks the selected task before the next push.

Attach toAny Object
When Goal Match Is Pressed
WhenCommand PressedCommand: Match Goal
1Start Workshop GoalFunction
goal
"Match"
When Goal Brake Is Pressed
WhenCommand PressedCommand: Brake Goal
1Start Workshop GoalFunction
goal
"Brake"
When Goal Target Is Pressed
WhenCommand PressedCommand: Target Goal
1Start Workshop GoalFunction
goal
"Target"
When Goal Clear Is Pressed
WhenCommand PressedCommand: Clear Goal
1Clear Workshop GoalFunction
When Goal Page Is Pressed
WhenCommand PressedCommand: Open Goals
1Open Workshop GoalsFunction

A.48 Clear Workshop Goal (Function)

Built in Chapter 5, Compare and remix.

FunctionClear Workshop Goal

Ends optional observation without changing settings, measurements or motion.

ACTIONS
1Change Variable
Variable
$workshopGoal
Value
""
2Change Variable
Variable
$goalResult
Value
""
3Change Variable
Variable
$goalStartBatch
Value
$pushBatch

A.49 Complete Workshop Goal (Function)

Built in Chapter 5, Compare and remix.

FunctionComplete Workshop Goal

Keeps the selected optional goal complete while later exploration continues.

ACTIONS
1Change Variable
Variable
$goalResult
Value
'Complete'

A.50 Evaluate Workshop Goal (Function)

Built in Chapter 5, Compare and remix.

FunctionEvaluate Workshop Goal

Reads one fresh paired impulse snapshot. Match compares velocity changes, Brake requires an opposing impulse, and Target uses the immediate signed after-speed. Later native motion cannot create a success.

ACTIONS
1If$goalResult == "Waiting" && $pushBatch > $goalStartBatch && $blueReadingValid && $copperReadingValid
Then
2If$workshopGoal == "Match"
Then
3Ifmax($blueMass,$copperMass) / min($blueMass,$copperMass) >= data("Goal Settings","Rules","minimumRatio") && abs($blueDelta - $copperDelta) <= data("Goal Settings","Rules","changeTolerance") && abs($blueDelta) >= data("Goal Settings","Rules","minimumChange")
Then
4Complete Workshop GoalFunction
5If$workshopGoal == "Brake"
Then
6If(abs($blueBefore) >= data("Goal Settings","Rules","minimumBefore") && abs($blueAfter) <= data("Goal Settings","Rules","stopTolerance") && $blueAppliedImpulse * $blueBefore < 0) || (abs($copperBefore) >= data("Goal Settings","Rules","minimumBefore") && abs($copperAfter) <= data("Goal Settings","Rules","stopTolerance") && $copperAppliedImpulse * $copperBefore < 0)
Then
7Complete Workshop GoalFunction
8If$workshopGoal == "Target"
Then
9Ifabs($blueAfter - data("Goal Settings","Rules","targetVelocity")) <= data("Goal Settings","Rules","targetTolerance") || abs($copperAfter - data("Goal Settings","Rules","targetVelocity")) <= data("Goal Settings","Rules","targetTolerance")
Then
10Complete Workshop GoalFunction

A.52 Open Starting Setup (Function)

Built in Chapter 5, Compare and remix.

FunctionOpen Starting Setup

Asks for a portable setup. Missing or incompatible fields are refused before changing apparatus. The native file completion Event validates and applies it.

ACTIONS
1Save Persistent Value
Action Name
persistentWriteResult
Key
"pushSetup.version"
Value
-999
2Save Persistent Value
Action Name
persistentWriteResult2
Key
"pushSetup.weightCount"
Value
-999
3Save Persistent Value
Action Name
persistentWriteResult3
Key
"pushSetup.impulseMagnitude"
Value
-999
4Save Persistent Value
Action Name
persistentWriteResult4
Key
"pushSetup.impulseDirection"
Value
-999
5Save Persistent Value
Action Name
persistentWriteResult5
Key
"pushSetup.copperLinked"
Value
-999
6Save Persistent Value
Action Name
persistentWriteResult6
Key
"pushSetup.copperImpulse"
Value
-999
7Save Persistent Value
Action Name
persistentWriteResult7
Key
"pushSetup.blueX"
Value
-999
8Save Persistent Value
Action Name
persistentWriteResult8
Key
"pushSetup.copperX"
Value
-999
9Save Persistent Value
Action Name
persistentWriteResult9
Key
"pushSetup.maximum"
Value
-999
10Save Persistent Value
Action Name
persistentWriteResult10
Key
"pushSetup.increment"
Value
-999
11Save Persistent Value
Action Name
persistentWriteResult11
Key
"pushSetup.capacity"
Value
-999
12For Each Row
Table
Workshop Weights
Variable Name
"clearWeight"
13Save Persistent Value
Action Name
persistentWriteResult12
Key
"pushSetup.weight." + clearWeight.number + ".cart"
Value
-999
14Save Persistent Value
Action Name
persistentWriteResult13
Key
"pushSetup.weight." + clearWeight.number + ".seat"
Value
-999
15Save Persistent Value
Action Name
persistentWriteResult14
Key
"pushSetup.weight." + clearWeight.number + ".mass"
Value
-999
16Change Variable
Variable
$setupStatus
Value
'Choose a starting setup file. The experiment continues until it opens.'
17Open Persistent Values File
Key Prefix
"pushSetup."

A.53 Open Starting Setup Page (Function)

Built in Chapter 5, Compare and remix.

FunctionOpen Starting Setup Page

Opens optional starting setup instructions without changing the experiment.

ACTIONS
1Change Variable
Variable
$inspectedPush
Value
-2
2Change Variable
Variable
$detailsOpen
Value
true

A.54 Open Workshop Goals (Function)

Built in Chapter 5, Compare and remix.

FunctionOpen Workshop Goals

Opens the optional goal page without changing the experiment. Negative inspectedPush selects goals; zero selects latest readings; positive values select a retained reading.

ACTIONS
1Change Variable
Variable
$inspectedPush
Value
-1
2Change Variable
Variable
$detailsOpen
Value
true

A.55 Press Copper Impulse Control

Built in Chapter 5, Compare and remix.

Logic ComponentPress Copper Impulse ControlAttach to: Store Copper Label, Link Both Label

The exact optional sheet label stores Copper's next impulse or links both carts. Keyboard and pointer routes call the same Functions.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
linksImpulsesBooleanConstantNo
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen && $inspectedPush == 0
Then
3If@self.linksImpulses
Then
4Link Workshop ImpulsesFunction
5Otherwise
6Store Copper ImpulseFunction

A.56 Press Experiment Reset

Built in Chapter 5, Compare and remix.

Logic ComponentPress Experiment ResetAttach to: Reset Experiment Label, Restore Defaults Label

The exact Reset or Defaults label chooses one operation. Commands and pointer controls share the same native reset Function.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
restoresDefaultsBooleanConstantNo
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true && $detailsOpen
Then
2If@self.restoresDefaults
Then
3Restart Game
4Otherwise
5Reset Workshop ExperimentFunction

A.57 Press Goal Page

Built in Chapter 5, Compare and remix.

Logic ComponentPress Goal PageAttach to: Workshop Goal Result, Open Goals Label

Opens optional goals from the visible link on the latest reading sheet.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen && $inspectedPush == 0
Then
3Open Workshop GoalsFunction

A.58 Press Setup Control

Built in Chapter 5, Compare and remix.

Logic ComponentPress Setup ControlAttach to: Save Setup Label, Open Setup Label

The exact visible setup label calls the same native Function as its keyboard Command.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
opensSetupBooleanConstantNo
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen && $inspectedPush == -2
Then
3If@self.opensSetup
Then
4Open Starting SetupFunction
5Otherwise
6Save Starting SetupFunction

A.59 Press Setup Page

Built in Chapter 5, Compare and remix.

Logic ComponentPress Setup PageAttach to: Setup Page Label

Opens starting setup files from the optional latest Readings page.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen && $inspectedPush == 0
Then
3Open Starting Setup PageFunction

A.60 Press Workshop Goal

Built in Chapter 5, Compare and remix.

Logic ComponentPress Workshop GoalAttach to: Match Goal Label, Brake Goal Label, Target Goal Label, Stop Goal Label

Starts or stops an optional goal from the exact visible sheet label. Keyboard and pointer routes share the same Functions.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
goalChoiceTextConstantMatch
PER INSTANCE VARIABLES
NameTypeStarting Value
pressSelectedBooleanNo
When the Left Mouse Button Is Pressed
WhenMouse PressMouse button: left
1Ifself.pressSelected == true
Then
2If$detailsOpen && $inspectedPush == -1
Then
3If@self.goalChoice == ""
Then
4Clear Workshop GoalFunction
5Otherwise
6Start Workshop GoalFunction
goal
@self.goalChoice

A.61 Push Selected Impulses (Function)

Built in Chapter 5, Compare and remix.

FunctionPush Selected Impulses

Chooses the next signed impulse for each cart, then asks the exact pair to perform one measured native push.

ACTIONS
1Declare Variable
Name
nextCopperImpulse
Value
$impulseMagnitude * $impulseDirection
2If$copperImpulseLinked == false
Then
3Change Variable
Variable
nextCopperImpulse
Value
$copperNextImpulse
4Push Workshop PairFunction
blue
$blueCart
copper
$copperCart
blueImpulse
$impulseMagnitude * $impulseDirection
copperImpulse
nextCopperImpulse

A.62 Reset Experiment Controls

Built in Chapter 5, Compare and remix.

Logic ComponentReset Experiment ControlsAttach to: Game Rules

R resets observations and returns the apparatus with chosen settings. D restarts from the authored defaults. Both end held input and leave exploration usable.

Attach toAny Object
When Reset Experiment Is Pressed
WhenCommand PressedCommand: Reset Experiment
1Reset Workshop ExperimentFunction
When Restore Defaults Is Pressed
WhenCommand PressedCommand: Restore Defaults
1Restart Game

A.63 Reset Workshop Experiment (Function)

Built in Chapter 5, Compare and remix.

FunctionReset Workshop Experiment

Returns the apparatus from rest and clears observations. Keeps the selected impulse, load arrangement, weight selection and edited tuning; Restore Defaults starts from the authored setup.

ACTIONS
1Clear Workshop GoalFunction
2Trigger Custom Event
Custom Event
returnCarts
3Reset Data Table
Table
Push Readings
4Change Variable
Variable
$inspectedPush
Value
0
5Change Variable
Variable
$detailsOpen
Value
false
6Change Variable
Variable
$pushBatch
Value
0
7Change Variable
Variable
$blueReadingValid
Value
false
8Change Variable
Variable
$copperReadingValid
Value
false
9Change Variable
Variable
$blueMass
Value
0
10Change Variable
Variable
$blueAppliedImpulse
Value
0
11Change Variable
Variable
$blueBefore
Value
0
12Change Variable
Variable
$blueAfter
Value
0
13Change Variable
Variable
$blueDelta
Value
0
14Change Variable
Variable
$copperMass
Value
0
15Change Variable
Variable
$copperAppliedImpulse
Value
0
16Change Variable
Variable
$copperBefore
Value
0
17Change Variable
Variable
$copperAfter
Value
0
18Change Variable
Variable
$copperDelta
Value
0
19Change Variable
Variable
$pushStatus
Value
'Experiment reset. Your settings and loads are kept.'

A.64 Restore Setup Position

Built in Chapter 5, Compare and remix.

Logic ComponentRestore Setup PositionAttach to: Blue Cart, Copper Cart

Places this released cart at the validated starting X. The rail and native rest state are retained; this is a deliberate setup operation, not motion integration.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
cartNumberNumberConstant1
On Setup Cart Position
WhensetupCartPositionCustom Event
1If@self.cartNumber == 1
Then
2Set Position
X
data("Starting Setup Values","blueX","value")
Y
self.transform.position.y
3Otherwise
4Set Position
X
data("Starting Setup Values","copperX","value")
Y
self.transform.position.y

A.65 Restore Weight Setup

Built in Chapter 5, Compare and remix.

Logic ComponentRestore Weight SetupAttach to: One Kilogram Weight, Two Kilogram Weight, Five Kilogram Weight

Moves this exact weight through the shared native transfer rule after a complete setup file is validated. First all weights go to rack, then preferred seats are applied.

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
weightNumberNumber0
rackXNumber0
rackYNumber0
weightHeightNumber0
On Setup Weights to Rack
WhensetupWeightsToRackCustom Event
1Transfer Workshop WeightFunction
Action Name
transferWorkshopWeightResult
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
0
preferredSeat
data("Starting Weight Setup","Weight " + self.weightNumber,"seat")
On Setup Weights to Seats
WhensetupWeightsToSeatsCustom Event
1Transfer Workshop WeightFunction
Action Name
transferWorkshopWeightResult2
weight
self
number
self.weightNumber
rackX
self.rackX
rackY
self.rackY
height
self.weightHeight
destination
data("Starting Weight Setup","Weight " + self.weightNumber,"cart")
preferredSeat
data("Starting Weight Setup","Weight " + self.weightNumber,"seat")

A.66 Save Starting Setup (Function)

Built in Chapter 5, Compare and remix.

FunctionSave Starting Setup

Downloads committed controls and the exact cart/weight arrangement as a portable Myth values file. It does not stop motion or save observations. Finish any cart or weight hand first.

ACTIONS
1If$blueCart.count == 1 && $copperCart.count == 1 && $blueCart.collider.fixed == false && $copperCart.collider.fixed == false && dataFind("Workshop Weights","cart",-1) < 0 && dataCount("Workshop Weights") == $weightCount
Then
2Save Persistent Value
Action Name
persistentWriteResult
Key
"pushSetup.version"
Value
1
3Save Persistent Value
Action Name
persistentWriteResult2
Key
"pushSetup.weightCount"
Value
dataCount("Workshop Weights")
4Save Persistent Value
Action Name
persistentWriteResult3
Key
"pushSetup.impulseMagnitude"
Value
$impulseMagnitude
5Save Persistent Value
Action Name
persistentWriteResult4
Key
"pushSetup.impulseDirection"
Value
$impulseDirection
6Save Persistent Value
Action Name
persistentWriteResult5
Key
"pushSetup.copperLinked"
Value
$copperImpulseLinked
7Save Persistent Value
Action Name
persistentWriteResult6
Key
"pushSetup.copperImpulse"
Value
$copperNextImpulse
8Save Persistent Value
Action Name
persistentWriteResult7
Key
"pushSetup.blueX"
Value
$blueCart.transform.position.x
9Save Persistent Value
Action Name
persistentWriteResult8
Key
"pushSetup.copperX"
Value
$copperCart.transform.position.x
10Save Persistent Value
Action Name
persistentWriteResult9
Key
"pushSetup.maximum"
Value
data("Impulse Settings","Shared","maximum")
11Save Persistent Value
Action Name
persistentWriteResult10
Key
"pushSetup.increment"
Value
data("Impulse Settings","Shared","increment")
12Save Persistent Value
Action Name
persistentWriteResult11
Key
"pushSetup.capacity"
Value
data("Cart Load Settings","cart","capacity")
13For Each Row
Table
Workshop Weights
Variable Name
"saveWeight"
14Save Persistent Value
Action Name
persistentWriteResult12
Key
"pushSetup.weight." + saveWeight.number + ".cart"
Value
saveWeight.cart
15Save Persistent Value
Action Name
persistentWriteResult13
Key
"pushSetup.weight." + saveWeight.number + ".seat"
Value
saveWeight.seat
16Save Persistent Value
Action Name
persistentWriteResult14
Key
"pushSetup.weight." + saveWeight.number + ".mass"
Value
saveWeight.mass
17Save Persistent Values To File
Action Name
setupFile
File Name
"push-lab-starting-setup"
Key Prefix
"pushSetup."
18IfsetupFile.ok
Then
19Change Variable
Variable
$setupStatus
Value
'Setup saved. Open it in another copy of this project.'
20Otherwise
21Change Variable
Variable
$setupStatus
Value
'Setup could not be saved. Try again.'
22Otherwise
23Change Variable
Variable
$setupStatus
Value
'Finish the hand; both carts and all weights must be available.'

A.67 Show Impulse Setting Label

Built in Chapter 5, Compare and remix.

Logic ComponentShow Impulse Setting LabelAttach to: Next Impulse, Independent Impulse Label

Shows either the shared dial readout or the independent Blue/Copper readout on the ordinary bench.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
showLinkedBooleanConstantNo
When Created
WhenCreate
1Set Visible
Visible
$detailsOpen == false && $copperImpulseLinked == @self.showLinked
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen == false && $copperImpulseLinked == @self.showLinked
On Variable Changed · Copper Impulse Linked
WhenVariable ChangedGlobal Variable: copperImpulseLinked
1Set Visible
Visible
$detailsOpen == false && $copperImpulseLinked == @self.showLinked
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen == false && $copperImpulseLinked == @self.showLinked

A.68 Show Setup Page

Built in Chapter 5, Compare and remix.

Logic ComponentShow Setup PageAttach to: Starting Setup Instructions, Save Setup Label, Open Setup Label

Shows setup instructions and controls only on the optional setup page. U reopens it; H returns to readings.

Attach toAny Object
When Created
WhenCreate
1Set Visible
Visible
$detailsOpen && $inspectedPush == -2
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen && $inspectedPush == -2
On Variable Changed · Inspected Push
WhenVariable ChangedGlobal Variable: inspectedPush
1Set Visible
Visible
$detailsOpen && $inspectedPush == -2
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen && $inspectedPush == -2

A.69 Show Workshop Goal

Built in Chapter 5, Compare and remix.

Logic ComponentShow Workshop GoalAttach to: Match Goal Label, Brake Goal Label, Target Goal Label, Stop Goal Label, Match Goal Instruction, Brake Goal Instruction, Target Goal Instruction, Workshop Goal Result, Open Goals Label

Shows choices on the optional Goals page (caption kind 0), selected rules (1), or a selected result (2) or idle Goals link (3) on the optional latest Readings page. captionGoal selects the matching rule caption.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
goalCaptionKindNumberConstant0
captionGoalTextConstant(empty)
When Created
WhenCreate
1If@self.goalCaptionKind == 0
Then
2Set Visible
Visible
$detailsOpen && $inspectedPush == -1
3If@self.goalCaptionKind == 1
Then
4Set Visible
Visible
$detailsOpen && $inspectedPush == -1 && $workshopGoal == @self.captionGoal
5If@self.goalCaptionKind == 2
Then
6Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal != ""
7If@self.goalCaptionKind == 3
Then
8Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal == ""
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1If@self.goalCaptionKind == 0
Then
2Set Visible
Visible
$detailsOpen && $inspectedPush == -1
3If@self.goalCaptionKind == 1
Then
4Set Visible
Visible
$detailsOpen && $inspectedPush == -1 && $workshopGoal == @self.captionGoal
5If@self.goalCaptionKind == 2
Then
6Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal != ""
7If@self.goalCaptionKind == 3
Then
8Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal == ""
On Variable Changed · Inspected Push
WhenVariable ChangedGlobal Variable: inspectedPush
1If@self.goalCaptionKind == 0
Then
2Set Visible
Visible
$detailsOpen && $inspectedPush == -1
3If@self.goalCaptionKind == 1
Then
4Set Visible
Visible
$detailsOpen && $inspectedPush == -1 && $workshopGoal == @self.captionGoal
5If@self.goalCaptionKind == 2
Then
6Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal != ""
7If@self.goalCaptionKind == 3
Then
8Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal == ""
On Variable Changed · Workshop Goal
WhenVariable ChangedGlobal Variable: workshopGoal
1If@self.goalCaptionKind == 0
Then
2Set Visible
Visible
$detailsOpen && $inspectedPush == -1
3If@self.goalCaptionKind == 1
Then
4Set Visible
Visible
$detailsOpen && $inspectedPush == -1 && $workshopGoal == @self.captionGoal
5If@self.goalCaptionKind == 2
Then
6Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal != ""
7If@self.goalCaptionKind == 3
Then
8Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal == ""
On Load:succeeded
Whenload:succeededCustom Event
1If@self.goalCaptionKind == 0
Then
2Set Visible
Visible
$detailsOpen && $inspectedPush == -1
3If@self.goalCaptionKind == 1
Then
4Set Visible
Visible
$detailsOpen && $inspectedPush == -1 && $workshopGoal == @self.captionGoal
5If@self.goalCaptionKind == 2
Then
6Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal != ""
7If@self.goalCaptionKind == 3
Then
8Set Visible
Visible
$detailsOpen && $inspectedPush == 0 && $workshopGoal == ""

A.70 Start Workshop Goal (Function)

Built in Chapter 5, Compare and remix.

FunctionStart Workshop Goal

Starts an optional goal from the next paired reading. Old successful observations remain available but cannot satisfy this request.

PARAMETERS
NameTypeStarts at
goalTextMatch
ACTIONS
1Change Variable
Variable
$workshopGoal
Value
goal
2Change Variable
Variable
$goalStartBatch
Value
$pushBatch
3Change Variable
Variable
$goalResult
Value
'Waiting'

A.71 Starting Setup Controls

Built in Chapter 5, Compare and remix.

Logic ComponentStarting Setup ControlsAttach to: Game Rules

U opens optional setup help. E saves committed choices and arrangement; I opens a setup with this same project tuning. Native file Events report success, failure or cancellation.

Attach toAny Object
When Setup Page Is Pressed
WhenCommand PressedCommand: Open Setup Page
1Open Starting Setup PageFunction
When Setup Save Is Pressed
WhenCommand PressedCommand: Save Setup
1Save Starting SetupFunction
When Setup Open Is Pressed
WhenCommand PressedCommand: Open Setup
1Open Starting SetupFunction
On Values:imported
Whenvalues:importedCustom Event
1Apply Starting SetupFunction
On Values:failed
Whenvalues:failedCustom Event
1Change Variable
Variable
$setupStatus
Value
'The setup file could not be opened. Nothing changed.'
On Values:canceled
Whenvalues:canceledCustom Event
1Change Variable
Variable
$setupStatus
Value
'Setup opening canceled. Nothing changed.'

A.72 Store Copper Impulse (Function)

Built in Chapter 5, Compare and remix.

FunctionStore Copper Impulse

Stores the dial and lever setting as Copper's next impulse. The dial can then change Blue independently. Existing motion and observations stay unchanged.

ACTIONS
1Change Variable
Variable
$copperNextImpulse
Value
$impulseMagnitude * $impulseDirection
2Change Variable
Variable
$copperImpulseLinked
Value
false