Quick answer: AR games fuse a live camera, motion sensors, and environment understanding into your render loop through ARCore or ARKit, adding failure modes no ordinary game has. Capture crashes with the standard Android and iOS paths, but attach the AR session state, the tracking state, interruption history, anchor counts, and camera permission, so a crash during limited tracking or after an interruption reads as a mishandled transition rather than a mystery.

AR games fuse a live camera feed, motion sensors, and environment understanding into your render loop through ARCore on Android or ARKit on iOS. That pipeline introduces failure modes no ordinary game has: camera permission revocation mid session, tracking loss in poor lighting, and session interruptions from a phone call. Crash reporting for AR must capture not just the stack but the state of the AR session at the moment things went wrong, because the same code path that runs fine a thousand times faults the one time tracking had just become limited. This post covers how the frameworks hook your app, platform specific crash capture, the AR specific failure modes, and the device and sensor variance that makes the same code behave differently across phones.

How AR frameworks hook your app

ARCore and ARKit run a continuous pipeline: they read camera frames, fuse them with the inertial sensors, build a model of the environment, and hand your app a stream of tracked poses and detected planes each frame. Your render loop consumes that output, so the AR session is effectively part of your update path. A fault in how you consume a frame, an anchor, or a pose can crash, and the relevant context is the AR session state, not just the call stack, because the stack alone will not tell you the environment had just stopped tracking.

The frameworks expose tracking state and session events that are central to crash context. Both report a tracking state and reasons for limited or lost tracking, plus interruption notifications. Because these change frame to frame with the physical environment, a crash report that omits the current tracking state and the recent session events is missing the very information that explains why a normally stable code path failed this time, which is what makes AR crashes feel random until you start attaching that state.

Platform specific crash capture

On Android, an AR game is typically a native or engine build, so you capture crashes with an NDK signal handler and, for managed runtimes, the exception hook, plus an ANR watchdog since AR keeps the main thread busy. On iOS the app is a signed binary, so you install a Mach exception and signal handler and rely on dSYM symbolication, because the system crash logs are inaccessible from a player device. Each platform follows its standard crash playbook before any AR specifics are layered on.

The AR addition on both platforms is a breadcrumb of session events. Record session interruptions, tracking state transitions, camera configuration changes, and anchor add or remove events into a small ring buffer, and attach it to any crash. When a fault arrives, that buffer often shows that tracking had just become limited or the session was interrupted, which reframes a seemingly random crash as a mishandled AR state change, the single most useful piece of context you can add to an AR crash report.

AR specific failure modes

Camera access is the sharpest edge. The user can revoke the camera permission from settings while your game is backgrounded, and on return the AR session cannot start; if your code assumes a camera is always available it will crash. Record the camera permission state and handle the denied case explicitly, because a downstream null from a missing camera frame is a common and confusing crash signature that looks nothing like the permission problem it actually is.

Tracking and anchors are the other big surface. In low light or with a featureless surface, tracking degrades or is lost, anchors can become invalid, and accessing a stale anchor pose can fault. Session interruptions from incoming calls or app switches pause and resume the pipeline, and code that does not handle the resume cleanly crashes on the next frame. Capturing the tracking state and interruption history makes these patterns visible instead of intermittent, so a low light crash becomes an obvious conditional rather than a ghost you cannot reproduce.

Device and sensor variance

AR leans hard on hardware that varies across phones: camera quality, motion sensor accuracy, and on some devices depth sensors. ARCore supports a long, uneven list of Android devices with differing calibration, so a tracking quality bug can appear only on lower end hardware. Capture the device model, the AR framework version, and whether depth or other optional features were available, because a crash tied to a missing capability is invisible without it and looks like a model specific gremlin.

Optional feature negotiation is a frequent fault line, mirroring extension handling in other layered systems. Your game might use depth or people occlusion where available and assume it elsewhere by mistake. Recording the negotiated AR feature set per session lets you spot a crash that only occurs where a capability is present or absent, turning a maddening device specific intermittent into a clear conditional bug you can fix by handling the absent case the way you already handle the present one.

Setting it up with Bugnet

Integrate the Bugnet SDK for your platform and initialize it before you create the AR session, so a crash during session configuration is captured. The SDK installs the native handlers and queues reports for upload on the next launch. You then push AR session state into the report context: the current tracking state, the last interruption reason, the number of active anchors, and the camera permission status at the time of the crash, alongside the in game report button for non fatal glitches.

Bugnet folds crashes together with occurrence grouping and lets you split by device model and OS, which matters because AR performance and sensor quality vary widely across phones. By attaching the tracking state and session breadcrumb as custom fields, you can filter every crash that happened during limited tracking or right after an interruption, which usually isolates a specific mishandled AR transition far faster than reading stacks alone, and occurrence counts tell you which transition to fix first.

Operating across the AR fleet

AR framework updates ship with OS updates and with the platform AR services package on Android, independently of your release, so a crash spike can follow a framework update rather than your patch. Record the framework version on every report so you can attribute spikes correctly. Sort signatures by occurrence and cross reference device and tracking state, since the top crash is often a single AR transition mishandled across many devices rather than many separate bugs.

After each release, verify that the session breadcrumb and tracking state are still attached, not just the raw stack, because the AR context is what makes these crashes solvable. Review the top signatures split by device and framework version, and reproduce on lower end hardware where tracking is most fragile. A short post release check protects you from a framework update quietly breaking your session resume on phones you do not own, which is otherwise a problem you only learn about from a wave of confused reviews.

AR crash reporting must capture the AR session state alongside the stack: tracking state, interruption history, anchor counts, and camera permission. Use the standard Android and iOS crash paths, then attach an AR breadcrumb so a crash during limited tracking becomes an obvious mishandled transition.