Skip to content

Releases: libriscv/godot-sandbox

v0.35: Improved error messaging

30 Dec 19:14
39206a3
Compare
Choose a tag to compare

This is a small release that adds error messaging and an editor break when a called function is not found.

The Zig toolchain produces stripped binaries where functions you want to call need to be added to the public API. Without the public API, it's just an inscrutable binary. Calling a function that was not found resulted in error messages that didn't state exactly what was wrong. This has been fixed.

Full Changelog: v0.34...v0.35

v0.34: Minor fixes

17 Dec 20:56
878e6f0
Compare
Choose a tag to compare

This release is just a convenience release for those who are using CMake or SCons to build their projects. Docker is now completely unused for C++ projects that have their own build system in the project. We are still working out how to instantiate or manage a build system from the editor.

There is now also support for program libraries. In project settings one can add a library and a github account/repository, like so:
mylibrary with the value mygithub/myprograms. Once added, we can do Sandbox.download_program("mylibrary/hello_world"). There must then be a hello_world.zip in the latest release of that repo.

Other improvements:

  • Record public API and properties for profiling, for better reporting even when programs are stripped
  • Improve sandbox loading times slightly
  • Improve best-effort symbol lookups

What's Changed

  • For C++, check if CMake or Scons and disable version check by @fwsGonzo in #238

Full Changelog: v0.33...v0.34

v0.33: Zig toolchain support

11 Dec 20:36
17c17d0
Compare
Choose a tag to compare

There is now support for using Zig to build RISC-V programs that are then used by Godot Sandbox. Zig is a programming language that has a stand-alone program with no dependencies for all platforms. It can build full Linux RISC-V programs using the zig cc and zig c++ commands. The underlying toolchain is LLVM-based and the C++ standard library is libc++. There are now CMake examples using the Zig toolchain and the unittests are also built and run using Zig.

The big picture idea here is that people will be able to compile Godot Sandbox programs no matter which platform they are on, without having to download anything other than Zig. This is effectively a Docker alternative, but with some additional benefits. CMake and git is still required for CMake projects.

Programs built with the Zig toolchain are much smaller than when built with the standard RISC-V GNU toolchain. Have a look for yourself: https://github.com/libriscv/godot-sandbox-programs/releases . The v0.5 binaries built using Zig are nearly half the size from v0.4. Most notably, the reduced binary sizes have reduced binary translation compilation times heavily.

Documentation on how to use this on Windows and macOS will be coming. We've tested macOS and Windows!

image

Otherwise, mostly bugfixes:

  • Fixed a bug with binary translations and multiple instances of the same program with different memory sizes
  • Fix precise simulation not throwing exception after a timeout
  • Added a new program property on Sandbox, exposing the current program in the editor
  • Made heap allocations default 16-byte aligned, in order to match expectations by run-times
  • Add initial native memalign() (+friends) support in the guests
  • Add a pre-generated version of the run-time generated API to CMake builds (default enabled)
  • Fetch the Godot Sandbox C++ API automatically in CMake builds, making it easier to use

Full Changelog: v0.32...v0.33

v0.32: Program libraries and Rust improvements

05 Dec 20:33
2cc72a5
Compare
Choose a tag to compare

It's now possible to download pre-made programs using Sandbox.download_program("name"):

if !FileAccess.file_exists("res://luajit.elf"):
	var buffer = Sandbox.download_program("luajit")
	var fa = FileAccess.open("res://luajit.elf", FileAccess.WRITE)
	fa.store_buffer(buffer)
	fa.close()

var luajit = Node.new()
luajit.set_script(load("res://luajit.elf"))
luajit.execution_timeout = 0
luajit.add_function("test", func(name): return "Test " + str(name) + " called!")
luajit.add_function("add", func(a, b): return a + b)
luajit.run("""
print(test(1))
print(add(333, 666))
function fib(n, acc, prev)
	if (n < 1) then
		return acc
	else
		return fib(n - 1, prev + acc, acc)
	end
end
print("The 500th fibonacci number is " .. fib(500, 0, 1))
""")

Read more about this feature here.

Rust has gained a new GodotString and access to the public API:

extern "C"
fn test(a: i32, b: i32, c: GodotString) -> Variant {
	let sum = a + b + c.to_string().parse::<i32>().unwrap();
	Variant::new_integer(sum.into())
}

