TutorialsPush Lab

5  Compare and Remix

Goal

Choose separate impulses, test an optional goal, and save an arrangement for another experiment.

V stores the dial choice for Copper; L links both again. O opens goals, U opens setup files. R resets observations with your settings; D restores defaults.

Push Lab, Chapter 5 finishedMyth project

Open the downloaded file with File › Open Project... in Myth Engine.

5.1 The Idea

Blue draws ahead again. Copper carries more mass, but this time you can give it a larger impulse. Their changes can match.

The earlier experiments kept the impulse equal and changed the load. Now you can choose each cart’s next impulse separately. The same relationship still holds: change in velocity equals signed impulse divided by mass.

A goal watches a new observation for a chosen result. It leaves you free to arrange the bench and try again. Nothing here is timed.

An old successful paper cannot answer a new request. Think of marking a new page in your experiment notebook: earlier notes remain useful, but this attempt needs its own observation.

You’ll also keep a starting setup, the controls and arrangement for another run. It opens from rest. Moving velocities and earlier papers belong to the running experiment, rather than to that file.

The rails were quiet in the first chapter. Now your bench can answer a question you choose.

5.2 The Plan

Store Copper Impulse keeps one signed choice while the dial continues choosing Blue’s. Push Selected Impulses sends both choices into the existing measured push.

Start Workshop Goal marks where an attempt begins. Push Workshop Pair records each accepted observation, then Evaluate Workshop Goal checks that same pair immediately.

The setup Functions collect and check a file before changing the bench. Restore Weight Setup and Restore Setup Position apply its arrangement through the native behaviors you already made.

5.3 Set Up

Continue with the weights, live gauges and printed history from last chapter. Joining here? Download the Chapter 4 starting workshop and open it through File > Open Project…. The finished download above is the result you’ll build here.

Keep the existing Game Settings and tuning. Add the Commands and Project Globals below, leaving the blank Text values empty.

Make the named Objects before placing them. Most new labels belong on optional sheets. Their visibility Logic will choose the appropriate page; keep their placement and drawing order from the setup card.

Set upWhat this chapter adds
COMMANDS (Game Settings > Input Manager)
Reset ExperimentButton
KeybindingsR
Restore DefaultsButton
KeybindingsD
Store Copper ImpulseButton
KeybindingsV
Link Workshop ImpulsesButton
KeybindingsL
Match GoalButton
KeybindingsC
Brake GoalButton
KeybindingsB
Target GoalButton
KeybindingsG
Clear GoalButton
KeybindingsX
Open GoalsButton
KeybindingsO
Open Setup PageButton
KeybindingsU
Save SetupButton
KeybindingsE
Open SetupButton
KeybindingsI
GLOBAL VARIABLES
$copperImpulseLinkedBooleanstarts at true
$copperNextImpulseNumberstarts at 4
$workshopGoalTextstarts at
$goalResultTextstarts at
$goalStartBatchNumberstarts at 0
$setupStatusTextstarts at Save controls and arrangement; open from rest.
$setupEmptyFieldsNumberstarts at 1
SCENE Lab: PLACE THESE
ObjectXY
Reset Experiment Label3.50.625
with Z-Index = 26
Restore Defaults Label20.50.625
with Z-Index = 26
Store Copper Label6.54.7
with Z-Index = 26
Link Both Label17.54.7
with Z-Index = 26
Independent Impulse Label8.1252.85
with Z-Index = 8
Match Goal Label3.7512.25
with Z-Index = 26
Brake Goal Label9.2512.25
with Z-Index = 26
Target Goal Label14.7512.25
with Z-Index = 26
Stop Goal Label20.2512.25
with Z-Index = 26
Match Goal Instruction1210
with Z-Index = 26
Brake Goal Instruction1210
with Z-Index = 26
Target Goal Instruction1210
with Z-Index = 26
Workshop Goal Result128
with Z-Index = 26
Open Goals Label128
with Z-Index = 26
Starting Setup Instructions128.75
with Z-Index = 26
Save Setup Label6.254.25
with Z-Index = 26
Open Setup Label17.754.25
with Z-Index = 26
Setup Page Label20.515.2
with Z-Index = 26
SCENE Lab: CHANGE THESE PLACEMENTS
Workshop Instructions move to X 12, Y 2.75

Build the new Functions before selecting them as Actions elsewhere. Setup validation takes more care. Its records come first, and its callers come afterward.

5.4 Give the Carts Separate Choices

5.4.1 Store Copper Impulse

Copper can keep the dial’s present signed choice while you turn the dial again for Blue. Store Copper Impulse takes that choice and ends the link between their controls.

It applies no push. Both carts keep their current motion and observations.

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

5.4.3 Push Selected Impulses

One press must now collect two choices. Push Selected Impulses starts with the shared signed value, then substitutes Copper’s stored choice when the link is off.

The existing paired Function still decides whether the apparatus is ready. Both choices enter that one route.

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

5.4.4 Request Pair Push

Space and the blue button must collect those choices alike. Replace their direct calls with Push Selected Impulses, keeping both existing Events.

