Godot Version
3.5.3-stable
Question
I’m trying to add modding support to my game, thinking of either making it with GDScript or perhaps some lua extension, the problem is that modders would have access to things like OS related functions and classes that manage the game in ways it could break when irresponsibly modded. Is there any way I can limit what singletons/classes a script/class can call? I would much rather expose an API specific for modding with it’s own signals and methods. Thank you very much in advance.
dbat
January 21, 2024, 6:48am
2
You’re in for a world of hurt. I don’t think this is even possible. Can other engine’s do this?
Your best bet would be to be open about how mods can be malicious and solve the problem on a social-level. You may have to vet mods manually and probably force your game to only fetch mods from some single, controllable repo.
After seeing this post, I had found an open issue on GitHub for adding this. I came back here to share it, but then I realized I didn’t have it in my history (was on mobile and it opened in the GitHub app), and can’t find it for some reason. I’ll keep looking, but if anyone else sees the issue I would appreciate the link
Just found it after a lot of searching, though I feel like this may be a different proposal than the one I initially saw, but still same idea:
opened 02:17PM - 29 Jul 22 UTC
topic:core
### Describe the project you are working on
Godot
### Describe the problem… or limitation you are having in your project
It seems many users want to use Godot in a way where more complex content (such as scenes or Godot resources or even scripts) are downloaded from the internet. Unlike just sending simple variants, this is very insecure because the attack surface is huge.
Just limiting the Godot API (or script) to not accessing files and similar things is far from ideal because the more code you can run the more you can workaround to exploit the engine, and Godot is not designed for security (except in some areas like networking and protocols), it is designed for performance.
### Describe the feature / enhancement and how it helps to overcome the problem or limitation
A _real_ sandbox mode to run projects should be provided to users, to make sure security is as high as possible and attack surfaces are as limited as possible.
### Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The way this would work takes advantage of the Godot architecture. Basically, it would split Godot into two processes, similar to software like Chrome works, one that talks to the low-level OS and another that runs the game in a sandbox (and sends commands to the first)
As such, this means that some of the core engine classes would effectively work as "proxies", like:
* OS
* DisplayServer
* AudioDriver
* RenderingDevice
* FileAccess
* DirAccess
Meaning we would have a platform "sandbox" that has sandbox versions of the above classes, like DisplayServerSandbox that call the actual ones running outside of the sandbox (which is a regular Godot instance that starts as sandbox host and receives the sandbox API commands).
And not a lot more, so this means only those few classes are the ones that need to be "fortified" to avoid exploits, the rest can run entirely sandboxed.
For the sandbox itself, there are several available FOSS libraries that provide sandboxing, and alternatively WebAssembly can also be used to run the sandbox.
The best advantage of this approach is that it should not be very difficult to implement and provides a very easy and trustworthy way of running user content downloaded from the internet without danger.
A relatively straightforward way to implement this sandboxing could be via [Wasmer](https://wasmer.io/), which is multi platform and portable.
### If this enhancement will not be used often, can it be worked around with a few lines of script?
N/A
### Is there a reason why this should be core and not an add-on in the asset library?
N/A
Edit: just saw this one that was referenced from that one, which I think was the one I originally saw:
opened 11:24PM - 08 Jun 22 UTC
topic:core
### Describe the project you are working on
Currently working on a project on… space exploration (think "No Man's Sky") where players manage their spaceships very technically, customizing the ship's software by writing real code (e.g. rewriting the autopilot).
Previously published a game where player character was a hacker controlling robots by scripting code.
Also planned a mecha robot building game in a style similar to games like Kerbal Space Program but more inclined to software and circuits, but I gave up on the project due to, among other things, the lack of this specific feature.
### Describe the problem or limitation you are having in your project
Some games and apps involve players typing their own code, which is then interpreted/executed as part of the process.
One example is games where the player is expected to write logic as part of the game mechanic (control robots, hack into fictional systems, etc). There is an entire game genre based on this (https://en.wikipedia.org/wiki/Programming_game).
Another example is games which can be customized by players (mods), including writing script code (e.g. enemy AI).
So far, when working with this mechanic, I had to design a scripting language and write my own interpreter (I have seen others trying the same as well). Due to having to write the interpreter, the scripting was rudimentary (sequential) and players complained they wanted usual programming features like branching, loops, functions, local variables, etc, and were frustrated by the lack of.
GDScript could be used to implement in-game programming with a very functional, complex, stable and user friendly language, and it comes with a compiler for free, zero dev effort. However, due to the access to the engine globals, this comes with severe issues. Players could:
- Break the game behaviour
- Call `OS` and damage something in their system
- Call `ResourceSaver` and steal assets
- In multiplayer games (or with leaderboards), extract server confidential credentials
And if players are meant to share scripts (e.g. mods), hell is unleashed with anything from "delete all hdd" pranks to trojan horse attacks.
Therefore, so far using GDScript to power in-game general purpose scripting is "a nice thing you can't have".
### Describe the feature / enhancement and how it helps to overcome the problem or limitation
This proposal (implemented in PR https://github.com/godotengine/godot/pull/61831) adds a feature to the `GDScript` class allowing to disable globals, per script, via a simple method call. All game scripts behave as usual by default, but an individual script can have a flag set so that specific script won't have access to any engine globals, including class names, singletons and constants, becoming detached from the game system. It still _can access_ anything if access is _explicitly given_, via variables or method arguments. Including globals in a script with globals disabled results in the script not compiling or running.
By disabling globals in a script of interest, the GDScript class can be used as a general purpose scripting parser, compiler and interpreter, running inside a safe box and interacting only with what is desired.
### Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The code below demonstrates how to use the new `set_globals_disabled` method.
Assuming a file `res://user_script.gd` (or a String assigned into `GDScript.source_code`), which is meant to be isolated:
```gdscript
var my_var
func my_func(arg):
print("Hello %s!" % arg)
```
A node can safely run this script with globals disabled:
```gdscript
var new_script = load("res://user_script.gd")
new_script.set_globals_disabled(true)
if new_script.reload():
# Script recompiled successfully
var new_script_instance = new_script.new()
# Any method can be called externally,
# and variables can be externally assigned
new_script_instance.my_var = 42
new_script_instance.my_func("world") # prints "Hello world!"
else:
# Pauses with an error if running from the editor,
# fails silently and continues running in standalone build
print("Failed to compile script")
```
An example to give explicit access to something, assuming the `res://test_script.gd` script:
```gdscript
var input
func do_something():
if input.is_action_pressed("ui_accept"):
print("Hello world!")
```
The `input` local variable can be used to give the script access to the `Input` singleton:
```gdscript
var new_script = load("res://test_script.gd")
new_script.set_globals_disabled(true)
if new_script.reload():
var new_script_instance = new_script.new()
new_script_instance.set("input", Input) # Fails silently if user doesn't want to declare or use `var input`
new_script_instance.do_something()
```
Function arguments also work with external objects. The following script would work even with globals disabled, if `ai_search_player` is called externally providing the `KinematicBody` arguments:
```gdscript
func ai_search_player(my_kinematic_body, player_kinematic_body):
var player_distance = (player_body.global_transform.origin - my_body.global_transform.origin).length()
```
### If this enhancement will not be used often, can it be worked around with a few lines of script?
No, as this requires changes in the GDScript and GDScriptCompiler classes, which are engine code.
### Is there a reason why this should be core and not an add-on in the asset library?
An addon is not possible since this cannot be implemented via scripting.
wchc
August 11, 2025, 7:40am
5
There was a very related discussion topic not that long ago
Hey that’s me!
Just for clarification, the approach I plan on using and discuss on my post is rather an “addon” system and not a modding system. Sandboxing imported scenes and scripts seems feasible, but modding is a whole different beast. As I mention, for modding, I use Godot Mod Loader , which is not sandboxed and probably won’t be in the near future, as Godot in general.
Sandbox is a complicated topic mostly because it requires much more customization than I expected at first glance. For an agnostic engine, like Godot, how would you decide on what should be restricted or not in a sandbox? Clearly there’s a need to specify your own limits through an API for each specific case. Apart from all the technical challenges of actually isolating a program at a system level, which is truly sandboxing. Still, Godot is also used for actual applications and not just games, so not everyone would benefit from sandbox, and Godot PRs like their features to be apt for everybody!
Godot native sandboxing is going to take a looong while, just guessing. In the mean time, if you want a true sandbox, check godot-sandbox . However, it is not a simple library! And honestly, you seem like just wanting mod support, for what GML seems more than enough. If your mods are going to be downloaded manually by the users and loaded on startup, yeah, just use the loader . We’ve all been downloading mods for years exposing ourselves to the risk of malicious intent, it’s a risk we accept and usually, if you’ve got your 101 internet course, nothing bad will ever happen. Finally, if you want your mods to be automatically downloaded at runtime (something more akin to UGC items), you can try my approach.