# DOF Events

If DOF is installed on your system, PinballY generates DOF events to trigger effects from your feedback devices (such as solenoids and flasher lights). This will fire flashers and other devices on certain events, such as when you switch between tables in the table list.

DOF integration is automatic. To take advantage of it, just make sure that DOF is installed and that your .ini files from the DOF Config Tool are up to date. The PinballY definitions were added to the Config Tool database in late July 2018, so you'll need to generate and download fresh copies if your current .ini files are older than that.

You can disable PinballY's DOF usage entirely via the DOF Options page in the Settings dialog.

## DOF setup

If you use a "cabinet config" file with DOF, it's important to create a DOF global config file for PinballY. DOF requires a separate global config file for each program. The DOF global config file for PinballY is called GlobalConfig_PinballY.xml.

This is only needed if you're already using a global config file for other programs. That file must be set up manually, so if you never went through that manual process for other programs, you don't have to do it now. The global config is generally only required if you have certain hardware devices that DOF can't detect automatically, such as addressable LED light strips.

The easiest way to create the PinballY global config file is to copy your existing global config for B2SServer (that's the one that Visual Pinball uses, so most people who need the file at all have the B2SServer file):

- Open your main DOF install folder
- Open the Config subfolder
- Make a copy of GlobalConfig_B2SServer.xml
- Rename the copy GlobalConfig_PinballY.xml

In the future, if you make any changes to any of your global config files, remember to make the same changes to your GlobalConfig_PinballY.xml file while you're at it. (It's not ideal that we have to make duplicate changes like that, but unfortunately that's just the way DOF is designed.)

If you don't create a GlobalConfig_PinballY.xml file, DOF uses its default option settings for PinballY. That's fine in most cases; the main exception is when you have certain types of hardware devices in your DOF setup that DOF can't discover on its own, particularly "smart" LED strips (the "addressable" kind, where each LED can be set to a separate color). In those cases, DOF needs a cabinet config file to find the special devices, and the way it finds the cabinet config file is through the global config file. So, if DOF is partially working on your system, but isn't using your smart LED strips (or other individual devices), you probably just need to create the PinballY copy of the global config file, as described above.

## Where to find DOF documentation

- A full reference to the DOF Config Tool syntax: Pinscape Build Guide > DOF Event Codes
- General DOF background and setup: Pinscape Build Guide > DOF
- DOF's own documentation, newest version, but abandoned before officially finished: pinball.weilenmann.net/docu/DirectOutputWIP/index.html
- DOF's own documentation, older version, somewhat out of date, but the last one officially "finished": directoutput.github.io/DirectOutput/

## How PinballY communicates with DOF

PinballY and DOF communicate using "named events". A named event is an abstract label that PinballY defines to represent some particular action in the program. All of PinballY's named events are listed in the sections below. They all start with the prefix PBY to help clarify that they're PinballY custom events.

PinballY's custom events represent abstract program actions, not particular physical effects in DOF. So, for example, you won't find a PBY event for "turn on the shaker motor". The PinballY events all relate to things that happen in the PinballY UI, such as "user pressed the left flipper button" (PBYFlipperLeft) or "a new game was selected" (PBYGameSelect).

So how does DOF turn these abstract PinballY UI events into physical device effects? How does DOF know that we want to fire the left flipper solenoid when you press the left flipper button, for example, or flash a pattern of lights when you navigate to a new game? Those associations come from the DOF Config Tool. In fact, this is really the whole point of the DOF Config Tool: it lets you specify the associations between abstract program events and physical device effects.

The full details of setting up these associations in the Config Tool are beyond the scope of what we can cover here, so you should follow the DOF documentation links above if you want to learn more. The link you'll probably want to look at first is the Pinscape Build Guide's DOF Event Codes chapter, since that's all about exactly this subject. (It's also the only comprehensive reference to the Config Tool syntax that I'm aware of.)

The DOF Config Tool's database already includes a set of pre-defined rules for the PinballY custom events, so you should see DOF effects fire automatically when you use PinballY, as long as your config files are all up-to-date. You can also fully customize the DOF effects by editing the rules defined for the pseudo-table called PinballY in the Config Tool. (The DOF rules are defined on a game-by-game basis, since DOF thinks in terms of pinball simulation. So programs like PinballY that aren't really pinball simulators at all, but which still want to use DOF effects, have to pretend to be pinball games.)

