Crash reporting for Godot 4 and web games: two new SDKs

If your game runs in a browser or in Godot, a crash tool built around Unity or native binaries leaves you wiring your own error handlers and session timers. Tombstack now ships an SDK for each, next to Unity and native C/C++, all reporting into one dashboard split by the same builds, platforms and hardware cohorts.
The Web SDK is for games built on three.js, Babylon.js, PlayCanvas, Phaser or raw WebGL/WebGPU, and for Unity and Godot web exports. The Godot addon is for Godot 4 games written in GDScript. Both follow the shape of the Unity SDK (init, identify the player, mark progression, track events), so a studio shipping one game on two engines writes the same calls twice and reads one dashboard.
Web SDK 0.1.3: install and init
Zero runtime dependencies, ESM and CommonJS builds, TypeScript types included. It installs from a versioned archive on tombstack.com rather than the npm registry.
npm install https://tombstack.com/downloads/anklebreaker-tombstack-web-0.1.3.tgz
import { Tombstack } from "@anklebreaker/tombstack-web";Tombstack.init({ token: "tmb_<your-game-token>", buildVersion: "1.4.62", engine: "three.js" });Tombstack.setUser(account.id); // as soon as the player authenticatesTombstack.progression("onboarding", "tutorial_1", "start");
token and buildVersion are the only required options. The per-game token (tmb_…) can only write telemetry for one game, so shipping it in your bundle is fine. You do not have to await init(): calls made before it resolves are queued and replayed in order.
What the Web SDK captures on its own
- Uncaught errors from the window error and unhandledrejection listeners, with the breadcrumb trail attached. The listeners are passive, so your own handlers still run. They count as exceptions, not crashes, so a web build's crash rate is not inflated against its native sibling.
- Error budgets: one report per signature per 60 seconds and at most 10 a minute, so an error thrown every frame does not flood you.
- Session heartbeats every 60 seconds by default, checked against the wall clock and forced when the tab is hidden or shown again, so a throttled background tab does not drop a player out of your live count or your peak CCU.
- Frame timing on each heartbeat: average FPS, share of slow frames, hitch count and worst frame.
- Device and GPU snapshot: browser, OS, CPU cores, coarse RAM, GPU vendor and renderer, screen, language. The OS is the real one, so a Chrome player on Windows sits in your Windows cohort.
- Signatures that survive a deploy: bundler content hashes, query strings and line numbers are stripped, so a release does not reopen every known bug as a new issue.
Everything else is one call: progression, trackEvent, trackMetric, addBreadcrumb, captureException for errors you caught, and reportBug for an in-game bug form.
Consent gating
Pass requireConsent: true and init() starts nothing: no request is sent, and the SDK's one localStorage key is neither read nor created. Calls made meanwhile are held and replayed when the player agrees. setConsent(false) stops a live session without flushing and drops every later call. The decision lasts for the page load; remembering it across visits is your consent tool's job.
Tombstack.init({ token, buildVersion, requireConsent: true });consentBanner.onAccept(() => Tombstack.setConsent(true));consentBanner.onReject(() => Tombstack.setConsent(false));
Godot 4 addon 0.1.3: install and init
GDScript only: no C#, no native module, no dependencies.
- Download the addon archive from the download page.
- Copy its addons/tombstack folder into your project.
- Enable Tombstack in Project ▸ Project Settings ▸ Plugins. That registers the Tombstack autoload, so every script can call it.
extends Nodefunc _ready() -> void:Tombstack.init({"token": "tmb_<your-game-token>", # per-game ingest token from the dashboard"build_version": "1.4.62", # the build players are actually running})
token and build_version are required; without either, init pushes an error and does nothing.
What the addon captures
- Sessions and heartbeats every 60 seconds, timed on the engine's real clock. A game paused with Engine.time_scale = 0 or get_tree().paused keeps counting its players.
- Unclean shutdowns: a session marker on disk is removed on a clean quit. One found at the next launch is reported as a crash against the session and build that died. A mobile app killed in the background counts as a normal exit.
- Device snapshot shaped like the Unity SDK's (model, OS, CPU, RAM, GPU, screen, locale, engine version), so Godot builds land in the same hardware cohorts.
- Your calls: set_user, progression, track_event, track_metric, add_breadcrumb, report_bug, capture_exception.
What neither SDK does
Call capture_exception wherever you already handle a failure, and pass your own short stack string: without one the addon falls back to get_stack(), which is empty in an exported build.
var save := FileAccess.open(path, FileAccess.READ)if save == null:Tombstack.capture_exception("save load failed: %s" % error_string(FileAccess.get_open_error()),"load_save() in save_manager.gd")return
- Web: no source-map symbolication yet, so stacks arrive as your bundler emitted them. In sandboxed iframes, such as some web game portals, localStorage can be blocked and every page load looks like a new player; call setUser early if you have accounts.
- Godot: no dedicated-server role yet. A headless build that calls init counts as a player, including toward peak CCU, so skip init when OS.has_feature("dedicated_server") is true. No offline queue, screenshots, minidumps or frame stats. get_tree().quit() does not flush, so call Tombstack.flush() first.
Get started
Sign up, create a game with Godot 4 or Web (browser) as its engine, and mint an SDK token; the SDK tab and onboarding wizard then show the matching snippet with your token. Downloads: Web SDK and Godot addon. To post from your own code instead, both SDKs use the ingest endpoints. Unreal and custom engines keep the native C/C++ SDK.