TutorialsPush Lab

3  Deliver an Impulse

Goal

Choose a shared impulse, push both carts, and compare their changes in velocity.

Press Space to push both carts. Arrows choose the next impulse and sign. H opens the readings; Home returns the carts.

Push Lab, Chapter 3 finishedMyth project

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

3.1 The Idea

Blue rolls toward the stop. Copper follows below, more slowly, although the same push reached them together. Their answers differ.

A brief push gives an impulse, measured here in newton seconds, shown as N s. It changes a cart’s velocity, which includes direction: positive points right along the rail, and negative points left.

The same impulse changes the lighter cart’s velocity more because their masses differ. Think of pushing an empty shopping cart beside a loaded one. The load matters.

This workshop uses ideal horizontal tracks, with no friction slowing the carts. Gravity is zero, and the bodies cannot rotate. Native physics carries their motion after the push, along the rail until a stop intervenes.

The dial holds a future choice. This chapter keeps that choice separate from the action that delivers it.

The last distinction takes a little care. A cart may stop after hitting the rail end, while its earlier push reading still describes the moment it received the impulse. You’ll measure that moment before physics carries it onward.

3.2 The Plan

Remember the carts, choose the next push, then measure their answers. Identify Workshop Cart remembers the original pair. Choose Next Impulse and Turn Impulse Dial choose a magnitude; Choose Impulse Direction supplies its sign. Request Pair Push passes those choices to Push Workshop Pair.

Apply Cart Impulse measures each body around its native Apply Impulse Action. Show Measured Reading reveals the results. Native physics owns released motion, without another mover placing the cart each frame.

3.3 Set Up

Continue with your draggable carts and working Return button. Joining here? Download the Chapter 2 starting workshop. Open that file through File > Open Project… before adding this chapter’s pieces. The download above is already finished. Keep their existing settings and placements, using the kit’s pictures for the new controls.

Add the Commands in Input Manager and the Globals under Project Globals. Instance Set holds running copies. Leave the cart sets empty initially, so their registration Logic can fill them at creation. Blank starting entries mean empty, without typing undefined.

The setup card lists the new placements. Make each resource below before placing its copy in the Scene. Its Z-Index belongs to the Scene placement, while component ordering belongs inside the Object.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Workshop push-button
Workshop knob
Workshop lever
Reading Sheet Surface
Impulse Calibration
COMMANDS (Game Settings > Input Manager)
Push BothButton
KeybindingsSpace
Increase ImpulseButton
KeybindingsUp Arrow
Decrease ImpulseButton
KeybindingsDown Arrow
Maximum ImpulseButton
KeybindingsEnd
Zero ImpulseButton
Keybindings0
Push LeftButton
KeybindingsLeft Arrow
Push RightButton
KeybindingsRight Arrow
Workshop HelpButton
KeybindingsH
GLOBAL VARIABLES
$blueCartInstance Setstarts at
$copperCartInstance Setstarts at
$pushBatchNumberstarts at 0
$pushStatusTextstarts at Ready for an impulse.
$blueMassNumberstarts at 0
$blueAppliedImpulseNumberstarts at 0
$blueBeforeNumberstarts at 0
$blueAfterNumberstarts at 0
$blueDeltaNumberstarts at 0
$copperMassNumberstarts at 0
$copperAppliedImpulseNumberstarts at 0
$copperBeforeNumberstarts at 0
$copperAfterNumberstarts at 0
$copperDeltaNumberstarts at 0
$impulseMagnitudeNumberstarts at 4
$impulseDirectionNumberstarts at 1
$detailsOpenBooleanstarts at false
$blueCartRegisteredBooleanstarts at false
$copperCartRegisteredBooleanstarts at false
SCENE Lab: PLACE THESE
ObjectXY
Game Rules016
Push Button15.4754.1
Push Status125.925
with Z-Index = 25
Blue Push Reading1213.125
with Z-Index = 25
Copper Push Reading1210.625
with Z-Index = 25
Workshop Instructions123.5
with Z-Index = 25
Impulse Dial8.1254.075
Impulse Direction Lever124.925
Next Impulse8.1252.85
with Z-Index = 8
Reading Sheet128.7hidden
with Z-Index = 20
Reading Sheet Title1215.2
with Z-Index = 25
Help Control120.725
with Z-Index = 25
Impulse Dial Face8.1254.075
with Z-Index = 2

