WAMONH BallPaths

This tech tip examines the BallPaths specific to the Weird Al module.

The information here was verified against WAMONH 1.5.0.0 with module driver version 1.3.0.0.

The documentation for the module API is excellent. You can find it in %HOMEDRIVE%%HOMEPATH%\.multimorphic\P3\ModuleDrivers\WAMONH\0.9.4.5\UsageInstructions.txt

For the list of BallPaths, see the module definition file in %HOMEDRIVE%%HOMEPATH%\.multimorphic\P3\ModuleDrivers\WAMONH\0.9.4.5\WAMONH.json

For an introduction to BallPaths in general, see the tech tip on Heist BallPaths.

BallPath API

The BallPath API for WAMONH is an improvement over the BallPath API for Heist. See Appendix A for a comparison of the two APIs.

To enable a BallPath on WAMONH, send the event Evt_EstablishBallPath with the BallPath name as the event argument. The current BallPath for the same Entrance will be replaced by the new BallPath. You can see the list of valid BallPath names in the module definition file.

PostModeEventToModes("Evt_EstablishBallPath", "<BallPathName>");

For example:

PostModeEventToModes("Evt_EstablishBallPath", "OuterLeftToOuterRight");

Just be careful not to mistype the BallPath name because the error will be silently ignored.

A static BallPath is when the entrance has only one possible exit. For example, this could be a BallPath for a standup target. Since there is no way to change a static BallPath, it is always enabled. You can establish a static Ballpath if you wish, though this is rather pointless.

Note the BallPath request will be deferred if a custom launch or ball search is in progress. The module driver is smart enough to re-establish the correct BallPaths after the custom launch or ball search ends.

The event sent when a shot is started is:

PostModeEventToModes("Evt_ShotStarted_<EntranceName>", "<EntranceName>");

The event sent when a shot is successfully completed is:

PostModeEventToModes("Evt_ShotMade_<BallPathName>", "<ExitName>");

These events are well documented in the module definition file as p3.BallPaths["<BallPathName>"].StartedEvent and  p3.BallPaths["<BallPathName>"].CompletedEvent respectively.

Diverters

WAMONH has 6 servos: 3 diverters (top, hamster and mezzanine), 2 ramp lifts (right and spiral) and the camera sweep.

The top diverter can be in one of 3 states:

The hamster diverter can be:

The mezzanine diverter can be:

Internally, the mezzanine diverter is known as the CameraLaneDiverter.

The diverter API is not documented. It’s not hard to find out if you use the universal event trace trick from this tech tip. Hint: look for Evt_Servo<ServoName><Position>.

On WAMONH, there is no need to use the internal diverter API. It is much better to control the diverters by establishing the desired BallPaths.

The servo values corresponding to each diverter position are given by GameAttributes configurable in the service menu under Settings/Mechs/Diverters. Within the simulator, they will take their default value of 180 because the simulated module has no local settings. On the physical machine, the diverter GameAttributes will have real values since those are stored physically on the module.

The diverter GameAttributes are:

        SettingRightRampLiftDown

        SettingRightRampLiftUp

        SettingSpiralRampLiftDown

        SettingSpiralRampLiftUp

        SettingHamsterLaneDiverterClosed

        SettingHamsterLaneDiverterOpen

        SettingCameraLaneDiverterClosed

        SettingCameraLaneDiverterOpen

        SettingTopDiverterLeft

        SettingTopDiverterDown

        SettingTopDiverterRight

        SettingCameraSweepLeft

        SettingCameraSweepCenter

        SettingCameraSweepRight

There is no need to adjust these values unless you have a problem with one of the diverters.

BallPaths

The table below describes all BallPaths in WAMONH.

The BallPath name is implicit in the table to save space. When the EntranceName and ExitName differ, the BallPath name is <EntranceName>To<ExitName>. When the EntranceName is the same as the ExitName, the BallPath name is <EntranceName>, this is indicated by leaving the ExitName blank in the table.

A * in the first column indicates a BallPath that behaves unexpectedly. See the comment below.

EntranceName

ExitName

Comment

OuterLeft

OuterRight

Unhindered left to right outer loop

Pops

Rear magnet grab and drop below to pop bumpers

RearHole

Rear magnet grab and fling up to rear hole

