103 lines
2.1 KiB
Markdown
103 lines
2.1 KiB
Markdown
|
|
# OneBit Lua Runtime
|
||
|
|
|
||
|
|
Native GDExtension prototype for the 1BitRL v2 Lua runtime contract.
|
||
|
|
|
||
|
|
## Current Scope
|
||
|
|
|
||
|
|
This runtime is intentionally small and breaking:
|
||
|
|
|
||
|
|
- `api_version = 2` scripts only.
|
||
|
|
- No `game` table.
|
||
|
|
- Explicit `ctx` and `state` handler arguments.
|
||
|
|
- Lua emits commands and logs; it does not mutate the Godot world directly.
|
||
|
|
- Queries cross a Godot-owned query host boundary.
|
||
|
|
- Instruction budget is enabled for handler calls.
|
||
|
|
|
||
|
|
Initial Lua API:
|
||
|
|
|
||
|
|
```lua
|
||
|
|
sense.is_walkable(x, y)
|
||
|
|
sense.find_nearest(group)
|
||
|
|
move.step(dx, dy)
|
||
|
|
log.say(message, duration)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Requirements
|
||
|
|
|
||
|
|
- Godot 4.6.
|
||
|
|
- `godot-cpp` master, targeting `api_version=4.6`.
|
||
|
|
- SCons.
|
||
|
|
- A Lua development package with `pkg-config`.
|
||
|
|
|
||
|
|
This machine currently uses Lua 5.1:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
pkg-config lua-5.1 --cflags --libs
|
||
|
|
```
|
||
|
|
|
||
|
|
Lua 5.1 is explicit for now because it is the installed system package. If the project moves to Lua 5.4, install a Lua 5.4 development package and build with the matching pkg-config name, for example:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
scons platform=linux target=template_debug api_version=4.6 lua_pkg=lua5.4
|
||
|
|
```
|
||
|
|
|
||
|
|
Script semantics differ between Lua 5.1 and 5.4, so do not change the runtime version silently.
|
||
|
|
|
||
|
|
## Build
|
||
|
|
|
||
|
|
Clone `godot-cpp` as a submodule or checkout at `godot-cpp/`, then run:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
scons platform=linux target=template_debug api_version=4.6 -j4
|
||
|
|
```
|
||
|
|
|
||
|
|
The demo extension library is written to:
|
||
|
|
|
||
|
|
```text
|
||
|
|
demo/addons/onebit_lua/bin/
|
||
|
|
```
|
||
|
|
|
||
|
|
## Smoke Test
|
||
|
|
|
||
|
|
Run the demo project headlessly:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
godot --headless --path demo
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected behavior:
|
||
|
|
|
||
|
|
- Loads `OneBitLuaRuntime`.
|
||
|
|
- Loads a tiny `api_version = 2` script.
|
||
|
|
- Calls `on_update(ctx, state)`.
|
||
|
|
- Mutates `state.count`.
|
||
|
|
- Emits one `move` command.
|
||
|
|
- Emits one log entry.
|
||
|
|
- Calls the GDScript query host for `sense.is_walkable` and `sense.find_nearest`.
|
||
|
|
|
||
|
|
## Safe Lua Libraries
|
||
|
|
|
||
|
|
The runtime opens only selected Lua libraries:
|
||
|
|
|
||
|
|
- base
|
||
|
|
- math
|
||
|
|
- string
|
||
|
|
- table
|
||
|
|
|
||
|
|
It does not open:
|
||
|
|
|
||
|
|
- `io`
|
||
|
|
- `os`
|
||
|
|
- `package`
|
||
|
|
- `debug`
|
||
|
|
|
||
|
|
After opening the base library, the runtime removes dangerous dynamic-loading globals:
|
||
|
|
|
||
|
|
- `dofile`
|
||
|
|
- `load`
|
||
|
|
- `loadfile`
|
||
|
|
- `loadstring`
|
||
|
|
- `module`
|
||
|
|
- `require`
|
||
|
|
- `collectgarbage`
|