feat(scripting): Lua (MoonSharp) content-scripting layer — migrate rat, sword, bow #193
No reviewers
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo!193
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/scripting-lua"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds the Lua (MoonSharp) content-scripting layer (#183, Phase 1) and uses it to migrate the rat, sword and bow out of C# into Lua — proving the whole mechanism end to end. The goal set for this work was developer experience: content authored in
content/scripts/*.lua, hot-reloadable, with editor autocomplete and mistakes caught as early as possible.What's in it:
IsoMmo.Scripting— engine-agnostic host (references onlyShared+ MoonSharp): compiles/sandboxes scripts, derives each script's FQN from its path (mobiles/npc/rat.lua→Mobiles.NPC.Rat), exposes curated verbs (say/spawn/getFlag/setFlag), dispatches theonUsetrigger under an instruction budget with error isolation + quarantine, and hot-reloads compile-fresh-then-swap. CleanApi/Content/Hostingnamespaces.WorldScriptContext : IScriptContextrealises the verbs overWorld(id + DTO boundary, server-authoritative); scripted content bridges intoItemCatalog(now an instance) +CreatureRegistry. Scripts are loaded at startup and a broken set is FATAL; a runtime handler failure is isolated + logged./reloadscriptsGM command.content/scripts/mobiles/npc/rat.lua,items/weapons/sword.lua,items/weapons/bow.lua; the C#Rat/Sword/Bowclasses are removed. Unit tests use C# test-doubles (the one documented test-only exception to "content in Lua").[Script*]attributes on the C# contract;content/scripts/api.d.luais generated from them (just gen-lua-defs) and the host validates every table against the same reflected model, so editor types and runtime acceptance share one source. A CI drift-check + alua-lintgate (luacheck + lua-language-server) run over the scripts. Dialogue is typed:say(npc, Messages.Creatures.RatSqueak).UseMobileintent +MobileSaidbroadcast; client renders a speech bubble over any mobile.docs/scripting.md, a new## Content scripting (Lua)HARD GATE inCLAUDE.md(+ scopedsrc/IsoMmo.Scripting/CLAUDE.mdandREADME.md),.vscode/shared dev setup.The
critical-design-review(with the Invariants Check + the dialogue-vs-catalog resolution) is recorded on #183.Screenshots / recording
Captured by piloting the client via the debug harness from a fresh DB (
docs/debug-harness.md).A scripted NPC talks — double-click the rat → its Lua
onUseruns → cataloguedMobileSaidbubble:(The rat normally wanders; for a stable frame the shot was taken with the wander cadence turned up via a runtime env override — the
onUse→ talk behaviour is unaffected.)The migrated Lua weapons —
/give sword+/give bow→ real UO art in the backpack (13 st = 6 + 7):How it was tested
IsoMmo.Scripting, fakeIScriptContext) — instruction-budget aborts awhile true; syntax error does NOT swap (old handlers keep running); handler exception isolated + quarantine after N; trigger routing; FQN-from-path; schema-driven field validation (unknown field rejected); typedMessages.*; the generated-api.d.luadrift-check.World) —onUsemakes the rat talk to AoI observers;setFlagsurvives a serialize/restore round-trip; off-map spawn from a script rejected (authority holds); C#/Lua kind collision is fatal.UseMobileend to end; the server refuses to start on a deliberately broken script.luacheck+lua-language-server --checkrun locally against the real tools: the committed scripts pass; a deliberate type error fails (exit 1).just lint(CSharpier + build, zero warnings), whole-solution build (client + tools),dotnet testall green (536 tests),just check-docsclean.Checklist
just lintpasses (CSharpier + analyzers, zero warnings)just testis green- docs/scripting.md: model, namespacing gate, authoring, verbs/flags/dialogue, the generated-API contract, validation stages, operating. - Root CLAUDE.md: new 'Content is authored in Lua' HARD GATE + Design-checklist bullet + Architecture entry + Content-scripting section. - src/IsoMmo.Scripting/{README,CLAUDE}.md: VSCode setup, generated types, layer gates. - .vscode/{extensions,settings}.json: shared dotnet+Lua dev setup across machines. - gm-commands.md: /reloadscripts row + scripted spawn kinds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>