pub fn main() {
	register_public_api_func3("test", test, "int", "int a, int b, String c");
}

Also:

  • Fixed a rare bug with shared execute segments in libriscv
  • Removed old Public API method as it didn't work with all languages, nor with stripped binaries
  • Added new Public API method that is accessible during int main() (startup).
  • Implement Public API support for sandboxes loaded from byte arrays
  • Fixed empty Public API argument list appearing as Object
  • Add support for Zig cc/c++ RISC-V builds using riscv64-linux-musl
  • Fix multiple build issues when LLVM's libc++ is the standard library
  • Add alternative API paths for when std::string is not 32-byte with 16b SSO
  • Fixed compiler flags for C sources when using the CMake API

What's Changed

  • Allow creating public API at init through system call by @fwsGonzo in #230
  • Add function to download a known program from programs repo by @fwsGonzo in #231

Full Changelog: v0.31...v0.32

v0.31: Minor bugfixes

01 Dec 14:34
402a90b
Compare
Choose a tag to compare

This release is mostly maintenance. Small changes that removes some friction here and there.

  • Add Sandbox::try_compiling_binary_translation() to automatically produce a shared object (only tested on Linux so far)
  • Toggling generate run-time API and methods requires an editor restart (fixed)
  • Cache StringName usage where possible, reducing overhead of getting/setting properties
  • Add ArrayProxy::get_as_type()
  • Add better support for detecting void return types in the generated run-time API and public APIs
  • Enable C++ demangling and 128-bit integers again in WASM
    • Sidenote: Demangling can probably be enabled for other platforms too, but needs to be verified first

In the future we will try to get editor documentation into Godot Sandbox, however it is currently only available for debug builds which we don't produce. We already build a ton of artifacts in CI and we just cannot build more. For those of you who knows your way around CI and you really want documentation, it's currently sitting in an open PR.

Also, check out the newly written introduction in the documentation for Godot Sandbox.

Full Changelog: v0.30...v0.31

v0.30: Custom public APIs

25 Nov 19:01
8a169d4
Compare
Choose a tag to compare

Public API with auto-complete

It is now possible to craft a custom API for Sandbox programs, documented here. The public API is optional and overrides the old method when present.

Screenshot from 2024-11-25 19-03-28

The public API generates detailed auto-completion in GDScript.

Binary translations loadable at run-time

It is now also possible to load shared objects that contains binary translations for programs on Windows, macOS and Linux. Documented here. Binary translations are freestanding C99 and should be very easy to compile using any local compiler. Adding -DCALLBACK_INIT will make the dll self-register when loaded:

x86_64-w64-mingw32-gcc-win32 -shared -O2 -DCALLBACK_INIT bintr_test.cpp -o bintr_test.dll

An example of compiling a binary translation for Windows from a Linux terminal. The .dll can be loaded using Sandbox.load_binary_translation("res://bintr_test.dll") during initialization. Loading DLLs after init is disabled as a security measure.

This feature is especially useful during development as baking binary translations into Godot or an extension is time-consuming. Compiling a shared object can be done automatically, even from the Godot editor, but the project must be reloaded in order to load it during init. It can technically also be used as part of shipping (performant) updates to desktop systems.

Other changes

  • Setting max instruction limit to 0 will now disable execution timeout and enable faster intepretation, resulting in up to ~15% performance gain.
  • Improve error messages when failing to cast or unbox Variants
  • Add Array::at_or(), ArrayProxy::get_or() and DictAccessor::value_or() to the public API
  • Add Sandbox::reset() which quickly resets the loaded program
  • Fix missing language icons in the editor
  • The performance of freeing heap allocations has been improved slightly

PRs merged

  • Add support for loading binary translation DLLs on Windows by @fwsGonzo in #221
  • Separate languages into separate docker and project folders by @fwsGonzo in #222
  • Allow programs to expose custom API by @fwsGonzo in #224
  • Parse public API and generate method information by @fwsGonzo in #225

Full Changelog: v0.29...v0.30

v0.29: Various bugfixes, SConstruct custom builds

17 Nov 21:33
b14c140
Compare
Choose a tag to compare