Logic ComponentRequest Pair PushAttach to: Game RulesAddDelete

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 Workshop PairFunction
blue
$blueCart
copper
$copperCart
blueImpulse
$impulseMagnitude * $impulseDirection
copperImpulse
$impulseMagnitude * $impulseDirection
1Push Selected ImpulsesFunction
On Push Requested
WhenpushRequestedCustom Event
1Push Workshop PairFunction
blue
$blueCart
copper
$copperCart
blueImpulse
$impulseMagnitude * $impulseDirection
copperImpulse
$impulseMagnitude * $impulseDirection
1Push Selected ImpulsesFunction

5.4.5 Choose Copper Impulse

The keyboard gets the same two operations. Choose Copper Impulse listens for storing and linking, then calls their shared Functions.

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

5.4.6 Calibrate Recorded Gauge

Copper’s first scale must respect its own choice too. Before an observation exists, the changed branch uses Copper’s stored impulse when the controls are separate.

After a push, the scale still comes from measured motion. Revise your existing Function.

FunctionCalibrate Recorded GaugeAddDelete

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

5.4.7 Show Impulse Setting Label

The bench needs to say whether the choices are linked. Show Impulse Setting Label chooses between the shared caption and a separate Blue/Copper caption.

Declare showLinked once here. Each caption’s Object value chooses its role.

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

5.4.8 Next Impulse

The familiar caption remains useful while both carts share the dial. Replace its old visibility attachment with the new one and keep showLinked set to Yes.

ObjectNext ImpulseAddDelete
Transform
Bounding Box > SizeX 0.8, Y 0.8
Text / UI
Text{round($impulseMagnitude * $impulseDirection * 10) / 10} N s
Font Size0.2375
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X3.1
Logic
Show Impulse Setting Label
Show Workshop Detail
Shared Variables
showLinkedYes
showOnOpenNo

5.4.9 Independent Impulse Label

When the link is off, both signed choices should be visible together. Independent Impulse Label reads Blue’s dial choice beside Copper’s stored choice.

Its showLinked value chooses the separate view. Match its placement to the setup card, beside the other apparatus readouts.

ObjectIndependent Impulse Label
Transform
Bounding Box > SizeX 12, Y 1.1
Text / UI
TextB {round($impulseMagnitude * $impulseDirection * 10) / 10} / C {round($copperNextImpulse * 10) / 10} N s
Font Size0.2375
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X3.3
Logic
Show Impulse Setting Label

Both choices are visible.

5.5 Watch a Fresh Attempt

5.5.1 Workshop Goal Entry

A successful attempt needs a stated rule. Workshop Goal Entry describes the mass ratio, speed changes and tolerances that the three goals will check.

A tolerance gives a small allowed difference around a target. It belongs to judging the observation, without changing the physical impulse.

Data StructureWorkshop Goal Entry

A goal rule: minimumRatio compares masses; minimumChange and changeTolerance compare immediate velocity changes; minimumBefore and stopTolerance define braking; targetVelocity and targetTolerance define the signed target, all speeds in m/s.

minimumRatioNumberdefault 5
minimumChangeNumberdefault 0.5
changeToleranceNumberdefault 0.1
minimumBeforeNumberdefault 0.5
stopToleranceNumberdefault 0.08
targetVelocityNumberdefault 2
targetToleranceNumberdefault 0.08

5.5.2 Goal Settings

The Rules row keeps those limits together. Make it with the structure above and enter its row name in Entry.

Match compares changes, Brake looks for an opposing push that leaves a cart near rest, and Target looks for a positive final velocity. Their fields serve different questions.

Data TableGoal SettingsData Structure: Workshop Goal Entry
Row 0Rules
minimumRatio5
minimumChange0.5
changeTolerance0.1
minimumBefore0.5
stopTolerance0.08
targetVelocity2
targetTolerance0.08

5.5.3 Complete Workshop Goal

A cart reaches its stop after earning a successful paper. That later motion must leave the success alone. Complete Workshop Goal keeps the outcome available while you explore another push.

FunctionComplete Workshop Goal

Keeps the selected optional goal complete while later exploration continues.

ACTIONS
1Change Variable
Variable
$goalResult
Value
'Complete'

5.5.4 Clear Workshop Goal

Sometimes you want to explore without a task watching your next push. Clear Workshop Goal ends that request. It keeps the carts, controls and papers available for another experiment.

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

5.5.5 Start Workshop Goal

Choose a goal after a successful push and the old paper should stay old. Start Workshop Goal remembers the current batch as goalStartBatch, then waits for a newer one.

The goal Parameter names its rule. Starting it applies no force and leaves both carts moving as they were.

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'

5.5.6 Evaluate Workshop Goal

A new measured pair arrives. Evaluate Workshop Goal first checks that the attempt is waiting, the batch is newer, and both latest readings remain valid.

Only then does its selected branch judge the answer. Match compares their mass ratio and changes; Brake checks an opposing impulse; Target checks signed after velocity.

Read these as three separate questions. The long comparisons use the Rules row rather than hiding the limits inside the Logic. Brake’s parentheses keep each cart’s whole test together.

Blue moves right. A leftward impulse brings it near rest immediately afterward. Blue’s before reading must meet minimumBefore, and its after reading must fit stopTolerance. Their opposite signs make impulse times before negative.

Copper gets the same complete test after the OR. Either cart can satisfy Brake. A later collision with a stop cannot supply that immediate after reading.

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

5.5.7 Push Workshop Pair

The goal must see this observation immediately. Add Evaluate Workshop Goal immediately after Record Pair Reading, inside the accepted-push branch.

Each accepted pair is recorded and judged together. Keep both guards.

FunctionPush Workshop PairAddDelete

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.'

5.5.8 Open Workshop Goals

Looking at the tasks should leave the current attempt alone. Open Workshop Goals selects the goals page inside the sheet without starting or clearing anything.

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

5.5.9 Choose Workshop Goal

The keyboard can request or clear an attempt without opening a page. Choose Workshop Goal connects them.

The page-opening Command is separate from starting a task. Looking at the choices starts nothing.

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

The experiment can judge a new attempt without taking the controls away.

5.6 Return for Another Experiment

5.6.1 Reset Workshop Experiment

Your chosen load may be exactly the arrangement you want to test again. Reset Workshop Experiment returns the carts from rest and clears observations while keeping that arrangement and the impulse choices.

Return alone still has its earlier, narrower job. This reset also clears the optional goal, latest comparison and retained history. Its return message lets the existing hand cleanup finish first.

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.'

5.6.2 Reset Experiment Controls

Reset and Defaults answer different requests. Reset Experiment Controls calls the reset Function for one Command; the other restarts the authored Scene.

The restart restores the original load and linked choices too. Keep those Events separate.

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

Your arrangement can survive a fresh observation window.

5.7 Keep an Arrangement in a File

5.7.1 Starting Setup Values Entry

A portable setup needs somewhere to wait while its fields are checked. Starting Setup Values Entry gives each scalar a value and an allowed range.

These staging records are separate from the live controls.

Data StructureStarting Setup Values Entry

One row of the "Starting Setup Values" Data Table.

valueNumberdefault 0
minimumNumberdefault 0
maximumNumberdefault 0

5.7.2 Starting Setup Values

Each named row checks one part of the incoming setup. Starting Setup Values includes the file version, control choices, cart positions and matching project settings.

Enter all named rows now. The current weight count will replace its authored upper bound during validation, so an edited rack can use its actual number of weights.

Data TableStarting Setup ValuesData Structure: Starting Setup Values Entry
Row 0version
value0
minimum1
maximum1
Row 1weightCount
value0
minimum0
maximum12
Row 2impulseMagnitude
value0
minimum0
maximum100000
Row 3impulseDirection
value0
minimum-1
maximum1
Row 4copperLinked
value0
minimum0
maximum1
Row 5copperImpulse
value0
minimum-100000
maximum100000
Row 6blueX
value0
minimum5.749999
maximum21.100001
Row 7copperX
value0
minimum5.749999
maximum21.100001
Row 8maximum
value0
minimum0.01
maximum100000
Row 9increment
value0
minimum0.000001
maximum100000
Row 10capacity
value0
minimum1
maximum4

5.7.3 Starting Weight Setup Entry

The matching weights need their own staging record. Starting Weight Setup Entry keeps identity, destination, seat and mass together while the file is checked.

Data StructureStarting Weight Setup Entry

One row of the "Starting Weight Setup" Data Table.

numberNumberdefault 0
cartNumberdefault 0
seatNumberdefault 0
massNumberdefault 0

5.7.4 Starting Weight Setup

Leave this table empty when authoring. Starting Weight Setup will receive one proposed arrangement for each registered weight before any live transfer begins.

Data TableStarting Weight SetupData Structure: Starting Weight Setup Entry

5.7.5 Check Setup Fields

An absent value must stay distinguishable from a genuine zero. Check Setup Fields counts missing fields.

Create this Script and replace its Script Code with the supplied source. It checks presence alone; the native Function below checks scientific ranges, matching settings and occupied seats.

ScriptCheck Setup Fields
Script Code
// Count empty file fields before the native numeric checks.
let empty = 0;
const check = key => { if (api.loadPersistent(key, null) == null) empty++; };
for (let i = 0; i < api.dataCount('Starting Setup Values'); i++) {
  check('pushSetup.' + api.dataRow('Starting Setup Values', i));
}
for (let i = 0; i < api.dataCount('Workshop Weights'); i++) {
  const number = api.dataGet('Workshop Weights', i, 'number');
  for (const field of ['cart', 'seat', 'mass']) {
    check('pushSetup.weight.' + number + '.' + field);
  }
}
api.setGlobal('setupEmptyFields', '=', empty);
Download this Script source

5.7.6 Save Starting Setup

Save while a cart is rolling and the experiment should keep rolling. Save Starting Setup collects the committed controls and arrangement, then downloads a Myth values file.