Keep the helper page nearby for Data Structures and Data Tables. Build them first. The experiment will remain quiet until the callers and Objects are connected.

3.4 Give the Readings a Shape

3.4.1 Impulse Reading

A push needs a small record of what happened. Impulse Reading holds the body’s measured mass and its horizontal velocity before and after the push.

Make this Data Structure with its named fields. A Function will return one record after each cart receives its impulse.

Data StructureImpulse Reading

An immediate native impulse measurement: mass in kg, and before/after signed horizontal velocity in m/s.

massNumberdefault 0
beforeNumberdefault 0
afterNumberdefault 0

3.4.2 Impulse Settings Entry

The dial needs limits. Impulse Settings Entry describes those two fields for the tuning table. The table comes next.

Data StructureImpulse Settings Entry

One row of the "Impulse Settings" Data Table.

maximumNumberdefault 40
incrementNumberdefault 0.1

3.4.3 Impulse Settings

The carts share one setting. Create Impulse Settings using the structure above, then use Add Row. Enter Shared in the Entry cell at the row’s left. The row position is separate. The maximum bounds the dial. The increment field sets the regular spacing between choices on its scale.

Data TableImpulse SettingsData Structure: Impulse Settings Entry
Row 0Shared
maximum40
increment0.1

3.4.4 Prepare Impulse Settings

An edited table should still leave the dial usable. Prepare Impulse Settings checks its row. If increment exceeds maximum, the Function reduces increment to that maximum. The dial retains a usable step.

Look for Check Data Row Exists before the branches. Its named result tells the Function whether to repair an existing row or make the missing one.

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

3.4.5 Select Shared Impulse

A hand may ask the dial for a point beyond its marked face. Select Shared Impulse keeps that request within the allowed range and rounds it to the chosen increment.

All magnitude controls call this Function, so they share the same limits. Its selected Local Variable holds a temporary answer during this call; impulseMagnitude keeps the chosen result for the workshop.

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

The choice has a home.

3.5 Remember the Actual Pair

3.5.1 Cart Press Input

The input helper now needs to recognize controls on the optional sheet. Import the new supplied file into the existing Cart Press Input Library. Keep its wiring unchanged.

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

3.5.2 Identify Workshop Cart

The push must reach the carts standing on these rails. An Instance Set remembers them.

Identify Workshop Cart fills the matching empty set when its cart appears. The registration flag protects the identity of the experiment’s original pair. Delete Blue and create another copy: the set loses Blue, but the registration flag remembers its original owner. A push still reports that the original cart is missing.

Declare cartNumber here. The Object values below choose which place each cart claims in the pair. The Collider reference works as it did last chapter.

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

3.5.3 Blue Cart

Blue claims the upper cart’s place. Attach Identify Workshop Cart, then select it in Blue Cart’s Logic workspace. Match its supplied cartNumber row to the Changes card, keeping the earlier drag attachment.

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

3.5.4 Copper Cart

Copper claims the other place. Use the same attachment on Copper Cart with its own cartNumber value. Its lane values and load pictures stay with the lower cart.

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
Place Cart on Rail > Components > Collider (Collider)Collider
Identify Workshop Cart > Components > Collider (Collider)Collider
Sprite(additional component)
NameRear Load
SpriteWorkshop weight-2
Z Index Within Object6.04
Transform > PositionX -1.125, Y 0.825
Transform > SizeX 0.625, Y 0.95
Sprite(additional component)
NameMiddle Load
SpriteWorkshop weight-2
Z Index Within Object6.05
Transform > PositionX -0.375, Y 0.825
Transform > SizeX 0.625, Y 0.95
Sprite(additional component)
NameFront Load
SpriteWorkshop weight-5
Z Index Within Object6.08
Transform > PositionX 0.375, Y 0.9
Transform > SizeX 0.75, Y 1.1
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

The pair is registered.

3.6 Deliver and Measure the Push

