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

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

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:

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:

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:

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.

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: