VPX Scripting — Part 5 (DOF)

Pit Stop backglass.
Backglass for Pit Stop by the user Hauntfreaks.

21 Apr 2024

You may recall a few posts back when we were savagely modifying the script to Teacher’s Pet that there had been some references in the script to something called DOF. I left some commented-out lines of code behind like breadcrumbs and promised to come back and deal with them. We’ll do that in this post.

But first there are a few other loose ends and housecleaning duties I want to attend to for Teacher’s Pet.

Missing Sounds

There’s a debugging mode in Visual Pinball (VPX) that allows you to bring up a debugging console window. Sometimes while playing, VPX will encounter small errors in the pinball table script — errors it believes are non-fatal — and it will report these in the debug window if it is open. These can be very useful to us.

To bring up the debugger when playing VPX hit the “D” key. You may have to switch to playing VPX in a windowed mode so that you can have the table visible to play at the same time that the debug window is also visible. To play VPX though you also need to be able to click on the window showing the pinball table.

Debugger window open.

As I played Teacher’s Pet I started to notice a few messages come up in the Debugger window. There is a sound VPX is trying to play but it is missing. You can see the messages in the debugger window pictured below.

Debugger showing missing sounds.

If you followed the previous posts you’ll remember we removed all the sounds from Teacher’s Pet and imported new ones from the EM Sounds folder we pulled down from Github. All of the EM Sound routines we changed over to have corresponding sound files included among the EM Sounds folder. But there were two places in the script where we specified the same sound be played that was originally referred to in the script. One of those, unsurprisingly, is “scoopexit” — the sound that the debugger is telling us is missing.

Hopefully you exported all the old sounds from Teacher’s Pet and still have them on your hard drive somewhere. But even if you did not, you can always re-download the table and export the missing sound files.

But here’s something kind of odd, there is no sound called “scoopexit” in Teacher’s Pet. It happens sometimes, I guess: Loserman76 uploaded a table and had not noticed that a sound resource was missing.

I searched high and low for a “scoopexit” sound in other VPX tables but was only able to find one called “fx_ScoopExit”. I put the sound file up on Github in the Teacher’s Pet repository so that you can download it by clicking here.

The download button on Github.

You can download the sound file from Github by clicking on the download button shown above.

Go back to Part 4 if you have forgotten how to import a sound in VPX.

There is one more issue we need to resolve with “scoopexit”. Since the script is trying to play a sound called “scoopexit” and the sound we substituted is called “fx_ScoopExit” we either need to rename the sound resource, or change the script. It’s your call as to which way you want to go. The Sound Manager window that we looked at in Part 4 allows you to easily rename the file right there if you prefer.

I think I’m going to leave the file named as it is though and change the script. It was an easy change — here is what one change looked like:

Coding diff.

The “diff” (difference) above shows a “−” (minus symbol) and a red highlight indicating the line of code as it was before I edited it. Below it (with a “+” and green highlight) is the new line of code. There were four places like this in the script that I had to change like this, I am showing just one above.


Recall that back in Part 3 we looked for instances of PlaySound and mostly replaced those calls with calls to EM Sound routines. I forgot one other VPX routine we should have looked for: StopSound.

If you search the script for “stopsound” there is only one place it is called outside of the new EM Sound code. In a subroutine called PlasticsOff it is being called to stop any “buzz” sound that might be playing.

One of the goals of the EM Sound code is to take over the duty of playing and stopping sounds so that the rest of the script can be kind of sound-ignorant.
Coding diff.

Above, the two StopSound calls were removed, replaced by EMSStopBuzzSounds.

By the way, I’m going to explain in a later post how the EM Sound routines work. For now though I assumed there would be readers that just wanted to get the new sounds working, understand them later. But now we’re going to switch gears a bit and talk about something not really sound related.


DOF stands for Direct Output Framework. It is another one of the pieces of software you can install with VPX. As I understand it, VPX talks to the DOF software and DOF talks to USB controllers the controllers control hardware you have installed in your virtual pinball cabinet. Some people with pinball cabinets attach real solenoids, knockers, chimes, and external LEDs and lights to their cabinets — these are activated via DOF by in-game events. So when the knocker is triggered in the VPX table you are playing, an actual knocker in the player’s cabinet kicks off.

I have built a virtual pinball cabinet but personally I have not yet added any of these toys, but you will find code in Loserman76’s scripts to support DOF and Teacher’s Pet is no exception.

People have created DOF templates for many of the VPX tables out there to specify “identifiers” for each DOF element that the table supports. If you have a DOF-enabled pinball setup you pull down these config files for the tables you play and it enables the correct toy to activate when it is supposed to.