Release any cart or weight you are dragging first. Both original carts and the complete weight registry must be available. The file keeps positions and loads. It leaves velocities, contact state and history in the running experiment where they belong.

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.'

5.7.7 Open Starting Setup

An incomplete file must not borrow forgotten values from an earlier file. Open Starting Setup marks the expected stored keys as missing before asking for a new file.

Suppose Copper’s impulse is absent from the new file. Its key keeps -999. Apply Starting Setup rejects that placeholder’s magnitude when comparing it with the workshop’s maximum of 40.

Most other rows reject the placeholder through their table ranges. Copper needs both checks.

Check Setup Fields catches null or missing stored values separately. Zero remains a real possible choice. The separate range, tuning and presence checks protect different parts of the incoming proposal.

The experiment continues while you choose. Native file completion will tell Starting Setup Controls when validation can begin.

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."

5.7.8 Apply Starting Setup

An incoming arrangement waits outside the live experiment until all its checks pass. Apply Starting Setup gathers its fields into staging tables, then checks their ranges and agreement with this project.

This is the long card. Its first stretch ends before Reset Data Table at Action 15. The scalar values are now staged and checked against this project’s settings. The live bench is still untouched.

Actions 15 through 40 stage every proposed weight and check its destination before anything on the bench moves. The live arrangement still waits. The final stretch begins at Action 41, where the accepted branch can apply the arrangement.

Throughout these stretches, setupValid remembers whether every check has survived. Refusal stays refused.

Build the complete card before testing it. The keyboard connections and file-completion Events come later, under Starting Setup Controls and Game Rules. These stretches describe the Function’s order; they aren’t pauses where you need to run unfinished Logic or inspect live tables.

After Game Rules is connected, you’ll save an arrangement with E. Rearrange the bench. Open that file with I and watch the loads return to their saved destinations, with both carts resting.

Inside For Each Row, setupField.name is the row’s Entry label. Myth provides it automatically; don’t add a name field to the structure. For the version row, setupField.name is "version". That label selects the file key.

Likewise, openWeight.name and checkWeight.name identify their current rows. Those labels identify rows, while number and mass remain separate columns declared in the structure.

The weight checks compare identities and masses, then count uses of each occupied seat. Two weights cannot claim the same cart seat. Refusal leaves the running experiment and all its existing observations alone.

The final accepted branch can now reset the experiment and commit the checked arrangement. It returns weights to the rack before assigning their saved seats, restores cart positions, and commits the control choices. The order prevents the old arrangement from blocking the new one.

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.'

5.7.9 Restore Weight Setup

The accepted file now needs each exact weight to answer. Restore Weight Setup listens for the rack pass and seat pass, using the same transfer Function as ordinary play.

Its existing Per Instance values identify this running weight. Reuse those names and starting values.

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")

5.7.10 One Kilogram Weight

The smallest weight gains the setup listener after its existing hand behavior. Keep its earlier Sprite bindings and attachment order while adding Restore Weight Setup.

ObjectOne Kilogram WeightAddDelete
Transform
Bounding Box > SizeX 0.5, Y 0.8
Sprite
Z Index Within Object6
SpriteWorkshop weight-1
Transform > SizeX 0.5, Y 0.8
Logic
Move Selected Weight
Select Workshop Weight
Listen for Control Press
Drag Workshop Weight
Restore Weight Setup
Move Selected Weight > Components > Sprite (Sprite)Workshop weight-1
Select Workshop Weight > Components > Sprite (Sprite)Workshop weight-1

5.7.11 Two Kilogram Weight

Several taller weights can share this picture. Each running identity selects its own staged row, so restoring one leaves the other copies’ destinations distinct.

ObjectTwo Kilogram WeightAddDelete
Transform
Bounding Box > SizeX 0.625, Y 0.95
Sprite
Z Index Within Object6.04
SpriteWorkshop weight-2
Transform > SizeX 0.625, Y 0.95
Logic
Move Selected Weight
Select Workshop Weight
Listen for Control Press
Drag Workshop Weight
Restore Weight Setup
Move Selected Weight > Components > Sprite (Sprite)Workshop weight-2
Select Workshop Weight > Components > Sprite (Sprite)Workshop weight-2

5.7.12 Five Kilogram Weight

The broad weight joins the restoration route too. A setup file will move this exact copy through the existing capacity and mass rules.

ObjectFive Kilogram WeightAddDelete
Transform
Bounding Box > SizeX 0.75, Y 1.1
Sprite
Z Index Within Object6.08
SpriteWorkshop weight-5
Transform > SizeX 0.75, Y 1.1
Logic
Move Selected Weight
Select Workshop Weight
Listen for Control Press
Drag Workshop Weight
Restore Weight Setup
Move Selected Weight > Components > Sprite (Sprite)Workshop weight-5
Select Workshop Weight > Components > Sprite (Sprite)Workshop weight-5

5.7.13 Restore Setup Position

A saved cart position belongs along its own rail. Restore Setup Position reads that cart’s validated X while retaining its lane height and released rest state.