OuterRight

OuterLeft

Unhindered right to left outer loop

Pops

Rear magnet grab and drop below to pop bumpers

RearHole

Rear magnet grab and fling up to rear hole

LeftRamp

RightInlane

Left ramp always leads to right inlane

MiniLoopRight

MiniLoopLeft

Loop under camera from right to left

MiniLoopLeft

MiniLoopRight

Loop under camera from left to right

CrossLeft

OuterLeft

Cross under the left ramp from right to left

CrossRight

OuterRight

U-turn under the ramps to right outer loop

*

SpiralReject

Up spiral ramp and back down again

HamsterLock

Up spiral ramp to hamster wheel.

Hamster wheel must be controlled separately.

LeftInlane

Up spiral ramp, to right of mezzanine, to left inlane

MezzLoop

Up spiral ramp, to skywalk, to left side of mezzanine loop.

RearHole

Hole at far top between the pop bumpers

SecretHole

Hole to the left of PopBumperL in outer loop

PopEscape

Hole between PopBumperR and PopBumperB

DropTarget

Drop target dropped. Must be reset separately.

DropHole

Hole behind the drop target

VUK1Entry

VUK1EntryFinished

Hole half-way on left outer loop

*

RightRamp

Cannot be established. Appears in other RightRamp BallPahs.

*

SpiralReject

Up right ramp, down spiral ramp

HamsterLock

Up right ramp to hamster wheel.

Hamster wheel must be controlled separately.

*

LeftInlane

Up right ramp, to right of mezzanine, to left inlane

*

MezzLoop

Up right ramp, to skywalk, to left side of mezzanine loop.

MezzLoop

Mezzanine loop, cannot distinguish direction.

*

MezzRight

MezzRightTarget

Opens access to mezzanine round target. Never completes.

CameraLock

Mezzanine to camera lock.

Camera must be controlled separately.

MezzExit

Drain from mezzanine to left inlane.

CameraTarget

UHF standup target

HamsterTarget

Harvey round standup target

FoodTargetL

Ketchup standup target on mezzanine

FoodTargetR

Mustard standup target on mezzanine

MezzTarget

Red round standup target on mezzanine

LeftRampTarget

V standup target

LeftSideLoopTarget

I standup target

LeftMiniLoopTarget

P standup target

CenterTargetL

Supplies standup target facing PopBumperB

CenterTargetH

Closet standup target facing PopBumperB

PopBumperR

Right pop bumper

PopBumperL

Left pop bumper

PopBumperB

Bottom pop bumper

CameraLockFront

First ball locked

CameraLockMiddle

Second ball locked

CameraLockBack

Third ball locked

Keep in mind a BallPath that never completes can still be useful to control the diverters.

* CrossRightToSpiralReject starts 4 times for a single shot and never completes.

* RightRamp BallPath cannot be established. If you do, it does nothing leaving the current RightRamp BallPath in place. This BallPath is started and completed as part of the completion of RightRampToSpiralReject, RightRampToLeftInlance and RightRampToMezzLoop but not RightRampToHamsterLock. This BallPath sends an extra started event Evt_ShotStarted_RightRamp with the event argument "Ramp". Notice this is an invalid EntranceName. The completed event is Evt_ShotMade_RightRampToRightRamp.

Just be careful when implementing the Evt_ShotStarted_RightRamp event handler because it will be called twice in quick succession: once as expected with the valid EntranceName "RightRamp" and again with the invalid EntranceName "Ramp".

* RightRampToSpiralReject moves the top diverter to block access to the skywalk from the right ramp. This BallPath is never started nor completed.  When making this shot, the started event is Evt_ShotStarted_RightRamp and the completed event is Evt_ShotMade_RightRampToRightRamp. This is surprising because the ball drops down the spiral ramp instead. The completed event is not unique to RightRampToSpiralReject. The application will need to remember which RightRamp BallPath is active if it needs to uniquely identify that shot.

* RightRampToLeftInlane works as expected except there are extra BallPath events between the started event and the completed event:

Evt_ShotStarted_RightRamp with event argument "RightRamp”

Evt_ShotStarted_RightRamp with event argument "Ramp"

Evt_ShortMade_RightRampToRightRamp

