Quick answer: Capture .NET exceptions with their stack trace, and attach the graphics backend (DesktopGL or DirectX), platform, and content-pipeline context, because MonoGame games fail through exceptions and backend differences across platforms. The backend and platform context is what distinguishes a cross-platform bug from a backend-specific one.
MonoGame is a mature, code-first framework for building cross-platform games on .NET, and games built with it fail in ways shaped by .NET and by MonoGame two graphics backends. Crashes are .NET exceptions, the content pipeline can fail to load assets, and the DesktopGL and DirectX backends behave differently, so a game can crash on one and not the other. Setting up crash reporting for a MonoGame game means capturing exceptions with their stack traces and the backend and platform context that explains why a crash hits some players and not others.
MonoGame runs on .NET across backends
A MonoGame game is a .NET application, so crashes surface as .NET exceptions with stack traces, which is convenient because the exception model is well understood and the traces are readable. The complication is MonoGame two main graphics backends: DesktopGL, which uses OpenGL and runs across Windows, macOS, and Linux, and the DirectX backend on Windows. These backends behave differently, and a crash can be specific to one.
This means a MonoGame crash report needs the backend context to be fully diagnosable. A graphics crash on DesktopGL might not appear on DirectX, and vice versa, so knowing which backend a crash came from immediately narrows whether it is a general bug or a backend-specific rendering issue. Capturing the .NET exception is the foundation, and the backend context is what makes cross-backend crashes interpretable.
Capture unhandled exceptions
The foundation of MonoGame crash reporting is capturing unhandled exceptions. In .NET you hook the unhandled exception events, at the AppDomain level and for the UI or task contexts as relevant, so any exception that would otherwise crash the game to the desktop is captured first. Your handler records the exception type, message, and stack trace, then sends a report before the process exits.
Because MonoGame games are .NET, the stack traces are readable without symbolication in the way native code requires, which makes triage straightforward, the trace points directly at the line that threw. Capture the full exception including inner exceptions, since the root cause is often wrapped, and the inner exception chain reveals the original error beneath a more general wrapper, which is frequently where the real bug lives.
Capture the backend and platform
Capture which graphics backend is active, DesktopGL or DirectX, and the platform and OS, because these are the dimensions along which MonoGame crashes cluster. A crash on DesktopGL on Linux is a different situation from one on the DirectX backend on Windows, and the backend plus platform context lets you see which environment a crash affects.
Capture the GPU and driver too, since graphics crashes on either backend can be hardware-specific. When a crash concentrates on one backend, one platform, or one GPU family, you have a targeted issue rather than a universal one, and the combined backend, platform, and GPU context makes that pattern visible. This is especially valuable for MonoGame, where the same codebase ships across several backend-and-platform combinations that each behave slightly differently.
Watch the content pipeline
MonoGame uses a content pipeline that processes assets into a runtime format, and content-loading failures are a distinct class of MonoGame crashes. An asset that fails to load, a content file built for a different version, a missing or misnamed asset, or a content format the platform does not support, all produce content-pipeline exceptions at load time, often on a specific asset.
Capture content-load failures with the asset name and the context, so these are identifiable as content issues rather than general logic bugs. A content crash usually points at a build or packaging problem, an asset left out of the build, a version mismatch, a platform-specific format issue, and knowing it is a content failure on a named asset directs you straight to the content pipeline rather than your game code, which is where the real cause lies.
Setting it up with Bugnet
Bugnet captures .NET exceptions from your MonoGame game by hooking the unhandled exception events, recording the full exception chain and stack trace, and you attach the graphics backend, platform, GPU, and content context as custom fields. Reports flow into one dashboard tagged with the backend and platform, so you can see your whole cross-platform game stability in one place.
Add custom fields for your game state and group identical exceptions into occurrence counts. Because MonoGame ships the same code across DesktopGL and DirectX and multiple platforms, the ability to filter crashes by backend and platform is especially valuable, instantly telling you whether a crash is a universal bug or isolated to one backend or platform, which completely changes how you prioritize and fix it.
Test both backends and platforms
Because MonoGame backends behave differently, test on both DesktopGL and DirectX where you ship them, and on each platform you target, since the worst backend-specific bugs show up the moment you run the other backend. A game that runs flawlessly on the DirectX backend on Windows can have rendering or content issues on DesktopGL on Linux that you will only see by testing there.
Pair that testing with your backend-tagged crash data for the long tail of platforms, GPUs, and configurations you cannot exhaustively test. Your testing catches the obvious backend differences, and the captured crashes, tagged by backend and platform, reveal the hardware-specific and configuration-specific issues across the range your players run. For a MonoGame game spread across backends and platforms, this per-backend visibility is what lets you confidently ship the same codebase everywhere it runs.
MonoGame ships one codebase across two backends. Capture which backend crashed, not just the exception.