The file applies a starting arrangement. Native physics still owns the motion that follows, after you deliver another push.

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

5.7.14 Blue Cart

Blue gains that position listener. Keep its existing cartNumber value; the new attachment uses the same Object identity.

ObjectBlue CartAddDelete
Transform
Bounding Box > SizeX 3.6, Y 0.9
Sprite
Z Index Within Object3
SpriteBlue Cart Art
Transform > SizeX 3.6, Y 0.9
Collider
Shape and Transform > SizeX 3.6, Y 0.9
Logic
Place Cart on Rail
Identify Workshop Cart
Set Starting Cart Load
Change Native Cart Load
Restore Setup Position
Place Cart on Rail > Components > Collider (Collider)Collider
Identify Workshop Cart > Components > Collider (Collider)Collider
Shared Variables
homeX > TypeNumber
homeX > KindConstant
homeX > Value6.75
laneY > TypeNumber
laneY > KindConstant
laneY > Value10.975
leftLimit > TypeNumber
leftLimit > KindConstant
leftLimit > Value5.975
rightLimit > TypeNumber
rightLimit > KindConstant
rightLimit > Value20.875
cartNumber > TypeNumber
cartNumber > KindConstant
cartNumber > Value1

5.7.15 Copper Cart

Copper uses its own staged copperX position. Its lower lane stays unchanged while Restore Setup Position joins its existing attachments.

ObjectCopper CartAddDelete
Transform
Bounding Box > SizeX 3.6, Y 0.9
Physics > Mass10
Sprite
Z Index Within Object3
SpriteCopper Cart Art
Transform > SizeX 3.6, Y 0.9
Collider
Shape and Transform > SizeX 3.6, Y 0.9
Logic
Place Cart on Rail
Identify Workshop Cart
Set Starting Cart Load
Change Native Cart Load
Restore Setup Position
Place Cart on Rail > Components > Collider (Collider)Collider
Identify Workshop Cart > Components > Collider (Collider)Collider
Shared Variables
homeX > TypeNumber
homeX > KindConstant
homeX > Value6.75
laneY > TypeNumber
laneY > KindConstant
laneY > Value8.2
leftLimit > TypeNumber
leftLimit > KindConstant
leftLimit > Value5.975
rightLimit > TypeNumber
rightLimit > KindConstant
rightLimit > Value20.875
cartNumber > TypeNumber
cartNumber > KindConstant
cartNumber > Value2

5.7.16 Open Starting Setup Page

The file instructions need their own optional view. Open Starting Setup Page selects that view and opens the existing sheet, leaving the apparatus running.

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

5.7.17 Starting Setup Controls

Keyboard requests can now save, open or explain a setup. Starting Setup Controls also receives native file Events: imported starts validation, while failure and cancellation report their outcomes.

Keep these completion Events as Custom Events with the exact names shown. Opening a file is unfinished until its imported Event reaches Apply Starting Setup.

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.'

5.7.18 Game Rules

Game Rules connects the keyboard routes. Add the four marked attachments in order, keeping the earlier weight and ticket makers.

ObjectGame RulesAddDelete
Logic
Request Pair Push
Choose Next Impulse
Prepare Workshop Weights
Choose Next Weight
Prepare Reading Tickets
Choose Historical Ticket
Reset Experiment Controls
Choose Copper Impulse
Choose Workshop Goal
Starting Setup Controls

Run Lab here. Try storing Copper’s choice, changing Blue’s, and pushing. Test Reset. Choose a load and impulse you’d like to return to after trying another arrangement.

Release any cart or weight you’re dragging. Press E. Keep the downloaded Myth values file, then move a weight to another destination and change the impulse. Press I and choose that saved file. Its load and choices return, with both carts at rest and earlier observations cleared.

This is the file test deferred from Apply Starting Setup. Watch the bench and its readouts; no live-table inspection or unfinished Function call is needed.

The keyboard routes are connected. Next come the sheet labels.

5.8 Put Choices on the Sheets

5.8.1 Cart Press Input

The new labels must receive their own exact presses while visible. Replace the Library source with this chapter’s supplied file, keeping its existing wiring.

The helper recognizes the optional page controls. Every response remains in the native Functions you built earlier, with no second experiment hidden in the helper.

LibraryCart Press InputAddDelete
SOURCEfrom a file
Import .js...push-lab-cart-press-input-ch03.js
Size2.9 KB
Import .js...push-lab-cart-press-input-ch04.js
Size3.9 KB
ADVANCED WIRING AND LOAD ORDER
Alias (Lib.Ext....)cartPress
Global NameCartPressInput

5.8.2 Show Reading Page

There are now more optional pages than latest and history. Revise the existing Show Reading Page with this Changes card so those captions stay off the goals and setup pages.