3.6.1 Apply Cart Impulse

The body is moving, or waiting where you left it. Apply Cart Impulse reads its mass and horizontal velocity, delivers the impulse, then reads the new velocity. It returns that small Impulse Reading record.

The before reading comes first, while the body still has its earlier velocity. Apply Impulse changes the body through native physics. The after reading follows immediately, before later travel or a stop can replace it. Direction zero points right along the rail. A negative Strength applies the impulse in the opposite direction.

Its cart Parameter uses Instance Set. Use that type in the Function’s Parameters, and leave its default empty. The caller supplies the exact cart set. Choose Impulse Reading as Return Type, then match its returned fields.

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

3.6.2 Push Workshop Pair

Both carts must be free before either receives a push. Push Workshop Pair checks the pair first. A held or missing cart refuses the whole request, leaving the other cart unpushed.

Once accepted, each call to Apply Cart Impulse returns its own measurement. The named bluePush and copperPush results feed the corresponding Globals. Their velocity changes come from after minus before.

Both measurements must exist before the batch counter advances to announce another accepted push. The click answers an accepted push, while pushStatus gives the sheet a reason when a request is refused.

FunctionPush Workshop Pair

Pushes the exact workshop pair once only when both hands are clear. A held cart rejects the whole push.

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
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
$pushBatch
Operator
+=
Value
1
16Change Variable
Variable
$pushStatus
Value
'Impulse applied to both carts.'
17Play Workshop ClickFunction
accepted
Yes
18Otherwise
19Change Variable
Variable
$pushStatus
Value
'Release both carts before pushing.'
20Otherwise
21Change Variable
Variable
$pushStatus
Value
'Both workshop carts are needed for Push Both.'

3.6.3 Request Pair Push

Space and the blue button need to reach the same experiment. Request Pair Push sends both routes to the paired Function, using the registered cart references.

The magnitude and direction multiply into a signed impulse. Both carts receive that same signed choice here. Match the Command field to Push Both, keeping the Event’s displayed name as its card shows.

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

The push has one route through physics, shared by both keyboard and pointer requests.

3.7 Choose the Next Push

3.7.1 Choose Next Impulse

Arrow keys change the next choice while the carts keep rolling. Choose Next Impulse sends magnitude requests through the limiting Function. Its direction Commands change the sign separately.

Creation checks the choice too, as do restoration and edits to the tuning table. The Load Events prepare these controls for saved experiments later; this chapter adds no save control. Its range stays bounded. None of these Events applies 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

3.7.2 Game Rules

The bench needs a place for those shared controls. Game Rules carries Request Pair Push and Choose Next Impulse without a visible picture. Place it using the setup card.

ObjectGame Rules
Logic
Request Pair Push
Choose Next Impulse

You can test now. Run Lab, press Space, and watch Blue draw ahead of Copper. Home brings both back.

3.7.3 Turn Impulse Dial

Your pointer turns the knob by moving across its width. Turn Impulse Dial converts that horizontal place into the next magnitude. It shares the keyboard’s limiting Function.

Get the dial Event headers. Install this Myth Pack through File > Install Myth Pack… > Add to This Project. Resources now contains Turn Impulse Dial. Open that imported Logic Component instead of making another resource with the same name. It contains only the first Event, with empty Released and Turning Modes. Make its Variables and fill the Actions from the cards below, then add the remaining Events.

Keep the supplied Mouse Press trigger for Released and Mouse Held trigger for Turning. Myth’s Change Event command changes all Modes together, so this small prepared resource keeps their separate input moments. You still build the behavior inside them.

The prepared Released and Turning Modes belong to one named Event. Released begins the gesture. Turning follows your held pointer across the marked face until you let go. Add their Actions without creating another Event or changing either supplied trigger.

These blocks belong together. Fill the Actions inside those two existing Modes.

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

Letting go ends the dial’s hand, as do the same interruptions that released last chapter’s carts. Rotation after Load reflects the stored magnitude, so the knob shows the choice that returned.

Logic ComponentTurn Impulse Dialcontinued
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

Now the knob follows other ways of choosing too. A changed magnitude turns it, and the wheel adjusts it while your pointer is over its face. Opening Help or returning the carts ends a remaining dial hold.

