Godot Sandbox

repository·main·Indexed 19 days ago

https://github.com/libriscv/godot-sandbox

A safe, high-performance sandbox for the Godot game engine that enables secure modding APIs and high-performance code execution. It allows developers to write and distribute RISC-V ELF resources using C++, Rust, or SafeGDScript across all platforms. The project includes a build system utilizing Zig and CMake, a Godot editor plugin for dependency management, and a GDExtension for RISC-V integration.

Tokens
15.1K
Snippets
37
Records
56
Agent score
63%

What's inside godot-sandbox

  1. Overview of GDScript Compiler IR Optimizations

    main

    The GDScript-to-RISC-V compiler performs optimizations on the Intermediate Representation (IR) before generating RISC-V code. These optimizations run in multiple iterative passes to reduce code size, eliminate redundancy, and improve runtime performance.

    Optimization Pipeline Order:

    1. Constant Folding (Enables downstream optimizations)
    2. Copy Propagation (Basic cleanup)
    3. Enhanced Copy Propagation (Advanced cleanup)
    4. Loop-Invariant Code Motion (Hoist invariants)
    5. Peephole Optimization (Local patterns)
    6. Peephole Optimization (Second pass)
    7. Redundant Store Elimination (Before dead code)
    8. Peephole Optimization (Final cleanup)
    9. Dead Code Elimination (Remove unused code)
  2. Loop-Invariant Code Motion (LICM)

    main

    Moves loop-invariant computations outside of loops to avoid redundant execution.

    Limitations & Behavior:

    • Nested Loops: Currently, the optimizer skips the entire function if any nested loops are detected to avoid hoisting past incorrect loop headers.
    • Hoisting Criteria: Only hoists pure operations: LOAD_IMM, LOAD_FLOAT_IMM, LOAD_BOOL, LOAD_STRING, and MOVE.
    • Safety Checks: Verifies the destination register is not read before definition and that source registers are not modified anywhere within the loop.
    • Identification: Identifies loops via back edges (a JUMP to an earlier label).

    Example:

    while i < 10:  # "10" is loop-invariant
        i = i + 1  # "1" is loop-invariant
  3. Constant Folding Optimization

    main

    Evaluates constant expressions at compile time instead of runtime. It handles integer and float arithmetic, supports comparison operations, respects GDScript type promotion (e.g., int + float $\rightarrow$ float), and avoids division by zero.

    Example:

    var x = 5 + 10  # Compiled as: x = 15
    var y = 2.0 * 3.0  # Compiled as: y = 6.0
  4. How to use Godot Sandbox programs

    main

    Godot Sandbox allows you to run C++, Rust, and SafeGDScript by compiling them into ELF resources. You can use these resources in two ways:

    1. Using a Sandbox Node

    Create a new Sandbox node in your scene and assign an ELF resource to it.

    • The Sandbox node follows the standard Godot node lifecycle.
    • You can use @export to provide auto-completion from other GDScripts.

    2. Using ELF resources directly as scripts

    You can directly assign an ELF script resource to a node.

    • This uses a shared sandbox among all instances of that script, providing maximum scalability.
    • You can call functions and attach signals just like standard GDScript.
  5. Understanding the Stack-Based Codegen Bottleneck

    main

    A critical architectural detail for developers is that the current RISC-V codegen is entirely stack-based and ignores the sophisticated register allocator.

    Current Behavior:

    • All operations load Variants from the stack.
    • Operations use only t0 as a scratch register.
    • Results are stored back to the stack.

    Implications:

    • Even though a register allocator assigns 18 physical RISC-V registers (t0-t6, s1-s11), they are not utilized for data movement in the current implementation because the Variant ABI is complex (Variants are 24 bytes and system calls operate on Variant pointers).
    • The main performance bottleneck is this stack-based approach rather than the IR optimizations themselves.
  6. Copy Propagation and Enhanced Copy Propagation

    main

    These optimizations eliminate redundant MOVE instructions.

    • Copy Propagation: Eliminates redundant MOVE instructions after constant loads.
    • Enhanced Copy Propagation: Tracks copy chains and propagates sources through uses. It follows chains to the original source and verifies the source register hasn't been modified. It clears tracking at control flow boundaries and handles special cases for BRANCH_ZERO/BRANCH_NOT_ZERO.

    Example (Enhanced):

    var a = x
    var b = a
    return b  # Can use x directly
  7. Build RISC-V C++ projects using build.sh

    main

    This project uses a build.sh script to build RISC-V C and C++ programs with the Godot Sandbox API. The build process utilizes Zig to handle the compilation and linking. The resulting binaries are placed in a hidden .build directory.

    # Example: Build with stripping enabled
    $ ./build.sh --strip
  8. Build Godot Sandbox as a Godot Module

    main

    To build Godot Sandbox as a native module within a Godot repository, add it as a submodule and initialize it:

    git submodule add https://github.com/libriscv/godot-sandbox modules/sandbox
    cd modules/sandbox
    git submodule update --init --recursive
  9. Embed binary translations into the Godot Sandbox extension

    main
    To include binary translation files in the Godot Sandbox extension, place the files directly into the src/bintr/ directory. Files located in this folder are automatically embedded into the extension during the build process.