This release fixes quite a few bugs, further stabilizing the APIs and the extension.

  • It's now possible to build custom programs using SConstruct
    • When a SCons file is present, saving a .cpp file will invoke scons instead
  • Make it possible to disable execution timeout by setting it to 0, which yields up to 13% performance
    • If the sandbox program loops forever the game can still be closed from the editor or process explorer, like other hung processes
  • Completely disable all socket calls, reducing size of all shipped binaries
  • Add a work-around for an issue with icon registration in the Android editor
  • Fix mishap with BCLR and BINV instruction bitmasks, leading to exception about unimplemented opcodes
  • Fix PackedVector3Array not able to be constructed from a Variant
  • Fix Sandbox monitoring properties being inadvertently stored in project file
  • Many improvements made to Array and PackedArray<> interactions
  • Improve support for double builds, add DOUBLE_PRECISION CMake option to enable in custom builds
  • Add size() and is_empty() to packed arrays
  • Add support for PackedVector4Array
  • Add a new Sandbox property that limits maximum heap allocations
  • Add monitoring that shows arena allocations, deallocations and current chunk usage
  • Add EXPECT() macro to the API
  • Increase the argument limit for vmcallv to 16 (unxboxing disabled)
  • Increase the argument limit for vmcall to up to 11 arguments (unboxing enabled)
    • The limit is still 7 integral and 8 fp arguments, but can now be better spread out

PRs

Full Changelog: v0.28...v0.29

v0.28: Live-profiling and Godot module support

03 Nov 15:25
9cb7535
Compare
Choose a tag to compare

Godot Sandbox can now be built as a module, thanks to @Ughuuu. There is now also a live-profiling feature that enables automatic sampling of Sandbox programs in order to show where time is most spent. The feature works on all platforms, including Web. Documentation here.

image

The image shows live-profiling being displayed in the demo project. The profiling information is automatically gathered over time.

PRs

  • Add support for instruction-counter profiling by @fwsGonzo in #199
  • Build as both addon and module. Part 1, integration. by @Ughuuu in #184
  • Make static libs too by @Ughuuu in #202
  • package everything for modules by @Ughuuu in #203

Full Changelog: v0.27...v0.28

v0.27: Hot-reloading support

26 Oct 11:53
69d2e2d
Compare
Choose a tag to compare

This release adds hot-reloading support to the Sandboxes initialized with set_program, directly or indirectly.

It also adds method argument names with default values to the run-time API. The full run-time API has higher compilation times, but the argument names can be disabled in project settings. It's also possible to filter out classes in order to reduce the generated API down to a more manageable size for the compiler. There is a default filtering of things like OS, multiplayer and networking.

Screencast.from.26.okt.2024.kl.18.18.+0200.webm

Full Changelog: v0.26...v0.27

v0.26: Run-time generated C++ API

25 Oct 17:55
5383d75
Compare
Choose a tag to compare

A new run-time generated C++ API is made available to Docker- and CMake-based projects. The API is auto-generated on first save, and contains all loaded classes including extra modules and GDextensions. This adds auto-complete to your external editor as well, which greatly increases productiveness.

Since it's a run-time generated API it will automatically follow Godot versions forward.

	JSON j = ClassDB::instantiate<JSON>("JSON");
	j.parse(
	R"({
		"pi": 3.141,
		"happy": true,
		"name": "Niels Nielsen",
		"nothing": null,
		"answer": {
			"everything": 42
		},
		"list": [1, 0, 2],
		"object": {
			"currency": "USD",
			"value": 42.99
		}
	})");
	print(j.get_data());

Even the Sandbox class can be auto-completed in your favorite editor, as it is a loaded extension:

extern "C" Variant test_sandbox_pass(Sandbox s) {
	Sandbox s2 = s.FromBuffer(PackedArray<uint8_t>((const uint8_t *)binary_data, binary_data_size));
	return s2;
}

In the future we may add better support for static functions in classes and also try to add inline documentation to classes, properties and methods.

A new load<Class> resource loading helper has been added:

Node2D scene = load<PackedScene>("res://scenes/mod/mod.tscn").instantiate();

You can iterate nodes by group:

    for (Node node : get_tree().get_nodes_in_group("Coins")) {
    }

Other changes include preventing access to restrictions while in an active VM call, even indirectly.

What's Changed

Full Changelog: v0.25...v0.26