Logic ComponentTurn Impulse Dialcontinued
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

3.7.4 Impulse Dial

The painted knob needs an Object before it can receive those pointer Events. Attach both listed Logic Components. They share pressSelected, as Return did.

Match the supplied Shared Variable rows on this attachment. They describe its horizontal span.

ObjectImpulse Dial
Transform
Bounding Box > SizeX 2.05, Y 2.05
Sprite
Z Index Within Object5
SpriteWorkshop knob
Transform > SizeX 2.05, Y 2.05
Logic
Turn Impulse Dial
Listen for Control Press
Shared Variables
dialLeft > TypeNumber
dialLeft > KindConstant
dialLeft > Value7.1
dialWidth > TypeNumber
dialWidth > KindConstant
dialWidth > Value2.05

3.7.5 Choose Impulse Direction

The lever leans toward the next push direction. Pressing it reverses the sign, with the same quiet click as the Return control. Choose Impulse Direction also turns the picture when a keyboard Command changes that choice.

It changes the next push alone. A cart already moving keeps its velocity until another impulse or contact acts.

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

3.7.6 Impulse Direction Lever

The lever sits between choosing a strength and delivering it. Check its tilt before pushing. The same listener that serves the knob recognizes this separate handle.

ObjectImpulse Direction Lever
Transform
Bounding Box > SizeX 0.875, Y 2.1
Sprite
Z Index Within Object6
SpriteWorkshop lever
Transform > SizeX 0.875, Y 2.1
Logic
Choose Impulse Direction
Listen for Control Press

3.7.7 Push Button Response

The blue button delivers it. Push Button Response sends pushRequested only when this button received the press. Request Pair Push listens.

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

3.7.8 Push Button

The blue face gives your chosen push a place to land. Push Button waits beside the dial, so choosing and delivering remain separate gestures. Build its attachments before placement.

ObjectPush Button
Transform
Bounding Box > SizeX 1.875, Y 1.875
Sprite
Z Index Within Object5
SpriteWorkshop push-button
Transform > SizeX 1.875, Y 1.875
Logic
Push Button Response
Listen for Control Press

Your controls can choose and deliver a push.

3.8 Open the Readings

3.8.1 Toggle Workshop Readings

The bench can show its workings without stopping the experiment. Toggle Workshop Readings opens the sheet. The carts keep moving underneath the sheet, carrying on with the experiment you began.

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

3.8.2 Open Workshop Readings

H opens the sheet, then closes it again. Open Workshop Readings gives the Help label the same response. Its pointer Event shares the Object’s selection value with Listen for Control Press.

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

3.8.3 Help Control

A small Help label waits below the apparatus. Make its Text / UI and attach both Logic Components before placing it. It stays available in both views.

ObjectHelp Control
Transform
Bounding Box > SizeX 2.2, Y 0.8
Text / UI
TextHelp
Font Size0.35
Color#F4E8CF
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X2.2
Logic
Open Workshop Readings
Listen for Control Press

3.8.4 Show Workshop Detail

Some labels belong on the bench; others belong on the sheet. Show Workshop Detail compares the view with each Object’s showOnOpen value to decide whether to draw it.

Declare showOnOpen in this Logic’s Shared Variables as its card shows. Attaching the Logic supplies the row on each Object. Start with Yes for sheet elements. The cards for the bench readout and dial face instead specify No.

Logic ComponentShow Workshop DetailAttach to: Push Status, Workshop Instructions, Next Impulse, Reading Sheet, Reading Sheet Title, 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

3.8.5 Reading Sheet

The sheet covers the workshop. Its Scene placement starts hidden, as the setup card says. Give it showOnOpen Yes and attach Show Workshop Detail to reveal it with Help.

ObjectReading Sheet
Transform
Bounding Box > SizeX 1.875, Y 1.875
Sprite
SpriteReading Sheet Surface
Transform > SizeX 24, Y 14.6
Logic
Show Workshop Detail

3.8.6 Reading Sheet Title

The heading names the view above the measurements. Give this Object showOnOpen Yes too. Its placement Z-Index puts its text above the sheet’s surface.

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