## Customizing DOF effects

You can customize all of PinballY's DOF effects via the DOF Config Tool.

The Config Tool's database includes a predefined set of effects for PinballY, so you don't have to do anything to use the standard effects other than making sure your .ini files are up-to-date. If you want to customize anything, though, the Config Tool lets you override any of the default effects with your own custom settings.

Here's how you can access the PinballY settings in the DOF Config Tool:

- In your Web browser, open the DOF Config Tool
- Log in
- Click Table Configs in the top navigation bar
- Select PinballY from the Table Names drop list

All of the PinballY DOF effects are defined under this "PinballY" pseudo-table. As far as DOF is concerned, PinballY is just another pinball table. The lists below show all of PinballY's custom named events - they all start with PBY as short-hand to clarify that they're PinballY-specific.

When looking at the DOF Config Tool rules for the PinballY pseudo-table, there are a couple of special syntax elements you should be aware of:

- First, the Config Tool uses a $ prefix to signify named effects, so you have to add the $ prefix to the names in the lists below. For example, you'd write $PBYWheelNext in the Config Tool field if you want something to trigger on a "wheel next" event.
- Second, the special syntax @allrgb@ in a rule lets you use the RGB coloring for the device where the rule appears that's associated with the game currently selected in the PinballY wheel. For example, putting @allrgb@ in the "RGB Flippers" field makes the flipper buttons light up in the colors for whichever table is currently selected in the PinballY wheel display. This special syntax can only be used in RGB device rules.

For more information on the Config Tool rule syntax, refer to the DOF documentation links above, particularly DOF Event Codes in the Pinscape Build Guide.

### Events

Each time something DOF-worthy happens in the PinballY user interface, PinballY fires a named DOF event. For example, when you press the Next button (usually the right flipper button) to switch to the next game, PinballY fires a PBYWheelNext event.

"Fires an event" means that PinballY briefly pulses the event ON and then OFF. More technically, ON means that the event's "brightness" value is set to 255, and OFF means that it's set to 0. We put "brightness" in quotes because these events don't truly represent anything with a brightness or intensity; they're just arbitrary labels for discrete UI actions. In any case, you don't normally have to worry about the numeric brightness in the Config Tool syntax anyway, since what usually matters when you're writing the rules is just that an event was switched between OFF (0) and ON (any non-zero value).

Here's a list of the events that PinballY fires:

- PBYAttractA1 through PBYAttractA5: When attract mode is running, these events are fired in order (1 through 5) at 1-second intervals. After reaching 5, the counter loops back to 1. This can be used to create a series of events that runs on a 5-second loop.
- PBYAttractB1 through PBYAttractB60: When attract mode is running, these events fire in order (1 through 60) at 1-second intervals, looping back to 1 after reaching the last event. This can be used to create a series of events that runs on a 60-second loop.
- PBYAttractR1 through PBYAttractR5: When attract mode is running, these events fire in random sequence and at random intervals. These can be used for effects that you want to fire randomly when attract mode is active.
- PBYAttractWheelNext: Attract mode is running and automatically switched to a new game
- PBYEndGame: The current running game has ended
- PBYFlipperLeft: The left flipper button (or whichever key is assigned as the Previous button) was pressed
- PBYFlipperRight: The right flipper button (or whichever key is assigned as the Next button) was pressed
- PBYFlyer: The Flyer command was selected, to display the current game's flyer as a popup window
- PBYGameInfo: The Information command was selected, to display the pop-up information box for the current game
- PBYGameSelect: A new game was selected
- PBYHighScores: The High Scores command was selected, to display the pop-up high score box for the current game
- PBYInstructions: The Instructions command was selected, to display the current game's instruction card as a popup window
- PBYLaunchGame: A game is being launched. This fires at the start of the launch process, just after the user selects the launch command, before the new game program has been loaded. Note that any device effects associated with this event might be cut off after a short time, because PinballY has to disconnect from DOF before the new game starts, to allow the game to take over the feedback devices. DOF turns off all devices when the program disconnects.
- PBYMagnaRight: The right MagnaSave button (or whichever key is assigned as the Next Page button) was pressed
- PBYMagnaLeft: The left MagnaSave button (or whichever key is assigned as the Previous Page button) was pressed
- PBYMenuDown: The user navigated to the next item in a menu
- PBYMenuOpen: A new menu was opened
- PBYMenuSelect: A command was selected in a menu (this usually means that the "Start" button, or whichever key is assigned as the Enter/Select command key, was pressed)
- PBYMenuUp: The user navigated to the previous item in a menu
- PBYMenuQuit: A menu was closed
- PBYProgramStartup: The program just started up
- PBYScreenSaverStart: Attract mode (the "screen saver" mode) is starting
- PBYScreenSaverQuit: Attract mode is exiting
- PBYWheelNext: The user navigated to the next game in the wheel
- PBYWheelNextPage: The user navigated to the next "page" (the next alphabetical letter group) in the wheel
- PBYWheelPrev: The user navigated to the previous game in the wheel
- PBYWheelPrevPage: The user navigated to the previous "page" (the previous alphabetical letter group) in the wheel

