RadicalBeard.Evaluate 0.2.0

dotnet add package RadicalBeard.Evaluate --version 0.2.0
                    
NuGet\Install-Package RadicalBeard.Evaluate -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RadicalBeard.Evaluate" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RadicalBeard.Evaluate" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="RadicalBeard.Evaluate" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RadicalBeard.Evaluate --version 0.2.0
                    
#r "nuget: RadicalBeard.Evaluate, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RadicalBeard.Evaluate@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RadicalBeard.Evaluate&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=RadicalBeard.Evaluate&version=0.2.0
                    
Install as a Cake Tool

Evaluate

A data-driven, moddable game framework built as an extension that runs inside Godot (Godot is the host; Evaluate has no main). Engine-side code is .NET/C# (net10.0, Godot 4.6-mono). Gameplay is authored in "evt" scripts whose YAML frontmatter declares a capability-scoped signature; a custom loader sandboxes each script to exactly what it declares. Scripts are auto-discovered and hot-reloaded by default.

Architecture

  • Frontmatter → signature. The leading --- block is split off and parsed as real YAML (YamlDotNet) into config:, apis:, register:, returns:, assets:; the Lua body is handed to the VM verbatim (line numbers preserved). The signature is the C#↔Lua boundary contract — returns declares typed, access-scoped members (no Lua type system). (runtime/Frontmatter.cs)
  • Per-script sandbox. Each body runs via load(body, name, "t", env) on a shared LuaState, where env holds only the declared config.*, declared apis, the always-available std and ambient godot, plus a few safe primitives — including the metatable builtins (setmetatable/getmetatable/ rawget/rawset/rawequal/rawlen) so scripts can define classes the idiomatic Lua way. Undeclared globals (os, io, …) are absent, and pcall is intentionally withheld (errors surface rather than being swallowed). (runtime/Loader.cs)
  • Custom require narrows the returned module to its returns contract (get/set property → get_/set_ accessors; plain method; read-only hides the setter; missing accessor errors).
  • Data lives in the engine. entity.spawn{…} creates a C# entity (runtime/Engine.cs); the Lua handle proxies reads/writes into C# via metatable.
  • Auto-discovery. The runtime recursively scans res://scripts; any script with a register: block is wired to Godot lifecycle (on_start once, on_update(dt) per frame). Each hook may be registered by only one script project-wide.
  • Hot reload (default). A FileSystemWatcher watches scripts, configs, and frontmatter-declared assets:; changes reload on the main thread. A changed system re-runs its body and refreshes its hook closures while live entities persist. (runtime/EvaluateRuntime.cs)
  • Lifecycle hooks. register: wires on_start, on_update(dt), on_physics_update(dt), on_input(event) to Godot's Node lifecycle. One registration per hook, project-wide.
  • std.* standard library. Real C#-backed types via the [LuaObject] source generator — std.vec3, std.vec2, std.color, std.vector, std.linked_list (runtime/Std.cs).
  • Persistence (save). SQLite-backed runtime/player data under ~/.local/share/evaluate/save.set/get/delete (runtime/Persistence.cs).
  • Godot binding (ambient, default). godot.<Type> resolves any Godot type on first use (runtime/GodotBinder.cs):
    • instancesgodot.Node3D.new() (Activator); member access routes through the engine ClassDB (GodotObject.Call/Get/Set), not reflection. Instances are ILuaUserData, so they pass back into the engine (world:add_child(node));
    • propertiesnode.position = std.vec3(…) / node.position;
    • signalsnode:connect("timeout", fn) (0–6 args, dispatched on the main thread) and node:emit_signal(...);
    • enums/constantsgodot.Key.Space, godot.Timer.TimerProcessCallback.Idle;
    • marshalling — exhaustive: primitives, strings, NodePath, objects, Array/Dictionary; rich C#-backed Vector2/3 & Color (↔ std.*); and every other struct (Vector4, Vector2I/3I, Quaternion, Rect2, Plane, Aabb, Basis, Transform2D/3D) + packed arrays as named-field/list tables. Reads are tables; writes are target-type-aware — assigning a table to a struct property builds the exact struct (so node.transform = t round-trips);
    • statics — reflection fallback, or a pre-baked zero-reflection binding.
  • Pre-bake (source generator). generator/ is a Roslyn IIncrementalGenerator: [BindGodot(typeof(Godot.OS))] emits OsBinding.Create() with direct, reflection-free calls (53 bound OS methods), filtered to Lua-convertible signatures. The binder prefers pre-baked bindings.

Base VM

Lua-CSharp (LuaCSharp 0.5.5, Lua 5.2). Source-generator interop ([LuaObject]) → AOT-clean, low-allocation. Its API is async-only; we bridge to sync for Godot's _Process (safe because script calls don't actually await). Dialect note: scripts use x = x + …, not the planned custom dialect's +=.

Run

godot --headless --path .            # demo: discovery, engine call, instance+signal, std, movement
godot --headless --path . -- --test  # enforcement suite (6 tests)

Layout

project.godot  main.tscn  Evaluate.csproj
runtime/    EvaluateRuntime.cs  Loader.cs  Std.cs  Frontmatter.cs  Toml.cs
            GodotBinder.cs  Persistence.cs  BindGodotAttribute.cs  Prebaked.cs
            EvaluateTests.cs
generator/  Evaluate.Generator.csproj  BindGodotGenerator.cs   (Roslyn source generator)
scripts/    game.evt player.evt enemy_factory.evt  game.toml player.toml
tests/      forbidden_global / undeclared_api / missing_accessor /
            system_a / system_b / readonly_module  (.evt)
  • Godot coverage is complete: instance + static members (any type), all Variant structs + packed arrays, enums/constants, and signals — all two-way. Static methods with struct/packed signatures bind via the reflection fallback (layered over the pre-baked primitives). Instance access is reflection-free (engine ClassDB Call/Get/Set). Remaining (perf only): extend the source-gen pre-bake to struct/packed static signatures so they too avoid reflection.
  • Frontmatter LSP (deferred): editor diagnostics for the signature block — e.g. red-underline a non-existent godot.* API or missing config file. The Lua body itself rides the standard Lua LSP.
  • AOT export & mod packaging/distribution: not yet built.
  • Out of scope by decision: a Lua type system (signature contract is enough) and sandbox resource limits / DoS protection (modding is free).
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 0 6/18/2026
0.1.0 41 6/17/2026