Quick answer: Capture GML runtime errors with an exception handler and attach the platform, export target, and device context, accounting for the differences between VM and YYC compilation and across export platforms. GameMaker exports everywhere and fails differently on each, so platform-tagged capture is essential.

GameMaker Studio one of its great strengths is also a QA headache: it exports the same project to Windows, macOS, Linux, HTML5, Android, iOS, and consoles, and each target has its own runtime behavior and its own ways of breaking. A GML error that is harmless on Windows might crash on HTML5, and an export setting that works on desktop might fail on mobile. Setting up crash reporting that captures the platform and export context is what lets you make sense of crashes spread across all those targets.

One project, many runtimes

GameMaker compiles your single project to very different runtimes depending on the target. The desktop and console targets use the YoYo Compiler, mobile and desktop can use the VM, and HTML5 transpiles your GML to JavaScript. These are genuinely different execution environments, and behavior that is fine in one can break in another, especially around numeric precision, type handling, and performance.

This means a crash on one platform tells you little about the others, and you have to know which target a crash came from to interpret it. The HTML5 transpilation in particular introduces JavaScript-flavored quirks, while the YYC native compilation can expose undefined behavior the VM tolerated. Tagging every crash with its platform and runtime is the first requirement for making sense of a multi-target GameMaker game.

Capture GML runtime errors

GameMaker raises runtime errors for the common GML mistakes: accessing a variable that does not exist, an array index out of range, a wrong-type operation, a reference to a destroyed instance. These errors carry a message and often a location, and GameMaker provides an exception handler mechanism you can use to catch them rather than letting them drop the player to an error dialog.

Hook that exception handler to capture the error message, the script or object and event where it occurred, and your game state, then report it. This turns the unhandled GML error that would otherwise just show the player a crash message into a structured report in your dashboard, with the GML-level detail you need to find the line that failed.

Account for platform-specific failures

Beyond GML errors, each platform has its own failure modes. HTML5 has the browser constraints of any web game: memory limits, WebGL context loss, and audio autoplay rules. Mobile has memory ceilings and device fragmentation. Desktop has driver and file-path issues. A robust setup captures these platform-specific failures, not just the clean GML errors.

Capture the platform, OS version, and device or browser context with every crash so you can separate a universal GML bug from a platform-specific one. A crash that only appears on HTML5 points at the transpilation or a browser limit, while one that only appears on Android points at memory or a device quirk, and the platform tag is what lets you make that distinction immediately.

VM versus YYC compilation

The choice between the VM and the YoYo Compiler affects which bugs surface. The YYC produces faster native code but is stricter, and code that relied on the VM forgiving behavior can crash under YYC. Conversely, some performance issues only appear on the VM. The same project can have different crashes depending on how it was compiled.

Capture the compilation mode in your crash reports so you know whether a crash came from a VM or YYC build. When you ship YYC for release but test on the VM during development, this distinction is critical, because a YYC-only crash will never appear in your development testing and you will only ever see it in player reports from the release build.

Setting it up with Bugnet

Bugnet works with GameMaker through the exception handler to capture GML runtime errors, attaching the platform, export target, OS, and device context automatically. Your Windows, mobile, and HTML5 exports all report into one dashboard, tagged by platform, so you can see your whole multi-target game stability in one place.

Add custom fields for your game state, like the current room and key variables, and group identical errors into occurrence counts. Because GameMaker games ship to so many platforms, the ability to filter crashes by target is especially valuable: it instantly tells you whether a new crash is a universal bug or a problem isolated to one export, which completely changes how you prioritize and fix it.

Test each target you ship

Crash capture covers the long tail, but the worst platform-specific bugs show up the moment you run each export, so test every target you intend to ship at least briefly. An HTML5 build in a browser, a mobile build on a real device, and a YYC desktop build all surface their characteristic problems quickly, often on the first launch, before any player ever sees them.

Then let your platform-tagged crash data carry the rest. You cannot exhaustively test every browser and device, so your players across all your targets become the test matrix, and capturing crashes with the platform and runtime attached is how you read which target is breaking. For a GameMaker game spread across many platforms, that per-target visibility is the difference between confidently shipping everywhere and hoping each export works.

One GameMaker project, many runtimes. Tag the platform or the crash makes no sense.