Keep every existing attachment. Their historyPage values retain their earlier meanings.

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 LabelAddDelete

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)
Visible
$detailsOpen && (($inspectedPush > 0) == @self.historyPage)
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)
Visible
$detailsOpen && (($inspectedPush > 0) == @self.historyPage)
On Variable Changed · Inspected Push
WhenVariable ChangedGlobal Variable: inspectedPush
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)
Visible
$detailsOpen && (($inspectedPush > 0) == @self.historyPage)
On Load:succeeded
Whenload:succeededCustom Event
1Set Visible
Visible
$detailsOpen && $inspectedPush >= 0 && (($inspectedPush > 0) == @self.historyPage)
Visible
$detailsOpen && (($inspectedPush > 0) == @self.historyPage)

5.8.3 Press Experiment Reset

The Reset and Defaults labels call the same operations as the keyboard. Press Experiment Reset uses each label’s restoresDefaults value to choose its response.

The exact-press and visible-sheet checks keep a hidden label from acting through the bench.

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

5.8.4 Reset Experiment Label

Reset offers another attempt with your chosen apparatus. Give this label its listener and response, leaving restoresDefaults at No.

ObjectReset Experiment Label
Transform
Bounding Box > SizeX 5.2, Y 1
Text / UI
TextReset [R]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X5.2
Logic
Press Experiment Reset
Listen for Control Press
Show Workshop Detail

5.8.5 Restore Defaults Label

Defaults brings back the authored workshop. Its response uses the same Logic with restoresDefaults set to Yes, so these similar labels keep their distinct jobs.

ObjectRestore Defaults Label
Transform
Bounding Box > SizeX 5.2, Y 1
Text / UI
TextDefaults [D]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X5.2
Logic
Press Experiment Reset
Listen for Control Press
Show Workshop Detail
Shared Variables
restoresDefaultsYes

5.8.6 Press Copper Impulse Control

The optional sheet can store and link impulses too. Press Copper Impulse Control selects its Function through the holding label’s linksImpulses value.

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

5.8.7 Store Copper Label

Store Copper gives the separate choice a visible home. Its page attachment belongs to latest readings. Keep linksImpulses at No.

ObjectStore Copper Label
Transform
Bounding Box > SizeX 10, Y 1.1
Text / UI
TextStore Copper [V]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X10
Logic
Show Reading Page
Press Copper Impulse Control
Listen for Control Press

5.8.9 Show Workshop Goal

Choices and results occupy different places. Show Workshop Goal uses goalCaptionKind to choose that role; captionGoal identifies a particular rule.

Declare those Shared Variables here. Each Object card below supplies its own values after attachment.

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 == ""

5.8.10 Press Workshop Goal

A task label starts its named goal. Press Workshop Goal shares the keyboard’s Functions, while the stop label clears the request instead.

Match each Object’s goalChoice text exactly. The displayed task must agree with the selected rule that its response sends to Start Workshop Goal.

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

5.8.11 Press Goal Page

The result can lead back to the choices. Press Goal Page opens that page from either the active result or idle Goals label, without replacing the current task.

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

5.8.12 Match Goal Label

Match asks whether unequal masses can have matching velocity changes. This label chooses that question; it does not rearrange the experiment for you.

ObjectMatch Goal Label
Transform
Bounding Box > SizeX 5.3, Y 1.1
Text / UI
TextMatch [C]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X5.3
Logic
Show Workshop Goal
Press Workshop Goal
Listen for Control Press

5.8.13 Brake Goal Label

Choose Brake while a cart is already moving. The request waits for your next push; opening it must leave that motion alone.

ObjectBrake Goal Label
Transform
Bounding Box > SizeX 5.3, Y 1.1
Text / UI
TextBrake [B]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X5.3
Logic
Show Workshop Goal
Press Workshop Goal
Listen for Control Press
Shared Variables
goalChoiceBrake

5.8.14 Target Goal Label

Choose Target with the cart at rest. The request should wait while you arrange the load and dial, then judge the next accepted push.

ObjectTarget Goal Label
Transform
Bounding Box > SizeX 5.3, Y 1.1
Text / UI
TextTarget [G]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X5.3
Logic
Show Workshop Goal
Press Workshop Goal
Listen for Control Press
Shared Variables
goalChoiceTarget

5.8.15 Stop Goal Label

Stop ends the optional request. The carts and observations remain yours to explore, with no task waiting for a result.

ObjectStop Goal Label
Transform
Bounding Box > SizeX 5.3, Y 1.1
Text / UI
TextStop [X]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X5.3
Logic
Show Workshop Goal
Press Workshop Goal
Listen for Control Press
Shared Variables
goalChoice(empty)

5.8.16 Match Goal Instruction

The chosen Match rule should explain itself. Its caption reads the same tuning fields that Evaluate Workshop Goal checks, so the displayed task agrees with the decision.

ObjectMatch Goal Instruction
Transform
Bounding Box > SizeX 23, Y 4
Text / UI
TextMatch: {$goalResult} [new line] Mass ratio >= {data("Goal Settings","Rules","minimumRatio")}; changes within {data("Goal Settings","Rules","changeTolerance")} m/s. [new line] Blue change magnitude >= {data("Goal Settings","Rules","minimumChange")} m/s. [new line] Only a new push counts; later contact does not.
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X23
Logic
Show Workshop Goal
Shared Variables
goalCaptionKind1
captionGoalMatch

5.8.17 Brake Goal Instruction

Brake’s caption asks for motion before the push and near rest immediately afterward. It keeps the opposing-impulse requirement visible, so hitting a stop is not mistaken for completing the task.

ObjectBrake Goal Instruction
Transform
Bounding Box > SizeX 23, Y 4
Text / UI
TextBrake: {$goalResult} [new line] Start either cart at least {data("Goal Settings","Rules","minimumBefore")} m/s. [new line] Use an opposing impulse; finish within {data("Goal Settings","Rules","stopTolerance")} m/s of rest. [new line] Only a new push counts; later contact does not.
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X23
Logic
Show Workshop Goal
Shared Variables
goalCaptionKind1
captionGoalBrake

5.8.18 Target Goal Instruction

Blue reaches the right speed while moving left. Target still waits. Its caption asks for rightward motion, so the signed reading must agree with the requested direction too.

ObjectTarget Goal Instruction
Transform
Bounding Box > SizeX 23, Y 4
Text / UI
TextTarget: {$goalResult} [new line] Finish either cart at +{data("Goal Settings","Rules","targetVelocity")} m/s. [new line] Within {data("Goal Settings","Rules","targetTolerance")} m/s counts. [new line] Only a new push counts; later contact does not.
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X23
Logic
Show Workshop Goal
Shared Variables
goalCaptionKind1
captionGoalTarget

5.8.19 Workshop Goal Result

The latest page can keep the chosen task and outcome in view. Press its result to revisit the choices.

ObjectWorkshop Goal Result
Transform
Bounding Box > SizeX 14, Y 1.1
Text / UI
Text{$workshopGoal}: {$goalResult}
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X14
Logic
Show Workshop Goal
Press Goal Page
Listen for Control Press
Shared Variables
goalCaptionKind2

5.8.20 Open Goals Label

Before a task is chosen, an idle Goals label occupies that place. Its goalCaptionKind selects the idle case, so it yields to the result after you start an attempt.

ObjectOpen Goals Label
Transform
Bounding Box > SizeX 14, Y 1.1
Text / UI
TextGoals [O]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X14
Logic
Show Workshop Goal
Press Goal Page
Listen for Control Press
Shared Variables
goalCaptionKind3

5.8.21 Show Setup Page

The file page needs its own visibility rule. Show Setup Page reveals its instructions and controls only when that optional page is selected.

Its change and Load Events keep the view correct after restoration too. H closes the whole sheet from this page. U reopens it.

The card description says H returns to readings. Read that as returning to the bench: the readings sheet closes too. The existing Show Workshop Detail still owns H.

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

5.8.22 Press Setup Control

Saving and opening share one label response. Press Setup Control uses opensSetup to choose the Function, keeping both routes behind the visible-page check.

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

5.8.23 Press Setup Page

The latest readings need a route to the file instructions. Press Setup Page gives the Setup files label that response through the same Function as U.

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

5.8.24 Starting Setup Instructions

The file page explains what a setup keeps and what reopening changes. Its Text also displays setupStatus, so an incomplete file can explain its refusal beside the controls.

Preserve its line breaks, replacing each card marker with a real break.

ObjectStarting Setup Instructions
Transform
Bounding Box > SizeX 23, Y 7
Text / UI
TextSTARTING SETUP [new line] Controls, cart positions and weight seats. [new line] Open with this same project and tuning. [new line] Starts from rest; clears old readings. [new line] Not a moving Save Game snapshot. [new line] {$setupStatus}
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X23
Logic
Show Setup Page

5.8.25 Save Setup Label

You have found a load worth keeping. Release the weight you were dragging, then press Save before trying another arrangement on the bench. The experiment keeps running while the file downloads.

ObjectSave Setup Label
Transform
Bounding Box > SizeX 10, Y 1.5
Text / UI
TextSave setup [E]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X10
Logic
Show Setup Page
Press Setup Control
Listen for Control Press

5.8.26 Open Setup Label

Later, your rack and both cart loads may look different from the arrangement you saved. Press Open and choose that earlier file. Validation runs first; the accepted arrangement then returns with both carts at rest.

ObjectOpen Setup Label
Transform
Bounding Box > SizeX 10, Y 1.5
Text / UI
TextOpen setup [I]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X10
Logic
Show Setup Page
Press Setup Control
Listen for Control Press
Shared Variables
opensSetupYes

5.8.27 Setup Page Label

The latest paper looks useful. Setup files opens the file controls from that reading, leaving the experiment running. Its historyPage value keeps this link beside latest readings.

ObjectSetup Page Label
Transform
Bounding Box > SizeX 6.8, Y 1.1
Text / UI
TextSetup files [U]
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X6.8
Logic
Show Reading Page
Press Setup Page
Listen for Control Press

5.8.28 Workshop Instructions

The latest reminder now names storing and linking choices. Replace its marked Text while preserving the real line breaks between the separate control reminders. Move its Scene placement as the setup card shows to leave room for the new controls.