3.8.7 Workshop Instructions

The controls stay beside the readings when Help opens. Workshop Instructions carries that short reminder, with Show Workshop Detail and showOnOpen Yes. Replace each [new line] marker with a line break in its Text field. Do not type the marker itself.

ObjectWorkshop Instructions
Transform
Bounding Box > SizeX 0.8, Y 0.8
Text / UI
TextDrag carts; release from rest. [new line] Space: Push Home: Return Arrows: J / sign [new line] End: max 0: zero [new line] Experiment continues. H: close
Font Size0.8
EmphasisMedium
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X22
Logic
Show Workshop Detail

3.8.8 Push Status

A refused push needs a reason the player can find without examining the Logic. Push Status reads the workshop’s message on the sheet. Give it showOnOpen Yes, so the reason appears when you open Help. If a push is refused during play, open Help to read that reason.

ObjectPush Status
Transform
Bounding Box > SizeX 0.8, Y 0.8
Text / UI
Text{$pushStatus}
Font Size0.8
EmphasisMedium
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X22
Logic
Show Workshop Detail

The sheet has room for the experiment’s answer, ready for a measured push to fill it.

3.9 Show the Answer

3.9.1 Set Reading Visibility

Before a push, there is no measured answer to show. Set Reading Visibility reveals a caption only when the sheet is open and an accepted batch exists. A genuine zero impulse still counts as an observation.

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
ACTIONS
1If$detailsOpen && $pushBatch > 0
Then
2Set Visible
Applies to
caption
Visible
true
3Otherwise
4Set Visible
Applies to
caption
Visible
false

3.9.2 Show Measured Reading

A new push replaces the latest measurement. Show Measured Reading refreshes its caption when the batch changes, and when the sheet opens or a saved experiment returns.

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
When Created
WhenCreate
1Set Reading VisibilityFunction
caption
self
On Variable Changed · Push Batch
WhenVariable ChangedGlobal Variable: pushBatch
1Set Reading VisibilityFunction
caption
self
On Load:succeeded
Whenload:succeededCustom Event
1Set Reading VisibilityFunction
caption
self
On Variable Changed · Details Open
WhenVariable ChangedGlobal Variable: detailsOpen
1Set Reading VisibilityFunction
caption
self

3.9.3 Blue Push Reading

Blue’s caption gathers its mass, applied impulse and measured velocities. Attach Show Measured Reading here. These values describe the latest push, even after the cart reaches a stop.

ObjectBlue Push Reading
Transform
Bounding Box > SizeX 0.8, Y 0.8
Text / UI
TextBlue: {$blueMass} kg | J {$blueAppliedImpulse} N s [new line] v {round($blueBefore * 100) / 100} -> {round($blueAfter * 100) / 100} m/s | change {round($blueDelta * 100) / 100} m/s
Font Size0.8
EmphasisMedium
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X22
Logic
Show Measured Reading

3.9.4 Copper Push Reading

Copper’s caption follows the same pattern with the lower cart’s values. Keep the Globals distinct.

ObjectCopper Push Reading
Transform
Bounding Box > SizeX 0.8, Y 0.8
Text / UI
TextCopper: {$copperMass} kg | J {$copperAppliedImpulse} N s [new line] v {round($copperBefore * 100) / 100} -> {round($copperAfter * 100) / 100} m/s | change {round($copperDelta * 100) / 100} m/s
Font Size0.8
EmphasisMedium
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X22
Logic
Show Measured Reading

3.9.5 Next Impulse

The bench keeps a smaller readout for the next signed choice. Use Show Workshop Detail here with showOnOpen No, as the Object card shows below. Past measurements stay on the sheet.

ObjectNext Impulse
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 Workshop Detail
Shared Variables
showOnOpenNo

3.9.6 Impulse Dial Face

The face stays fixed. Impulse Dial Face carries the marked picture and the separate Text / UI labels. Keep those labels on this Object, so the knob turns without taking them along. Test the knob first. After trying the controls, return here to finish those labels before the next chapter.

Give it Show Workshop Detail and showOnOpen No. The knob sits in front.

