252 lines
23 KiB
Markdown
252 lines
23 KiB
Markdown
# 05 — Research: Script-Engine für Mod-Stufe (c)
|
|
|
|
Stand: 2026-08-11. Antwort auf `issues/05-research-script-engine.md`.
|
|
**Keine Entscheidung — Fakten plus begründete Empfehlung.**
|
|
|
|
## Methodik
|
|
|
|
Zwei Arten von Aussagen, überall getrennt gekennzeichnet:
|
|
|
|
- **[gemessen]** — auf dieser Maschine ausgeführt: `cargo 1.96.0` / `rustc 1.96.0`,
|
|
Host `x86_64-pc-windows-msvc`, LLVM 22.1.2. Versionen live über `cargo generate-lockfile`
|
|
gegen crates.io aufgelöst, Dependency-Zahlen aus `Cargo.lock` (`name =`-Einträge, gleiche
|
|
Methode für alle Kandidaten), Build-Zeiten mit `Measure-Command` über `cargo build` (debug,
|
|
leerer `fn main(){}`, eigener `CARGO_TARGET_DIR`).
|
|
- **[Quelle]** — aus Primärquelle zitiert, URL jeweils direkt dabei und in der Quellenliste.
|
|
|
|
Was nicht verifiziert werden konnte, steht explizit unter „Nicht verifiziert".
|
|
|
|
## Aufgelöste Versionen [gemessen, 2026-08-11]
|
|
|
|
| Crate | Aufgelöste Version | Release-Datum [Quelle] |
|
|
|---|---|---|
|
|
| `rhai` | **1.25.1** | 2026-05-29 — crates.io API |
|
|
| `mlua` (`lua54`, `vendored`) | **0.12.0** | 2026-07-05 — crates.io API |
|
|
| `wasmtime` | **47.0.3** | 2026-07-31 — crates.io API |
|
|
| `wasmi` | **1.1.0** | 2026-06-12 — crates.io API |
|
|
| `extism` | **1.30.0** | 2026-06-04 — crates.io API |
|
|
|
|
---
|
|
|
|
## Vergleichstabelle
|
|
|
|
| Kriterium | **Rhai 1.25.1** | **Lua 5.4 via mlua 0.12** | **WASM (wasmtime 47 / extism 1.30 / wasmi 1.1)** |
|
|
|---|---|---|---|
|
|
| **C-Toolchain unter Windows** | Keine. Kein `cc`, `libc`, `bindgen` oder `pkg-config` im Baum — reines Rust. | Ja, aber faktisch gratis: `vendored` kompiliert die Lua-C-Quellen über `cc`. [gemessen] hat `mlua-sys` hier eine echte `lua5.4.lib` erzeugt, **ohne dass `cl.exe` im PATH lag** — das `cc`-Crate findet MSVC über `vswhere` (VS 18.6 installiert). Der MSVC-Linker ist für den `*-windows-msvc`-Rust-Toolchain ohnehin Pflicht. | `wasmtime` hat `cc` als Build-Dep, praktisch aber irrelevant (msvc = Tier 1). `wasmi` ist reines Rust und `no_std`-fähig. |
|
|
| **Dependencies (Cargo.lock)** [gemessen] | **44** | **31** | `wasmi` **29** · `wasmtime` **166** · `extism` **304** |
|
|
| **Cold-Build debug** [gemessen] | **45,5 s** | **17,2 s** (erster Lauf mit kaltem Registry-Cache: 29,1 s) | `wasmi` **24,5 s** · `wasmtime` **262,5 s** · `extism` **356,1 s** (letztere zwei mit kaltem Registry-Cache, enthalten Download) |
|
|
| **MSRV** | 1.66 [Quelle: lib.rs] | 1.88 [Quelle: lib.rs] | `wasmi` 1.86 · `wasmtime` **1.95** (Edition 2024) — aggressiv, erzwingt Rust-Upgrades |
|
|
| **Typ-Brücke zu Rust-Structs** | `#[derive(CustomType)]` oder `CustomType`+`TypeBuilder`. **Einzige Anforderung: `Clone`** (mit `sync`-Feature zusätzlich `Send+Sync`). Mutable Game-State über `Rc<RefCell<_>>`-Closures (Control-Layer-Pattern) oder `&mut`-Erstargument. | `impl UserData` mit `add_field_method_get/set`, `add_method`, `add_method_mut`, `add_meta_method`. Mehr Zeremonie als Rhai, dafür sehr ausgereift. Für `!Send`/nicht-`'static`-Typen braucht es `Lua::scope`. Serde-Brücke über Feature `serialize`. | Am teuersten. Core-WASM kennt nur i32/i64/f32/f64 + Linear Memory — **jeder Struct muss serialisiert werden**. Extism: `#[plugin_fn] fn f(Json(x): Json<T>) -> FnResult<Json<U>>` (wenig Boilerplate, JSON-Kosten pro Call). wasmtime: WIT-IDL + `wit-bindgen` + `Guest`-Impls, Aufwand ähnlich protobuf. Kein Shared Memory — Daten werden kopiert. |
|
|
| **Sandbox — Default** | **Gut, aber zwei Fallen.** Keine Datei-/Netz-/Prozess-Funktionen in irgendeinem der 15 Built-in-Packages; Dateizugriff ist ein separates Opt-in-Crate (`rhai-fs`). ABER: (1) der Default-`FileModuleResolver` **lädt `./*.rhai` von der Platte** — `import "evil"` funktioniert auf einer blanken `Engine::new()`; (2) `eval()` ist eingebaut und aktiv. | **Schlecht.** [gemessen] Auf `Lua::new()` **und** auf `StdLib::ALL_SAFE` sind `io`, `os`, `package`, `require`, `dofile`, `load` vorhanden; `io.open` hat hier eine echte Datei gelesen, `os.execute` ist erreichbar. `ALL_SAFE` = `(1<<30)-1` und schließt nur `debug` und `ffi` aus — es bedeutet *speichersicher*, **nicht** *fähigkeitsbeschränkt*. | **Am stärksten.** „no raw access to system calls or other forms of I/O; the only thing a WebAssembly instance can do is what is available through interfaces it has been explicitly linked with." Ein Modul ohne Imports kann nichts. WASI ist Opt-in und default-deny. |
|
|
| **Sandbox — abschaltbar / härtbar** | `set_module_resolver(DummyModuleResolver::new())`, `disable_symbol("eval")`, `set_max_operations`, `on_progress`, `set_max_string_size/array_size/map_size`, `set_strict_variables`, Features `no_module`/`no_function`/`no_closure`. **CPU- und Memory-Limits sind per Default 0 = unbegrenzt.** | `Lua::new_with(StdLib::STRING\|TABLE\|MATH, …)` — [gemessen] danach sind `io`, `os`, `package`, `require`, `debug` weg (`load` und `print` bleiben, Base-Lib ist immer geladen). `set_memory_limit` [gemessen: greift, „memory error: not enough memory"], `set_hook(every_nth_instruction)` [gemessen: stoppt `while true do end`]. Luau-Backend bietet zusätzlich `Lua::sandbox()`. | `Config::consume_fuel` (deterministisch, inkompatibel mit Winch) oder Epoch-Interruption („cannot be avoided by malicious wasm code"), `StoreLimits` für Speicher. Caveat wörtlich: „Epochs (and fuel) do not assist in handling WebAssembly code blocked in a call to the host." |
|
|
| **Sandbox — bekannte Löcher** | GHSA-67fv-9r7g-432h (High, 2024, ≤1.18.0, gefixt). **Issue #894 „Rhai is unsound (use after free)" seit 2024-07-03 offen** — Host-API-Footgun, kein Script-Escape. | mlua-README selbst: „mlua does not provide absolute safety even without using `unsafe`. This library contains a huge amount of unsafe code." | **46 publizierte Advisories** bei wasmtime, davon **4 critical / 4 high**; zwei Criticals von 2026-04-09 sind echte Sandbox-Escapes (aarch64-Cranelift-Miscompile, Winch-Memory-Access). Der JIT ist in der TCB. Monatlicher Patch-Treadmill. |
|
|
| **Fehler mit Zeilennummer** | **Ja, Zeile + Spalte**, auch in verschachtelten Funktionen mit Call-Chain: `Array index 99 out of bounds: only 3 elements in array (line 3, position 11)`. API: `Position::line()` / `Position::position()`. ⚠️ 16-Bit-Auflösung, max. 65 535 Zeilen. | **Ja, Chunk-Name + Zeile + Traceback.** [gemessen]:<br>`[string "core/mods/evil.lua"]:2: attempt to index a nil value (local 't')`<br>`stack traceback:`<br>` [C]: in metamethod 'index'`<br>` [string "core/mods/evil.lua"]:2: in main chunk`<br>Syntaxfehler ebenso mit Zeile. | **Deutlich schlechter.** `WasmBacktrace` liefert Funktionsname + `module_offset`/`func_offset`. Quell-Zeile nur, wenn der Modder mit DWARF-Debuginfo gebaut hat *und* du `FrameInfo::symbols()` auswertest. Realistisch: Funktionsname + Byte-Offset. |
|
|
| **Hot-Reload** | **Trivial.** Engine ist zustandslos gegenüber dem `AST`; `AST` in `Rc<RefCell<_>>` neu kompilieren und tauschen. `Scope`-State überlebt den Reload. Chirurgisch möglich über `retain_functions` + `+=`. | **Ja.** [gemessen] Chunk im selben `Lua`-State neu ausführen → `tick()` liefert `v1 -> v2`. Alternativ neuen `Lua`-State bauen. | Möglich (neu kompilieren + frischer `Store`+`Instance`), aber Kompilierung ist teuer. `Module::deserialize` ist **`unsafe`** — „Arbitrary input could […] replace valid compiled code with any other valid compiled code, meaning that this can trivially be used to execute arbitrary code otherwise." Also niemals von Mods gelieferte `.cwasm` laden. |
|
|
| **Vertrautheit für Hobby-Modder** | Gering. Rhai-ähnliche Syntax (Rust/JS-nah), aber ein Modder muss sie neu lernen. Kein Spiel bekannt, das Rhai für Modding einsetzt (siehe „Nicht verifiziert"). | **Klar überlegen.** Factorio (Lua 5.2), Garry's Mod (5.1), Teardown (5.1), Luanti, Dota 2 VScript, WoW, Noita, Don't Starve, DFHack, Widelands, Balatro (via LÖVE). Alle mit offizieller oder de-facto Lua-Modding-API. | **Am schlechtesten.** Es gibt kein „Textdatei editieren und neu laden": Extism-Doku sagt, jedes Plugin „must be compiled to WebAssembly […] before it can be run in an Extism Host". Der Modder braucht Rust/Go/Zig/AssemblyScript-Toolchain. Die JS-Ausweichroute (Extism JS PDK = QuickJS-in-WASM, Javy-Fork) braucht zusätzlich Binaryen und kann „nur pure JS", ohne Node-/Browser-APIs. |
|
|
| **Reifegrad / Wartung** | Sehr aktiv, aber **Ein-Mann-Projekt** (Stephen Chung). ~4 Minor-Releases/Jahr seit 2 Jahren, letzter Commit 2026-08-11. 5 596 Stars, 316 Reverse-Deps. Hauptnutzer sind Config-/Policy-Engines (handlebars, casbin, apollo-router), nicht Spiele. Ein Bytecode-VM-Rewrite scheint im Gang → Verhaltens-Churn erwartbar. | Aktiv, breit genutzt. 2 826 Stars, letzter Push 2026-07-28, 438 direkte Dependents. Referenz auf Windows: **WezTerm** baut mit exakt `features = ["vendored","lua54",…]`. Produktions-Track-Record liegt in Tooling (WezTerm, Yazi, Vector/VRL, LibAFL), nicht in Spielen. | wasmtime: Bytecode Alliance, **fester Monatsrelease am 20.**, LTS nur alle 12 Versionen (36, 48) — Nicht-LTS-Releases fallen nach **2 Monaten** aus dem Support. extism (Dylibso): unregelmäßig, hängt an wasmtime **43** (bereits außerhalb des Supportfensters). wasmi: von der Stellar Development Foundation gesponsert, 2.0 seit Monaten in Beta. `cargo component` wird offiziell deprecated; Component Model ist **nicht 1.0**. |
|
|
| **Performance** | AST-Walking-Interpreter, „No bytecodes/JIT". Offiziell: „In general, Rhai is roughly 2x slower than Python 3." Für rundenbasierte Logik irrelevant. | Lua 5.4 ist eine der schnellsten Skriptsprachen; hier ebenfalls irrelevant. | JIT (Cranelift) am schnellsten, aber Pulley-Interpreter „~10x order-of-magnitude slowdown". Irrelevant für ein Terminalspiel. |
|
|
|
|
---
|
|
|
|
## Empfehlung
|
|
|
|
**Rhai** — mit klar benannten Gegenargumenten, weil die Entscheidung nicht eindeutig ist.
|
|
|
|
### Warum Rhai
|
|
|
|
1. **Es passt zur Fehlerstrategie aus der Map.** „`Result` statt `panic!` — kaputte Mod-TOMLs
|
|
sind der Normalfall." Rhai liefert Parse- *und* Laufzeitfehler mit Zeile und Spalte, inklusive
|
|
Call-Chain, als `EvalAltResult` — das fügt sich ohne Übersetzungsschicht in die bestehende
|
|
Fehlerbehandlung ein. WASM fällt an genau dieser Stelle durch: ein Modder bekäme Funktionsname
|
|
und Byte-Offset statt einer Zeilennummer.
|
|
|
|
2. **Die Typ-Brücke ist die billigste.** `#[derive(CustomType)]` und „the only requirement of a
|
|
type to work with Rhai is `Clone`" gegen mlua's `impl UserData` mit `add_field_method_get`/
|
|
`add_method_mut` pro Feld. Da Stufe (c) laut Map auf der Typ-Registry aufsetzt und das
|
|
Effekt-Vokabular ohnehin die Mod-API *ist*, ist die Zahl der zu brückenden Typen klein — aber
|
|
jeder gesparte Handgriff zählt bei einem Solo-Projekt.
|
|
|
|
3. **Der Default ist sicherer.** Das ist der schärfste Einzelunterschied: [gemessen] hat ein
|
|
Lua-Script auf `Lua::new()` *und* auf `StdLib::ALL_SAFE` eine echte Datei über `io.open`
|
|
gelesen; `os.execute` war erreichbar. Bei Rhai gibt es diese Funktionen in der Standard-Engine
|
|
überhaupt nicht — Dateizugriff ist ein separates Crate. Beide brauchen Härtung, aber ein
|
|
vergessener Handgriff kostet bei Rhai weniger.
|
|
|
|
4. **Kein C im Build, kleinste Toolchain-Angriffsfläche.** Rhai zieht kein `cc`, `libc` oder
|
|
`bindgen`. Praktisch ist das unter Windows-MSVC ein schwaches Argument — [gemessen] baute
|
|
`mlua` mit `vendored` hier problemlos und sogar schneller (17,2 s gegen 45,5 s), weil der
|
|
MSVC-Compiler für den Rust-Toolchain ohnehin installiert sein muss. Das Argument zählt erst
|
|
bei `x86_64-pc-windows-gnu` oder bei CI-Images ohne Build-Tools.
|
|
|
|
5. **Lernziel Rust.** Die Map nennt „Rust lernen **und** Spiel bauen" als Motivation. Rhais API
|
|
ist durchgehend Rust-idiomatisch (Traits, Derive-Makros, `Result`); mlua zwingt zusätzlich zum
|
|
Verständnis der Lua-C-API-Semantik (Stack, `longjmp`-Verhalten, `Lua::scope`-Lifetimes).
|
|
|
|
6. **Hot-Reload ist ein Zweizeiler** und `Scope`-State überlebt den Tausch — genau das Verhalten,
|
|
das man beim Iterieren an einem Mod will.
|
|
|
|
### Was gegen Rhai spricht (und für Lua)
|
|
|
|
- **Vertrautheit ist Lua's stärkstes Argument, und es ist ein starkes.** Factorio, Garry's Mod,
|
|
WoW, Teardown, Noita, Don't Starve, Luanti, Dota 2 — ein Hobby-Modder, der schon einmal etwas
|
|
gemoddet hat, kann mit hoher Wahrscheinlichkeit Lua. Für Rhai muss er neu anfangen. Wenn das
|
|
Ziel „möglichst viele fremde Mods" ist statt „gut moddbar für mich und ein paar Leute",
|
|
kippt die Empfehlung zu Lua.
|
|
- **Bus-Faktor 1.** Rhai wird im Wesentlichen von einer Person entwickelt.
|
|
- **Offene Unsoundness (#894, seit 2024-07-03)** und die Pflicht-Dependency **`smartstring` ist
|
|
seit 2026-08-10 als unmaintained gemeldet** (RUSTSEC-2026-0249, Repo am 2026-05-03 archiviert).
|
|
`cargo deny` schlägt damit heute an.
|
|
- **Ein Bytecode-VM-Rewrite scheint im Gang** (offene Issues „VM: Fuzz errors detected",
|
|
„VM: Modify switch statement processing") → Verhaltensänderungen in kommenden Releases.
|
|
- Kein einziges verifizierbares ausgeliefertes Spiel nutzt Rhai fürs Modding.
|
|
|
|
### Warum WASM für 1.0 ausscheidet
|
|
|
|
Nicht wegen der Technik — die Sandbox ist objektiv die beste der drei und die einzige, die
|
|
gegen wirklich bösartigen Code hält. Sondern wegen drei Dingen, die direkt gegen die Ziele
|
|
dieses Projekts laufen:
|
|
|
|
1. **Der Compile-Schritt tötet die Zielgruppe.** Ein Modder, der heute 30 Zeilen Lua schreiben
|
|
würde, müsste eine Rust-/TinyGo-/AssemblyScript-Toolchain installieren und ein Binary
|
|
ausliefern. Selbst der „einfache" JS-Weg (Extism JS PDK) braucht Binaryen und einen Build.
|
|
2. **Fehlermeldungen ohne Zeilennummer** widersprechen der Fehlerstrategie der Map.
|
|
3. **Der Build-Overhead ist eine Größenordnung höher** — [gemessen] 166 bzw. 304 Dependencies und
|
|
262 s bzw. 356 s Cold-Build gegen 44/45,5 s bei Rhai. Dazu wasmtimes MSRV 1.95 und ein
|
|
Support-Fenster von 2 Monaten für Nicht-LTS-Releases.
|
|
|
|
Falls WASM später doch relevant wird (z. B. um Mods aus dem Netz zu laden, wo echte Isolation
|
|
zählt): **`wasmi`** ist der interessantere Kandidat als wasmtime — reines Rust, `no_std`, 29
|
|
Dependencies, MSRV 1.86, mit Fuel und `StoreLimits`. Für ein Terminalspiel braucht es keinen JIT.
|
|
|
|
### Härtungs-Checkliste, falls Rhai gewählt wird
|
|
|
|
Alle vier sind nötig, weil die Defaults sie nicht mitbringen:
|
|
|
|
1. `engine.set_module_resolver(DummyModuleResolver::new())` — sonst liest ein Script `.rhai`-Dateien
|
|
vom Dateisystem (empirisch nachgewiesen).
|
|
2. `engine.disable_symbol("eval")`.
|
|
3. `set_max_operations(...)` und/oder `on_progress(...)` — CPU-Limit ist per Default **aus**.
|
|
4. `set_max_string_size` / `set_max_array_size` / `set_max_map_size` — Memory-Limits sind per
|
|
Default **aus**.
|
|
5. Niemals das Feature `unchecked` aktivieren.
|
|
6. Für ein Single-Thread-Terminalspiel das Feature `sync` **weglassen** und `Rc<RefCell<_>>`
|
|
nutzen — `sync` erzwingt Locking bei jedem Funktionsaufruf.
|
|
|
|
Analog für mlua, falls es doch Lua wird: `Lua::new_with(StdLib::STRING|TABLE|MATH, …)`
|
|
statt `ALL_SAFE`, plus `set_memory_limit` und `set_hook(every_nth_instruction)`. Factorio
|
|
veröffentlicht seine eigene Sandbox-Liste (`loadfile`, `dofile`, `coroutine`, `io`, `os`
|
|
entfernt, `debug` auf `getinfo`/`traceback` reduziert, `require` auf das Mod-Verzeichnis
|
|
gepatcht) — das ist die am besten erprobte Vorlage, die es gibt.
|
|
|
|
### Anmerkung zur Umkehrbarkeit
|
|
|
|
Laut Map ist das Effekt-Vokabular die Mod-API und Scripting setzt auf der Typ-Registry auf.
|
|
Wenn Scripts ausschließlich über dieses Vokabular mit dem Spiel reden — also Effekte
|
|
zurückgeben statt `Game` direkt zu manipulieren — ist die Engine-Wahl **deutlich umkehrbarer,
|
|
als sie aussieht**. Die Brücke wäre dann eine dünne Adapterschicht, kein Fundament. Das spricht
|
|
dafür, die Entscheidung nicht zu überdenken und Stufe (c) bewusst schmal zu halten.
|
|
|
|
---
|
|
|
|
## Nicht verifiziert
|
|
|
|
Explizit offen geblieben — nicht geraten:
|
|
|
|
- **Kein ausgeliefertes kommerzielles Spiel mit Rhai-Modding gefunden.** `github.com/rhaiscript/awesome-rhai`
|
|
gibt 404, weder rhai.rs noch das README führen eine „Who uses Rhai"-Liste. Nächste Treffer sind
|
|
HEMTT (Arma-Modding-Toolchain, nutzt Rhai für Hooks) und Bevy-Integrationen (`bevy_mod_scripting`,
|
|
`bevy_scriptum`).
|
|
- **Kein ausgeliefertes Rust-Spiel mit mlua gefunden.** Der Track-Record liegt in Tooling
|
|
(WezTerm, Yazi, Vector). WezTerm ist aber ein belastbarer Windows-`vendored`-Präzedenzfall.
|
|
- **Kein ausgeliefertes kommerzielles Spiel mit WASM-Modding gefunden.** Veloren hat ein
|
|
WASM-Plugin-System, warnt aber selbst: „we currently make no stability guarantees about APIs,
|
|
tooling, etc." Ob Veloren inzwischen auf WASI 0.2 / wasmtime umgestellt hat, ließ sich aus
|
|
Veloren-Primärquellen **nicht** bestätigen.
|
|
- **Build-Zeiten sind Einzelmessungen auf einer Maschine.** Der Registry-Cache-Zustand war nicht
|
|
überall gleich (`wasmtime`/`extism` liefen mit kaltem Cache, enthalten also Downloadzeit). Die
|
|
Dependency-Zahlen sind dagegen exakt und methodisch identisch erhoben.
|
|
- **Rhai-Zahlen im Detail:** Die parallele Erhebung zählte über `cargo tree -e normal` 24
|
|
Dependencies und maß 77 s Cold-Debug-Build; die Tabelle oben nennt 44 (Cargo.lock, inkl.
|
|
plattform-gegateter Einträge) und 45,5 s (warmer Registry-Cache). Beide Methoden sind korrekt,
|
|
sie messen Unterschiedliches. Innerhalb der Tabelle ist durchgängig dieselbe Methode verwendet.
|
|
- **Rhai-Hot-Reload-Randfall:** ob Closures, die aus einem alten `AST` stammen und Rust-seitig
|
|
noch gehalten werden, nach dem Verwerfen dieses `AST` korrekt funktionieren, sagt das Buch nicht.
|
|
- **Lua-Bytecode als Escape-Vektor:** die einschlägige Warnung im Lua-Referenzhandbuch (maliziös
|
|
konstruierte Binary-Chunks können den Interpreter zum Absturz bringen) ließ sich über die
|
|
abrufbaren Manual-Abschnitte nicht wörtlich belegen. Praktische Konsequenz bleibt unabhängig
|
|
davon: Mod-Scripts nur im Textmodus laden, nie vorkompilierte Chunks.
|
|
|
|
---
|
|
|
|
## Quellen
|
|
|
|
**crates.io / Registry**
|
|
- https://crates.io/api/v1/crates/rhai
|
|
- https://crates.io/api/v1/crates/rhai/1.25.1/dependencies
|
|
- https://crates.io/api/v1/crates/rhai/reverse_dependencies
|
|
- https://crates.io/api/v1/crates/mlua
|
|
- https://crates.io/api/v1/crates/wasmtime
|
|
- https://crates.io/api/v1/crates/wasmi
|
|
- https://crates.io/api/v1/crates/extism
|
|
- https://lib.rs/crates/rhai
|
|
- https://lib.rs/crates/mlua
|
|
|
|
**Rhai**
|
|
- https://rhai.rs/book/rust/custom-types.html — „The only requirement of a type to work with Rhai is `Clone`."
|
|
- https://rhai.rs/book/rust/build-type.html — `CustomType` / `TypeBuilder`
|
|
- https://rhai.rs/book/plugins/module.html — `#[export_module]`
|
|
- https://rhai.rs/book/patterns/control.html — Control-Layer-Pattern (`Rc<RefCell<_>>`)
|
|
- https://rhai.rs/book/safety/sandbox.html — „Rhai is sand-boxed so a script can never read from outside its own environment"
|
|
- https://rhai.rs/book/safety/index.html — Don't-Panic-Garantie, Warnung zu `unchecked`
|
|
- https://rhai.rs/book/safety/max-operations.html · https://rhai.rs/book/safety/progress.html
|
|
- https://rhai.rs/book/rust/modules/resolvers/index.html · https://docs.rs/rhai/latest/rhai/module_resolvers/struct.FileModuleResolver.html
|
|
- https://rhai.rs/book/language/eval.html — „eval is evil"
|
|
- https://rhai.rs/book/engine/strict-var.html · https://rhai.rs/book/engine/scope.html · https://rhai.rs/book/engine/ast.html
|
|
- https://rhai.rs/book/patterns/hot-reload.html
|
|
- https://rhai.rs/book/patterns/multi-threading.html — Kosten des `sync`-Features
|
|
- https://rhai.rs/book/about/benchmarks.html — „roughly 2x slower than Python 3"
|
|
- https://rhai.rs/book/about/non-design.html — „No bytecodes/JIT"
|
|
- https://rhai.rs/book/rust/packages/builtin.html · https://rhai.rs/book/start/features.html
|
|
- https://docs.rs/rhai/latest/rhai/struct.Position.html · https://docs.rs/rhai/latest/rhai/enum.EvalAltResult.html · https://docs.rs/rhai/latest/rhai/struct.Engine.html
|
|
- https://github.com/rhaiscript/rhai — Repo; Issue #894 „Rhai is unsound (use after free)", offen seit 2024-07-03
|
|
- https://github.com/rhaiscript/rhai-fs — separates Opt-in-Crate für Dateizugriff
|
|
- https://rustsec.org/advisories/RUSTSEC-2026-0249.html — `smartstring` unmaintained, 2026-08-10
|
|
- https://hemtt.dev/rhai/index.html — Arma-Modding-Toolchain mit Rhai
|
|
- https://docs.rs/crate/bevy_mod_scripting/latest · https://github.com/jarkonik/bevy_scriptum
|
|
|
|
**mlua / Lua**
|
|
- https://github.com/mlua-rs/mlua — README: `vendored`, Plattformen, „mlua does not provide absolute safety…"
|
|
- https://raw.githubusercontent.com/mlua-rs/mlua/main/src/stdlib.rs — `ALL_SAFE = StdLib((1 << 30) - 1)`
|
|
- https://docs.rs/mlua/latest/mlua/struct.Lua.html — `new_with`, `sandbox`, `set_memory_limit`, `set_hook`, `scope`, `load`
|
|
- https://docs.rs/mlua/latest/mlua/struct.StdLib.html
|
|
- https://docs.rs/mlua/latest/mlua/enum.Error.html
|
|
- https://docs.rs/mlua/latest/mlua/trait.UserData.html
|
|
- https://raw.githubusercontent.com/wezterm/wezterm/main/config/Cargo.toml — `features = ["vendored","lua54","async","send","serialize"]`
|
|
- https://lua-api.factorio.com/latest/auxiliary/libraries.html — Factorios Sandbox-Liste (Lua 5.2)
|
|
- https://wiki.facepunch.com/gmod/ (Lua 5.1) · https://www.teardowngame.com/modding/api.html (Lua 5.1)
|
|
- https://api.luanti.org/ · https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting
|
|
- https://docs.dfhack.org/en/stable/docs/Lua%20API.html · https://www.widelands.org/documentation/lua_index/
|
|
- https://noita.wiki.gg/wiki/Modding:_Lua_API · https://luau.org/
|
|
|
|
**WASM**
|
|
- https://docs.wasmtime.dev/security.html — „no raw access to system calls or other forms of I/O…"
|
|
- https://docs.wasmtime.dev/stability-release.html — Monatsrelease am 20., LTS alle 12 Versionen, 2 Monate Support sonst
|
|
- https://docs.wasmtime.dev/stability-tiers.html · https://docs.wasmtime.dev/stability-platform-support.html
|
|
- https://docs.wasmtime.dev/examples-pulley.html — „~10x order-of-magnitude slowdown"
|
|
- https://docs.wasmtime.dev/examples-debugging-native-debugger.html
|
|
- https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html — Fuel, Epoch, deren Grenzen
|
|
- https://docs.rs/wasmtime/latest/wasmtime/struct.Module.html — `deserialize` ist `unsafe`
|
|
- https://docs.rs/wasmtime/latest/wasmtime/struct.WasmBacktrace.html · https://docs.rs/wasmtime/latest/wasmtime/struct.FrameInfo.html
|
|
- https://docs.rs/wasmtime-wasi/latest/wasmtime_wasi/struct.WasiCtxBuilder.html — default-deny
|
|
- https://github.com/bytecodealliance/wasmtime/security/advisories — 46 Advisories, 4 critical / 4 high
|
|
- https://extism.org/docs/concepts/pdk — „must be compiled to WebAssembly … before it can be run"
|
|
- https://extism.org/docs/concepts/plug-in-system · https://docs.rs/extism/latest/extism/
|
|
- https://github.com/extism/js-pdk — QuickJS-in-WASM, Javy-Fork, braucht Binaryen
|
|
- https://github.com/bytecodealliance/javy
|
|
- https://component-model.bytecodealliance.org/language-support/building-a-simple-component/rust.html — `cargo component` wird deprecated
|
|
- https://bytecodealliance.org/articles/the-road-to-component-model-1-0 — Component Model ist nicht 1.0
|
|
- https://bytecodealliance.org/articles/WASI-0.3
|
|
- https://github.com/wasmi-labs/wasmi · https://docs.rs/wasmi/latest/wasmi/
|
|
- https://book.veloren.net/contributors/modders/writing-a-plugin.html — „we currently make no stability guarantees"
|
|
- https://tartanllama.xyz/posts/wasm-plugins/ — durchgearbeitetes WASM-Plugin-Beispiel (Demo, kein Produkt)
|