Quick answer: Run mod scripts against a curated API object, avoid handing them OS/DirAccess/scene-tree directly, and validate any path or resource a mod requests.

You let players write GDScript mods, but a mod can call OS.execute or DirAccess to touch the filesystem and walk the whole scene tree. Exposing engine globals directly gives mods unrestricted power, which is a security and stability problem.

How to fix it

1. Expose a curated API, not engine globals

Give mods a single API object with vetted methods (spawn this, register that). Do not pass them OS, DirAccess, or arbitrary get_tree() access.

2. Mediate file and resource access

Route any mod file or resource request through your API, restricting it to the mod's own directory and validating paths so a mod cannot read outside its sandbox.

3. Avoid arbitrary node mutation

Hand mods references to designated extension points rather than the whole scene tree, so a mod cannot reach in and break unrelated systems or the UI.

4. Guard mod calls

Wrap mod entry points so a mod error is caught and the mod disabled, keeping a misbehaving GDScript mod from crashing the game.

Catching the ones you can't reproduce

The hardest version of this to fix is the one you can't reproduce — it only happens on a player's hardware, OS, driver, or save state, under conditions that simply aren't present on your machine. A report that says “it crashed” or “it froze” gives you nothing to act on, so the bug survives release after release while quietly costing you players.

Automatic error capture closes that gap. Each failure arrives with its full stack trace, the device and OS, the build number, and a breadcrumb trail of what the player did right before it broke, so even a failure you have never seen becomes a specific, reproducible issue. Fold identical failures into one signature ranked by how many players each hits, and your worklist sorts itself worst-first instead of arriving as a stream of vague complaints.

This is where a tool like Bugnet earns its place. Its SDK captures every Godot error automatically with the full stack trace plus device, OS, memory, build, and game-state context, folds duplicates into one grouped issue with an occurrence count, and ties each to the build it first appeared on — so you fix the problem that hurts the most players first and confirm it is gone when its signature disappears from the next release.

Reproduce it once with full context and the fix writes itself. The hunt is the expensive part.