Javascript Debugging

The first and simplest step in debugging your Javascript code is to check for error messages in the log file. Make sure that Javascript-related messages are enabled in the Log File page in the settings dialog. As long as that's enabled, basic problems in your scripts, like syntax errors and run-time errors, will be reported in the log file. If your scripts don't do what you expect during the session, quit out of PinballY and check the log file for error messages. Javascript-related errors will not, for the most part, be reported interactively (they won't show up as pop-up messages or dialogs), since they're of such a technical nature and because there's not generally anything you can do about them at the UI level anyway. But they are recorded in the log file. Most logged Javascript errors include details on the script file location where the problem occurred, to help you pinpoint and fix the underlying problem.

Error messages in a log file are helpful for fixing simple problems like syntax errors, but if you've done any programming before - even simple scripting work - you know that a log file isn't enough for diagnosing more complex problems with a program's logic. For that, you need an interactive debugger. A debugger is a tool that lets you get inside your program and watch it as it runs, step by step, observing the values of variables and which branches are taken.

PinballY doesn't have its own built-in debugger window, but it has something better: it lets you connect an external debugger. That's better because it lets you use a full-fledged Javascript debugger that a professional team designed, not just some half-hearted afterthought that I came up with and bolted onto PinballY.

PinballY currently works with the following third-party debuggers:

Debugging is handled through the Chrome DevTools protocol. This is a standard protocol that's implemented by most Windows Javascript debuggers and IDEs, so in principle, you should be able to use any debugger that implements the protocol. However, be warned that the protocol implementation in ChakraCore is extremely immature and incomplete. Microsoft is building the debugger interface as a separate project from the main ChakraCore engine, and so far they're really only at the prototype stage. They're also only thinking in terms of VS Code support, so support for other debuggers (like Chrome) is an afterthought at best. Fortunately, they've made it open-source (like Chakra Core itself), so I've been able to flesh it out enough to make it fairly usable with VS Code and the Chrome debugger. You might be able to get it working with other Javascript debuggers, if there's something else you prefer, but it might be a bit shaky.

If you run into any problems with debugging, feel free to report them as issues, but be aware that it might not be practical for me to add any substantial missing features until Microsoft makes more progress on this. Hopefully they'll continue developing it and it'll become more complete over time.

Simple instrumentation

For very simple debugging tasks, you can sometimes get enough information by instrumenting your code with debugging messages. One way to do that is to display messages through the user interface, such as via the message() and alert() functions. Another way that's less intrusive in the UI is to use logfile.log(), which writes messages to the log file for review after the session ends.

Pausing in the debugger

One of the main functions of any debugger is the ability to pause execution at any arbitrary point in the program, so that you can inspect the current values of all variables and step through sections of code one line at a time. The exact command to pause execution varies by debugger, but the VS Code and the Chrome debugger have similar UI features, with buttons to pause execution of the running program, step one line at a time, and set breakpoints at source locations.

At program startup, the debugger will normally pause execution at the first line of your main.js script. You can override the initial stop location using the /jsdebug:break=xxx command-line option when starting PinballY.

VS Code and Chrome both have "pause" buttons, which cause the debugger to interrupt the Javascript program at the next opportunity while it's running. The debugger can only break into Javascript code, so pressing the button won't have any effect until the next Javascript script executes, which will happen the next time one of your event handlers fires. The pause button thus might not do anything immediately, since it won't interrupt execution until something is happening in Javascript.

Whenever execution is paused in the debugger, be aware that PinballY's windows won't respond to mouse clicks or keyboard input. That's because your Javascript scripting code is effectively part of the PinballY's user interface code. Freezing Javascript execution therefore also freezes the PinballY user interface. When you resume execution from the debugger, the PinballY windows will return to normal.

Visual Studio Code setup

VS Code is Microsoft's free and open-source code editor, which can also serve as a fairly full-featured IDE for Javascript. If you don't already have a good code editor, you might try VS Code as a combined editor and debugging environment.

Full documentation for VS Code is available on the VS Code docs site.

Note that you don't have to install the traditional Visual Studio (Microsoft's large-scale IDE for system programming languages like C++ and C#) to use VS Code. VS Code is a completely independent, standalone program that doesn't depend upon Visual Studio in any way, despite the similar name.

Here's the full setup procedure, starting from scratch. If you already have VS Code installed, just skip the download-and-install step.

VS Code will now be set up to connect to PinballY. You can return to this configuration in future sessions by using File > Select Folder to return to the same PinballY Scripts folder, since VS Code keeps its configuration data with the folder.

You can go back and manually edit that launch.json file at any time, or create it manually yourself. You'll find it in the .vscode folder within your PinballY Scripts folder (or whichever folder you selected in the "navigate to your Scripts folder" step above).

Starting a debug session with VS Code

This procedure launches PinballY as a child process of the VS Code debugger, so you should close any running instance of PinballY first.

PinballY will now launch, and the debugger will take control as soon as the first Javascript code starts running. You can now set breakpoints for any code you want to step through, or do any other initial setup for the debugging session. Press F5 to continue execution.

Launching PinballY and VS Code separately

You'll probably find it most convenient to launch PinballY directly from VS Code as described above, but there's another way to do it. You can alternatively launch PinballY yourself, and then "attach" VS Code later.

Chrome DevTools setup

The Chrome DevTools are built in to the Google Chrome browser, so if you have Chrome installed, you already have a nice Javascript debugger installed. The Chrome debugger is more of a standalone debugger than a full IDE like VS Code, so you might prefer VS Code if you want a more integrated user interface. Also note that VS Code support is Microsoft's first (and really only) priority, so Chrome support might lag in some ways.

The launching procedure with the Chrome debugger is a little different from VS Code. Chrome won't launch PinballY for you the way that VS Code does. Instead, you have to launch each program (Chrome and PinballY) separately, and then tell Chrome to connect to the running PinballY instance. PinballY accommodates this by pausing in a "Waiting for debugger" dialog until a debugger connects, giving you a chance to intercept the startup scripts without any super-human feats of timing.

Here's the setup procedure:

Generic setup for other tools

Warning: As mentioned earlier, ChakraCore's debugger interface is only designed to work with VS Code. It might work in a limited way with other debuggers that implement the Chrome DevTools protocol, but many functions are likely to be broken. Even so, I'm documenting the basic setup procedure here for reference, in the hope that support for other tools improves in the future.

If you want to try an alternative debugger, here's the generic setup procedure. You'll have to adapt the steps to your debugger's particular settings dialogs or configuration file setup, of course.

Startup procedure: By default, when you use /jsdebug to start PinballY in Javascript debugging mode, PinballY waits for a debugger to connect before doing anything else. As soon as the debugger connects, PinballY loads its own built-in Javascript code, then stops in the debugger just before the first line of your main.js script is executed. This gives you a chance to step through your script code from the beginning if you want to. You can simply use your debugger's "Go" or "Continue" command if you don't need to step through your startup code.

Choosing a port number

The "port number" we've referred to a number of times is a local TCP port number. This is a type of network port, but in this case it doesn't actually access your LAN or Internet connection; it's just for local connections between programs running on your computer. The port number simply identifies the port so that the applications can connect to each other.

Any port from 1024 to 49151 is valid, as long as the port isn't already in use by some other program. The default port is 9228, which isn't used by any common software that I know of. PinballY will show an error at startup if you choose a port that's already in use; if you see such an error, simply choose a different number in the valid range.

The range of valid ports is so large that it's usually easy to find a free port by just choosing one randomly. However, if you want to see a list of exactly which ports are in use on your computer, type netstat /an into a CMD prompt window. Look for entries in the "Local address" column with address 127.0.0.1: the number after the ":" is the port number.

How to tell PinballY which port to use: On the PinballY command line, enter the port number like this (substituting the port number of your choice for the default 9228):

PinballY.exe /jsdebug:port=9228

How to tell your debugger which port to use: That's different for each debugger. For VS Code, you enter it in the launch.json file under the "port" setting. For Chrome, you add it to the "network targets" list as localhost:port.

/jsdebug option syntax

The /jsdebug command-line option tells PinballY to enable Javascript debugging. Debugging is disabled by default, since it adds a little bit of performance overhead.

/jsdebug by itself enables debugging and selects a number of default settings. You can change the defaults by adding some extra sub-options to the /jsdebug parameter. Append sub-options to /jsdebug after a colon (":"). To use more than one sub-option, separate them with commas:

PinballY.exe /jsdebug:port=9228,break=system

The sub-options are: