Custom Game Command Line for Media Capture

In some cases, you might want to use different command-line options when launching Visual Pinball (or another game system) for a media capture session, vs. the regular options for a regular game play session.

I know of one special case where this is particularly useful, which is VP's "true full screen" mode. Many people normally run VP in Exclusive Full Screen mode, because the version of DirectX that VP is based on can achieve better GPU performance in that mode. But this creates a problem for media capture operations: by its very nature, "exclusive" mode means that only one program can access the video display. So putting the display in "exclusive" mode means that FFMPEG can't capture the video, defeating the whole purpose of the media capture operation.

At least one person has proposed adding a special feature to PinballY to turn off VP's exclusive mode when running a capture. But I can't see a way to do that without building knowledge of that very specific feature of VP into PinballY. I try to avoid making PinballY know special things about VP, because I want PinballY to work with any game system you want to use it with. Special handling for VP violates that principle of generality.

So instead of building special knowledge of VP into PinballY, I'll provide this worked example showing how you can use Javascript to perform this kind of extremely specific customization. This is the only way I see that makes it general enough to apply the same idea to other systems that might need something similar.

Launch events and command lines

The approach we're going to use is to listen for a prelaunch event. That event fires when a game is about to be launched, and it gives Javascript a chance to do all of the following:

So this lets us accomplish our goal here: when we see a VP X game being launched for a media capture operation, we'll sneak in and add the "disableTrueFullScreen" option to the VP command line.

This example uses a number of system objects, which you can find full details on in other chapters:

Here's the script:

// Intercept the prelaunch event, which fires each time a game is // about to be launched. This fires BEFORE the launch process starts, // so it gives us an opportunity to edit the command line that will be // used to launch the program. mainWindow.on("prelaunch", ev => { // check to see if we're in Media Capture mode AND this is VP X if (ev.command == command.CaptureGo && game.system.systemClass == "VPX") { // We're launching a Visual Pinball X game in media capture mode. // Edit the command line to add the /disableTrueFullScreen option flag. ev.overrides.params = gameSysInfo.params + " /disableTrueFullScreen"; } });

The overall body of the code is simply an event listener for the prelaunch event. As mentioned above, a listener for this event has the ability to modify anything about the command line for the game that's about to be launched.

The first thing the event listener does is check the command to see if it's a media capture command (command.CaptureGo) and that the game system is Visual Pinball X. The special command-line option that we want to insert only applies to that particular situation - we wouldn't want to add it to a Future Pinball launch, for example.

Note that we detect that the game is a Visual Pinball X game by checking the "system class" of the game system that we're about to launch. The "game system" is simply PinballY's internal data record describing the program. This corresponds exactly to one of the game systems that you can edit in the Settings dialog. The "system class" is one of the game system properties that you can select in the dialog. Even though I made a big deal earlier about how PinballY tries to avoid special knowledge of Visual Pinball (or any other particular game system), there are a few special cases that PinballY does have to handle, which is why it lets you specify that a particular system is VP, VPX, FP, or Steam-based. The script takes advantage of the fact that we have this way to specially designate VPX among the system data records. If you wanted to create a similar script that detects launches for some other game system that doesn't have a special system class in PinballY, you could use one of the other GameSysInfo properties to detect the system. One way would be to identify it by name, using the displayName property of the GameSysInfo object. I consider that a little unreliable because you can really set it to anything you want to for any system; it's just there for display purposes, not for absolute identification. A better way might be to check the defExt property, which tells you the filename extension used by the system's games; that might be unique enough to be reliable. Another option would be to look at the exe property, which tells you the EXE program file's name; that might also be unique enough to reliably identify the system.

Once we've identified the system as VPX, and identified the command as a Media Capture operation, we spring into action. The goal here is to get VP not to use exclusive full-screen mode for this session. VP helpfully provides a command-line option that does exactly that, /disableTrueFullScreen. So all we have to do is append that option to the command line options that we were going to provide for a normal launch. To get the original options, we just look at the params property of the system's GameSysInfo object. That gives us the exact text that you typed into the Settings dialog for this system. In the case of VPX, we can add new option flags simply by stringing them along at the end of the rest of the command line, so we use the Javascript string "+" operator to append the option at the end.

Note that some other systems might need options to be inserted at the beginning of the command line, or pasted into the middle. This is one more reason that it's not easy to generalize this into something that we could have built into PinballY itself. Command-line syntax on Windows is inherently idiosyncratic, so we can't say in general that "new options always go at the end" or whatever else. New options go where the particular program says they go.

Adapting the script to other game systems

The "Exclusive Full Screen" media capture issue will apply to any game system that uses Exclusive Full Screen mode. The same technique we used in the script above should be adaptable to other systems. Javascript lets you have as many prelaunch event listeners as you want, so you can just add another event listener based on the one above for each system that needs one.

The first step in adapting the event listener to a new system is to recognize the new system. If the system has a sufficiently unique filename extension that identifies its games, that should be a reliable way to identify it:

if (command == command.CaptureGo && game.system.defExt == ".somepin")

If the system doesn't use game files, or doesn't have a unique enough default extension, you could rely on the executable filename. The exe property of the GameSysInfo object gives us the full name, with drive letter and directory path prefix, so you might want to use a regular expression to just look for the main file name portion:

if (command == command.CaptureGo && /\\somepinplayer\.exe$/i.test(game.system.exe))

Once you've identified the system, all that remains is to tell the program being launched not to use Exclusive Full Screen mode for the current session. Exactly how you do that is up to the particular player program you're using: