Safe, low-latency and fast sandbox for the Godot game engine.
This extension exists to allow Godot creators to implement safe modding support, such that they can pass around programs built by other players, knowing that these programs cannot harm other players.
-
Automatic (Recommended): Download the plugin from the official Godot Asset Store using the AssetLib tab in Godot by searching for Godot Sandbox. TODO
-
Manual: Download the latest github release and move only the addons folder into your project addons folder.
Create a new Sandbox
and assign a RISC-V ELF program resource to it.
extends Sandbox
func _ready():
# Make a function call into the sandbox
vmcall("my_function", Vector4(1, 2, 3, 4));
# Measure the time it takes to cold-call one function
print("\nMeasuring call overhead...");
var emptyfunc = vmcallable("empty_function");
var t0 = Time.get_ticks_usec()
emptyfunc.call();
var t1 = Time.get_ticks_usec()
print("Execution time: ", (t1 - t0), "us")
# Pass a complex Variant to the sandbox
var d = Dictionary();
d["test"] = 123;
vmcall("my_function", d);
# Create a callable Variant, and then call it later
var callable = vmcallable("function3");
callable.call(123, 456.0, "Test");
# Pass a function to the sandbox as a callable Variant, and let it call it
var ff : Callable = vmcallable("final_function");
vmcall("trampoline_function", ff);
# Pass a packed byte array
var testbuf = PackedByteArray();
testbuf.resize(32);
testbuf.fill(0xFF);
vmcall("test_buffer", testbuf);
#vmcall("failing_function");
pass # Replace with function body.
The API towards the sandbox uses Variants, and the API inside the sandbox uses (translated) Variants.
extern "C"
void function3(Variant x, Variant y, Variant text) {
UtilityFunctions::print("x = ", x, " y = ", y, " text = ", text);
}
Above: An example of a sandboxed C++ function.
- You can implement a modding API for your game, to be used inside the sandbox. This API can then be used by other players to extend your game, in a safe manner. That is, they can send their mod to other people, including you, and they (and you) can assume that it is safe to try out the mod. The mod is not supposed to be able to do any harm. That is the whole point of this extension.
- You can implement support for your favorite language inside the sandbox. The sandbox receives Variants from Godot or GDScript, and can respond back with Variants. This means the communication is fully dynamic, and supports normal Godot usage.
Languages that are known to work inside libriscv:
- QuickJS
- C
- C++
- Rust
- Zig
- Nim
- Nelua
- v8 JavaScript w/JIT
- Go (not recommended)
- Lua, Luau
- Any other language that can produce RISC-V programs
The sandbox is implemented using libriscv which primarily focuses on being low-latency. This means that calling small functions in the sandbox is extremely fast, unlike all other sandboxing solutions.
There are high-performance modes for libriscv available for both development and final builds. When developing on Linux, libtcc-jit is available (which is in theory portable to both Windows and MacOS). And for final builds one can produce a high-performance binary translation, with up to 92% native performance, that can be embedded in the project (either Godot itself, or the GDExtension). This high-performance binary translation works on all platforms, such as Nintendo Switch, Mobile Phones, and other locked-down systems. It is especially made for such systems, but is inconvenient to produce.
Please see the documentation for libriscv for more information.
As a final note, the default interpreter mode in libriscv is no slouch, being among the fastest interpreters. And will for most games, and in most scenarios be both the slimmest in terms of memory and the fastest in terms of iteration. Certain variant operations will call out to Godot in order to get native performance.
Requirements:
If you want to contribute to this repo, here are steps on how to build locally:
scons
Linting:
./scripts/clang-tidy.sh
This project provides a dockerfile for compiling cpp code locally. For usage example, go to:
cd program
docker run -v .:/usr/src -d ghcr.io/fwsgonzo/compiler build.sh