These configuration files are maintained on this site: configtool.vpuniverse.com. Below is the configuration front end for the Teacher’s Pet table.

DOF Config Tool.

I don’t completely understand what all of the above means, but I know a little. As an example, I highlighted the two flipper entries.

It tells you the value for the left flipper is E101 and E102 for the right flipper. Ignore the E on the beginning, the interesting part with regard to scripting is the 101 and 102. It is by using these numbers that you indicate which object to trigger when, for example, the player activates the left or right flipper. (Presumably then the player’s cabinet will have actual solenoids that will come to life with the flipper activation.)

How does this relate to Teacher’s Pet script? (And can we finally deal with those lines of code we commented-out in Part 3?)


If you remember in Part 3 searching for PlaySound in the script, we’re going to do something similar to clean up the DOF support in Teacher’s Pet.

Searching for “dof”.

We’re not searching case-sensitive or for whole words. Starting from the top of the script, the first result is above.

DOF is a VPX routine that is always followed by an identifier (a number) then a comma and then a state that can be either 0, 1 or 2.

The previous call is telling DOF that for device number 232, turn it on (“1” means “on”).

VPX has constants already defined for the three DOF states: DOFOff, DOFOn and DOFPulse and these correspond to the numbers 0, 1 and 2 respectively. So just for ease of understanding the script, we should replace the “1” at the end of Line 254 with DOffOn.

Added “DOFOn”.

But that still leaves us a little confused by the 232. Let’s create our own constant for all the DOF devices this table supports. We’ll start with device 232.

Typically when a machine has more than zero (0) credits a start-button light is illuminated. Even if Visual Basic is new to you, you should see that Line 254 is saying, “If there are any credits, turn on device 232.” So let’s create a constant for the 232 that I’ll call kDOF_StartButton.

I’m going to put all my DOF constants near the top of the script though. And for what it’s worth, I decided to begin all constants with the lower-case “k”.

Added our constant.

I am putting the first constant on Line 38. One reason for creating this constant is that there are in fact several places in the script where the start button DOF device is referred to. By using a constant at the top of the file we can change its value at a later date if we have to and not have to search through the script and change it in several places.

Using the constant.

The other reason of course is to “self-document” the code. Look how much easier the code is to understand now.

I’m only going to give you one more example of DOF coding. This is one of those PlaySound calls that referred to DOF that I left in the script but commented out.

DOF flipper diff.

Both changes in the diff above are for the flippers. We finally can remove those commented-out lines of code and replace them with DOF calls. The reason we kept them around until now was to indicate where to put the DOF calls and so that we would know what identifier to use (201 for the left flipper, 202 for the right flipper). Not shown are two new constants I created for kDOF_LeftFlipper and kDOF_RightFlipper. As before, these constants were put near the top of the script so someone could easily edit them.

The rest of the DOF clean up works just like that. Search for “dof”, create new constants and make the code easier to figure out what is going on.

Okay, a funny thing happened while I was converting Teacher’s Pet for this series of blog posts. I found that the DOF identifiers found on the ConfigTool site were completely unlike the numbers I was seeing in the script.

Even with the small amount of code I have already shown you, you can see a problem. Just now I showed that 201 and 202 were identifiers for the left and right flipper objects in the script. But scroll up earlier in this post and the screenshot from ConfigTool shows them as 101 and 102. What gives?

Both can’t be right, and when there is a discrepancy I’m going to suggest we treat ConfigTool as authoritative. That means that I had to go through and re-number all the DOF identifiers in Teacher’s Pet to match the numbers in ConfigTool. Since I had already created constants for each device though that turned out to be easy.

Still wondering how that happened though, I finally discovered a patch for Teacher’s Pet that had all these new values for DOF in the script. I suppose the person that created the ConfigTool configuration the way it is probably were the ones that created the patch? In any event, we’re all on the same page now.

As I say, I’ll save both of us the tedium of going through all of the remaining cleanup I had to do for DOF in Teacher’s Pet. I did put the script with all my changes on Github.

Below is the diff just showing the DOF constants I created to give you some idea of how extensively DOF is being used.

DOF constants.


People with cabinets that support DOF may not be typical, but they are passionate (as I probably would be as well) so you should be careful with the DOF code in the script.

As we’ve seen though, the good news is that DOF is one of the easiest things to code. It’s just a single routine with this form:

DOF identifier, state

Where identifier is an integer we get from ConfigTool and state is one of DOFOff, DOFOn or DOFPulse.

We’ll finish up the work on sounds in the next post. There are a few loose ends we need to wrap up but we will also add a few new sound features that were not present in Loserman76’s Teacher’s Pet to give the table just a little more polish.