ObjectImpulse Dial Face
Sprite
SpriteImpulse Calibration
Transform > SizeX 4, Y 4
Text / UI
Text0
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > Size X0.65
Transform > PositionX -1.02530483272049, Y -1.02530483272049
Logic
Show Workshop Detail
Text / UI(additional component)
NameImpulse 5
Text5
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX -1.42213865658468, Y -0.282880966923386
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 10
Text10
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX -1.33962532214137, Y 0.55489097692938
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 15
Text15
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX -0.805576837878423, Y 1.20563093783869
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 20
Text20
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX 0, Y 1.45
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 25
Text25
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX 0.805576837878423, Y 1.20563093783869
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 30
Text30
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX 1.33962532214137, Y 0.55489097692938
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 35
Text35
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX 1.42213865658468, Y -0.282880966923386
Transform > Size X0.65
Text / UI(additional component)
NameImpulse 40
Text40
Font Size0.2
Color#39291B
AlignmentCenter
Text BoundsWrap to Width
Transform > PositionX 1.02530483272049, Y -1.02530483272049
Transform > Size X0.65
Shared Variables
showOnOpenNo

3.9.7 Place Cart on Rail

Opening the sheet should end a hand still holding a cart. Add the marked Event to the existing Place Cart on Rail. The cleanup is familiar.

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

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

The bench can show what its push did.

3.10 Play It!

Predict which cart will answer more strongly when both receive the same signed impulse. Begin a fresh run, then compare the readings with their motion.

  • Press Space once from rest, then H. Blue shows before zero and after four; Copper shows before zero and after four tenths of a meter per second.
  • Close the sheet and let Blue reach its stop. Open Help again. The latest push reading still describes its immediate after velocity.
  • Press Home, then push through the blue button. It uses the same choice and gives both carts another measured push.
  • While Copper rolls, change the magnitude with Up Arrow or the dial. Its motion stays unchanged.
  • Press Home, choose Left Arrow, and push. Both carts initially move left, with negative changes shown on the reading sheet.
  • Hold a cart and press Space. The whole push is refused, leaving the released cart’s velocity unchanged as well. Release it, open Help, and look for the release message.
  • Press Home, choose zero with 0, and push. An accepted zero push records no velocity change, while End chooses the maximum again.
  • Open and close Help with H and with its label. The experiment continues while its sheet is open.

Before leaving, return to Impulse Dial Face if you postponed its labels. Finish those fixed marks while keeping the knob separate.

3.11 How It Works

The dial holds a choice until a push delivers it to both native bodies. The reading keeps the moment.

For these carts, change in velocity equals signed impulse divided by actual mass: delta v = J / m. The same impulse therefore gives the heavier cart a smaller change. The change adds to existing velocity.

A later stop changes current motion while leaving the earlier observation alone. This separation also lets a game display a hit’s effect after the body has traveled onward.

3.12 If It Didn’t Work

Space does nothing? Check Game Rules is placed in Lab. Then compare Request Pair Push’s Command field with Push Both. Restore that connection and try a fresh run, with both carts released.

Only a missing-cart message appears? Compare the carts’ cartNumber values and Identify Workshop Cart attachments. Each must claim its own reference. Run again after that correction, letting creation fill both empty sets.

The knob turns but carts keep their old speed? That is the next-push choice at work, waiting for the action that delivers it. Press the blue button. Watch the new reading after that action, comparing it with the one you saw before.

The dial keeps following after release? Compare its Mode changes with the release and interruption Events. They all return to Released. Restore that destination and the knob should wait for another press.

Help opens without readings? Make a push with both carts released. If the sheet still stays blank, compare Show Measured Reading and its caption attachment. The opening zeros deliberately stay hidden until an observation exists.

Bench labels disappear at the wrong time? Compare each Object’s showOnOpen value. The dial face and Next Impulse use No; sheet elements use Yes. Restore the mismatched value.

3.13 Challenge

Choose a push that slows a moving cart without reversing it. Predict its signed change before pressing the button, then compare the sheet’s before and after values. What choice brings it nearer rest?

Both carts answer a chosen push, and your workshop can measure what happened. Next, you’ll change their loads and watch the instruments.