### States

In addition to events, PinballY has "states". These differ from events only in that states are long-lasting. An event fires briefly, usually triggering a quick event in DOF, such as flashing the flashers or firing a flipper solenoid. A state turns on and stays on for an extended period. States tell DOF the current context in the UI: showing a game in the wheel interface, showing a menu, running the "attract mode" screen saver, and so on.

- PBYMenu: A menu is being displayed
- PBYScreenSaver: Attract mode is active
- PBYStartupVideo: The startup video is playing
- PBYWheel: This is the default state, where the "wheel" interface is displayed with no menus or popups active

### Current ROM name

In addition to the PBYxxx states, PinballY also turns on a named event with the same name as the ROM for the table currently selected in the wheel display. For example, PinballY turns on the named effect MM when Medieval Madness is currently selected in the wheel. This lets you trigger effects that depend on which table is selected. The @allrgb@ syntax described above uses this to select device colors according to the selected table, but you can also use it explicitly for individual effects. The ROM names match the names in the Config Tool, which you can see listed on the Table Config page (look for "Rom: XXX" near the top of the page).

### Triggering DOF effects from Javascript

PinballY lets you trigger DOF effects from Javascript using the mainWindow methods DOFPulse() and DOFSet().

Those methods work in terms of DOF "named events", just like PinballY's own built-in DOF events. With these methods, you can use any of the PinballY events listed above, but you can also define your own custom events using whatever names you choose. DOF doesn't attach any significance of its own to event names; they're just arbitrary, user-defined labels that DOF uses to connect events fired by a program to rules defined in the DOF Config Tool. So you're free to add your own new names alongside PinballY's custom events listed above.

I'd recommend primarily using your own custom events with these methods. You can use any of the pre-defined PinballY events, but remember that PinballY itself also fires those events when the associated UI actions occur, so there could be cases where you're working at cross purposes with the PinballY events. That won't make anything terrible happen, but it could make the final visible effects somewhat unpredictable. For example, PinballY might just happen to deactivate an event at the same moment that you activate it, preventing the effect you expected from appearing.

Remember that the DOF Config Tool syntax for referring to a named event uses the $ prefix. So if you write something like `mainWindow.DOFPulse("MyEvent")` in Javascript, you'd refer to the event as `$MyEvent` in the Config Tool rules.

### Why isn't there a "program exit" event?

You might wonder why there's no event that fires when PinballY terminates, to match the PBYProgramStartup event that fires when the program first starts running. The reason is that such an event would be useless, because DOF always resets everything when the host program exits. Any effects that a "program exit" event triggered would be halted as soon as the DOF reset occurs, so there's no reason to bother programming such events - they'd just be lost anyway.

If you want to create program exit effects, a little Javascript scripting would be needed. The key would be to intercept the "Quit" command, via an event handler like this, and then carry out some special handling to show the desired DOF light show.

mainWindow.on("command", ev => { if (ev.id == command.Quit) { // place your special handling here } });

I can think of two approaches that would work, depending on the type of effect you wanted to create. There are undoubtedly other approaches, too, but here are my ideas:

- Keep PinballY running while the DOF effect plays out, perhaps showing a custom "exiting" video in the main window while it's going on. See Play an exit video for a full example of how to do this.
- Let PinballY exit as normal, but before it does, fire up a separate program that plays back your custom DOF effect. For example, you could use LEDBlinky (a third-party program, available separately, that plays back LedWiz effects scripts). The command.Quit handler wouldn't have to block the normal program exit; it would only have to launch the desired separate program. See Running an External Program for an example of how to launch a program from Javascript.