Evt_ShotStarted_MezzExit

Evt_ShotMade_MezzExit

Evt_ShotMade_RightRampToLeftInlane

* RightRampToMezzLoop works as expected except it completes twice and there are extra Ballpath events:

Evt_ShotStarted_RightRamp with event argument "RightRamp”

Evt_ShotStarted_RightRamp with event argument "Ramp"

Evt_ShotStarted_RightRamp with event argument "RightRamp”

Evt_ShortMade_RightRampToRightRamp

Evt_ShortMade_RightRampToMezzLoop

Evt_ShortMade_RightRampToMezzLoop // completes a second time

Evt_ShotStarted_MezzLoop

Evt_ShotMade_MezzLoop

Beware the duplicate Evt_ShortMade_RightRampToMezzLoop if you score points in your event handler. An easy solution is to score half the points you truly intend.

* MezzRightToMezzRightTarget moves the mezzanine diverter to give access to the red round standup target from the mezzanine flipper. This BallPath is never started nor completed. Hitting that target starts and completes the MezzTarget BallPath instead.

Hamster Wheel

CrossRampToHamsterLock and RightRampToHamsterLock are the two BallPaths that feed the hamster wheel. Those BallPaths control the diverters but not the wheel itself.

To spin the wheel and keep the ball in, call PostModeEventToModes(Evt_HamsterWheelLock", null);

To spin the wheel and release the ball, call PostModeEventToModes(Evt_HamsterWheelRelease", null);

You can stop spinning the wheel by calling PostModeEventToModes(Evt_HamsterWheelStop", null);

A good time to stop the wheel after a release is when you receive a Grid Event. It’s a good idea to implement a maximum timer in case the release fails.

See UsageInstructions.txt for details.

Camera Lock

MezzRightToCameraLock is the only BallPath feeding the camera. The BallPath controls the diverters but not the camera.

To make sure the ball can enter the camera, sweep the camera to the center position:

PostModeEventToModes("Evt_ServoCameraSweepServoCenter", true);

To release locked balls, sweep the camera to the left position and stay there at least 1 second per ball ejected:

PostModeEventToModes("Evt_ServoCameraSweepServoLeft", true);

PostModeEventToModes("Evt_CameraRelease", numBallsToRelease);

where numBallsToRelease is an integer.

See UsageInstructions.txt for details on programming the camera and how to keep track of the number of locked balls. This documentation is truly excellent.

Appendix A : Comparison with Heist

The following table compares the BallPath API for Heist versus WAMONH.

Heist

WAMONH

Low-level servo API

Not documented, use BallPaths instead.

PostModeEventToModes("Evt_AddPathByName", new List<string>{ballPathEntrance, ballPathExit});

PostModeEventToModes("Evt_EstablishBallPath", ballPathName);

PostModeEventToModes("Evt_AddPathsByName", new List<List<string>> {

   new List<string> {ballPathEntrance1, ballPathExit1},

    …,

   new List<string> {ballPathEntranceN, ballPathExitN}

});

Send multiple Evt_EstablishBallPath events.

PostModeEventToModes("Evt_ResetAllPaths", "");

Send multiple Evt_EstablishBallPath for BallPaths marked as Default.

PostModeEventToModes("Evt_CachePaths", key);

PostModeEventToModes("Evt_ApplyCachedPaths", key);

Not Available but BallPaths are restored after a custom launch or ball search.

Events sent when a shot is completed:

PostModeEventToModes("Evt_<EntranceName>Started", "");

PostModeEventToModes("Evt_<EntranceName>Completed", "<ExitName>");

PostModeEventToModes("Evt_Shot_<EntranceName>To<ExitName>", "<ExitName>");

PostModeEventToModes("Evt_Shot_<EntranceName>", "<ExitName>");

PostModeEventToModes("Evt_ShotHit<EntranceName>", "<EntranceName>To<ExitName>");

Events sent when a shot is completed:

PostModeEventToModes("Evt_ShotStarted_<EntranceName>", "<EntranceName>");

PostModeEventToModes("Evt_ShotMade_<BallPathName>", "<ExitName>");

Logs error when adding invalid EntranceName,ExitName BallPath.

Ignores error when establishing an invalid BallPath, can pick an unrelated BallPath.