ObjectWorkshop InstructionsAddDelete
Transform
Bounding Box > SizeX 0.8, Y 0.8
Text / UI
TextDrag to place. Space: Push / Home: Return / H: close [new line] Arrows: J / sign. V: store Copper; L: link both [new line] N: weight / 1,2: load / Delete: rack / T: tickets
TextDrag carts or weights; release from rest. [new line] Space: Push Home: Return Arrows: J / sign [new line] N: Weight 1 / 2: Load cart Delete: Rack [new line] End: max 0: zero T: tickets H: close
Font Size0.8
EmphasisMedium
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X22
Logic
Show Reading Page

5.8.29 Reading Sheet Title

The sheet now holds readings, tasks and files. Its heading changes to name the whole workshop, while the existing view attachment keeps showing it across the optional pages.

ObjectReading Sheet TitleAddDelete
Transform
Bounding Box > SizeX 22, Y 1
Text / UI
TextPUSH LAB / WORKSHOP
TextPUSH LAB / READINGS
Font Size0.8
EmphasisMedium
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X22
Logic
Show Workshop Detail

The earlier rail hand, weight hand and live gauge behaviors keep their existing cards. Their movement and measurement jobs have not changed.

5.9 Play It!

Predict the impulse ratio that will give unequal masses the same velocity change. Test it from rest, then compare both printed changes.

  • Begin with Defaults. Choose the maximum dial impulse, store it for Copper with V, then choose four for Blue. Press C, then Space. The default masses receive impulses in the same ratio as their masses, giving matching changes. Open Help to see the result.
  • Start Match again without delivering a new push to either cart. It waits despite the earlier successful paper. Make a fresh accepted push to answer this attempt.
  • Return with Home. Link both with L, choose a positive push and deliver it. Start Brake with B, reverse the next impulse, then push before the cart reaches its stop. Compare the immediate before and after readings.
  • Return again. Choose a positive impulse that gives Blue the target after velocity from rest. Start Target with G before pushing. Compare the paper with the completed result, checking the signed after velocity rather than its later live speed.
  • Press X to clear the task. Exploration continues. O opens the choices without starting a task on its own.
  • Change a load and a chosen impulse, then press R. The carts return from rest. Those choices remain while the printer empties and the goal clears. D restores defaults.
  • Release any cart or weight you are dragging, then press E to save a starting setup. Saving leaves motion and papers alone. Rearrange the load, then open the saved file with I. It returns from rest, clearing observations.
  • Open U and try the visible file controls. Press H: the whole sheet closes, leaving the bench visible. U reopens the file page. Open O and choose a task by pressing its label, then close with H again. Hidden labels should leave ordinary bench presses alone.

5.10 How It Works

The same impulse gave different changes when the masses differed. Separate impulses let you reverse that question: choose the change first, then choose an impulse suited to each mass.

The native body still supplies the measured answer. The goal watches one fresh paired observation, and history keeps it after the motion changes.

A starting setup keeps the apparatus for repeating an experiment. Checking every field before applying any live change lets a refused file leave the current experiment usable. That same pattern can protect a game’s loadout or level arrangement.

5.11 If It Didn’t Work

Copper keeps following the dial? Store its choice with V before turning the dial for Blue. Read both choices before pushing again, using the separate bench caption to check what each cart will receive. Linking with L deliberately restores the shared choice.

A goal still waits despite an earlier paper showing exactly the result you wanted? That is its freshness check. Make a newer accepted push with both readings valid. You can still inspect the earlier paper while the new attempt waits for its own answer.

A goal misses the first of two quick pushes? Keep Evaluate Workshop Goal directly after Record Pair Reading inside Push Workshop Pair. Restore that order so each accepted observation is judged before another can replace it.

Reset restores the wrong things? Compare the two Events in Reset Experiment Controls. Reset calls the Function. Defaults instead restarts Lab with its authored arrangement, rather than the loads you moved during play. Restore that distinction, then try the same chosen load again.

A setup opens with a missing weight? Check Restore Weight Setup on every weight resource and both named setup Events. Each copy needs the same identity it uses in Workshop Weights. Restore that connection before reopening the file.

A file is refused? Open U’s page and read the setupStatus message beside the file controls. The refusal is general. Keep the current experiment while checking the saved proposal.

Did you change Impulse Settings, Shared, maximum after saving that file? Tuning must match. Return to a matching project or save a new arrangement with today’s tuning, then try opening that new file.

Your own new file is refused too? Stop Lab and compare Apply Starting Setup with its card, beginning with the matching-settings checks. Check Restore Weight Setup’s attachments next. Run the completed Scene again and repeat E, rearrange, I to see whether the arrangement returns.

A label acts from the wrong page? Compare its visibility attachment and Object values with the card, then its response’s page check. Restore one mismatched value and test with the sheet closed too.

5.12 Challenge

Save an arrangement for someone else to investigate. Choose a load and a result you want them to predict, then let them choose the impulses. Compare their first paper with their prediction.

In the first chapter, two carts waited on quiet rails. Your workshop can now keep an arrangement and test a question. What will you ask it next?