
Your host runs Lua
Write an adapter.
One table maps the API onto your host, as an addon, a mod, a plugin or a shim.
Create an adapter
SDK
One API for your scripts, and the pieces that run it on every host.
The pieces
One API for scripts, on any Lua from 5.1 to 5.4 and LuaJIT.
One per host: it maps the API onto what the host already has.
For C# engines and servers. Runs Lua and TypeScript side by side.
Create, test, publish and install scripts from the command line.
Autocomplete for the whole API in your editor.
The runtime API, the manifest and the HTTP API, written down.
Integrate

Your host runs Lua
One table maps the API onto your host, as an addon, a mod, a plugin or a shim.
Create an adapter
Your engine has no Lua
A C# engine references the kit and its users write Lua or TypeScript.
Embed the .NET kitLanguages
On each host’s own Lua, 5.1 to 5.4 or LuaJIT.
On the .NET kit, compiled when you pack or verify.
The platform
A key per buyer, one activation per server, checked again on a schedule.
Licensing APIOn the seller’s own store: a payment there issues a licence here.
Open a shopStatuses come from reports written in the real runtime, never from a form.
How a status is earnedscriptgo add checks the hash and the signature before it writes a file.
scriptgo addMonetize
What is sold is the seller’s own code, as a SCRIPT//GO script that runs on the environments it declares.

a script studio
Each buyer gets a licence for their own servers. The release can be delivered encrypted.
Sold: a licence to run the studio’s script.Read more

a server operator
A monthly VIP pass, for example, unlocks a feature of the operator’s own script.
Sold: a feature of the operator’s own code. Never the game, its content or access to it.Read more
Protection
Signed releases, a licence per server, and encrypted delivery where the host can hold a key.
One module, every runtime
A package’s README example, and what each environment printed when it ran.
scriptgo//event-bus · v1.0.2 · the README example, run on each platform on the right
local bus = exports.sg_eventbus
AddEventHandler("sgbus:shop.sale", function(sale, meta)
print(("sale #%d from %s: %s for %d"):format(meta.seq, meta.publisher, sale.item, sale.price))
end)
-- Exports are called from a thread or a handler, never at file scope (OPEN//77 refuses that
-- with resource_preparing, and so does every SCRIPT//GO host).
CreateThread(function()
-- Payloads on "shop.sale" must have this shape. The last sale is kept (retain).
print(bus:defineTopic("shop.sale", {
schema = { type = "table", fields = {
item = { type = "string", maxLength = 32 },
price = { type = "number", min = 0 },
} },
retain = true,
}))
print(bus:publish("shop.sale", { item = "water", price = 3 })) -- true 1
print(bus:publish("shop.sale", { item = "water", price = "free" })) -- false invalid_payload: ...
local last = bus:last("shop.sale")
print("last sale: " .. last.item)
end)What each platform printed when it ran
[info] host started sg_eventbus 1.0.2
[debug] sg_eventbus:server topic shop.sale defined by sg_eventbus_readme
[info] sg_eventbus_readme:server true
[info] sg_eventbus_readme:server true 1
[info] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
[info] sg_eventbus_readme:server last sale: water
[info] host started sg_eventbus_readme 1.0.2
[info] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
[info] host stopped sg_eventbus_readme
[info] host stopped sg_eventbus[info] host started sg_eventbus 1.0.2
[debug] sg_eventbus:server topic shop.sale defined by sg_eventbus_readme
[info] sg_eventbus_readme:server true
[info] sg_eventbus_readme:server true 1
[info] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
[info] sg_eventbus_readme:server last sale: water
[info] host started sg_eventbus_readme 1.0.2
[info] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
[info] host stopped sg_eventbus_readme
[info] host stopped sg_eventbus
ok sg_eventbus > a defined topic delivers validated payloads to server and clients
ok sg_eventbus > payloads that break the schema are refused with a path
ok sg_eventbus > clients publish through the server under a per-player rate limit
ok sg_eventbus > a topic belongs to the resource that defined it
ok sg_eventbus > stopping the owner removes its topics
sg_eventbus: 5 passed, 0 failed (LuaJIT 2.1.1700008891)[info] host started sg_eventbus 1.0.2
[debug] sg_eventbus:server topic shop.sale defined by sg_eventbus_readme
[info] sg_eventbus_readme:server true
[info] sg_eventbus_readme:server true 1
[info] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
[info] sg_eventbus_readme:server last sale: water
[info] host started sg_eventbus_readme 1.0.2
[info] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
--- engine
2026-11-09 07:28:21: ACTION[Main]: [scriptgo] host started sg_eventbus 1.0.2
2026-11-09 07:28:21: ACTION[Main]: [scriptgo] sg_eventbus_readme:server true
2026-11-09 07:28:21: ACTION[Main]: [scriptgo] sg_eventbus_readme:server true 1
2026-11-09 07:28:21: ACTION[Main]: [scriptgo] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
2026-11-09 07:28:21: ACTION[Main]: [scriptgo] sg_eventbus_readme:server last sale: water
2026-11-09 07:28:21: ACTION[Main]: [scriptgo] host started sg_eventbus_readme 1.0.2
2026-11-09 07:28:21: ERROR[Main]: Mapgen: Mapgen alias 'mapgen_stone' is invalid!
2026-11-09 07:28:21: ERROR[Main]: Mapgen: Mapgen alias 'mapgen_water_source' is invalid!
2026-11-09 07:28:21: ACTION[Server]: [scriptgo] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
2026-11-09 07:28:24: ACTION[Server]: [scriptgo] verify sg_eventbus: verified (6 checks, 0 failed)
2026-11-09 07:28:24: ACTION[Main]: [scriptgo] host stopped sg_eventbus_readme
2026-11-09 07:28:24: ACTION[Main]: [scriptgo] host stopped sg_eventbus[info] host started sg_eventbus 1.0.2
[debug] sg_eventbus:server topic shop.sale defined by sg_eventbus_readme
[info] sg_eventbus_readme:server true
[info] sg_eventbus_readme:server true 1
[info] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
[info] sg_eventbus_readme:server last sale: water
[info] host started sg_eventbus_readme 1.0.2
[info] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
[info] host stopped sg_eventbus_readme
[info] host stopped sg_eventbus
ok sg_eventbus > a defined topic delivers validated payloads to server and clients
ok sg_eventbus > payloads that break the schema are refused with a path
ok sg_eventbus > clients publish through the server under a per-player rate limit
ok sg_eventbus > a topic belongs to the resource that defined it
ok sg_eventbus > stopping the owner removes its topics
sg_eventbus: 5 passed, 0 failed (LuaJIT 2.1.1774638290)2026-11-09 08:28:19.344 +01:00 [INF] [resource:sg_eventbus] discovered
2026-11-09 08:28:19.344 +01:00 [INF] [resource:sg_eventbus_readme] discovered
2026-11-09 08:28:19.383 +01:00 [INF] [resource:sg_eventbus] started generation=1
2026-11-09 08:28:19.390 +01:00 [INF] [resource:sg_eventbus_readme] started generation=1
2026-11-09 08:28:19.412 +01:00 [INF] Lua 5.4 resource host ready: count=2, root=<run>\resources.
2026-11-09 08:28:19.496 +01:00 [INF] [resource:sg_eventbus_readme] true
2026-11-09 08:28:19.497 +01:00 [INF] [resource:sg_eventbus_readme] true 1
2026-11-09 08:28:19.497 +01:00 [INF] [resource:sg_eventbus_readme] false invalid_payload: payload.price: expected number
2026-11-09 08:28:19.497 +01:00 [INF] [resource:sg_eventbus_readme] last sale: water
2026-11-09 08:28:19.504 +01:00 [INF] [resource:sg_eventbus_readme] sale #1 from sg_eventbus_readme: water for 3[info] host started sg_eventbus 1.0.2
[debug] sg_eventbus:server topic shop.sale defined by sg_eventbus_readme
[info] sg_eventbus_readme:server true
[info] sg_eventbus_readme:server true 1
[info] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
[info] sg_eventbus_readme:server last sale: water
[info] host started sg_eventbus_readme 1.0.2
[info] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
[info] host stopped sg_eventbus_readme
[info] host stopped sg_eventbus
ok sg_eventbus > a defined topic delivers validated payloads to server and clients
ok sg_eventbus > payloads that break the schema are refused with a path
ok sg_eventbus > clients publish through the server under a per-player rate limit
ok sg_eventbus > a topic belongs to the resource that defined it
ok sg_eventbus > stopping the owner removes its topics
sg_eventbus: 5 passed, 0 failed (Lua 5.1)[warn] host sg_eventbus: environment_undeclared (cctweaked)
[info] host started sg_eventbus 1.0.2
[warn] host sg_eventbus_readme: environment_undeclared (cctweaked)
[debug] sg_eventbus:server topic shop.sale defined by sg_eventbus_readme
[info] sg_eventbus_readme:server true
[info] sg_eventbus_readme:server true 1
[info] sg_eventbus_readme:server false invalid_payload: payload.price: expected number
[info] sg_eventbus_readme:server last sale: water
[info] host started sg_eventbus_readme 1.0.2
[info] sg_eventbus_readme:server sale #1 from sg_eventbus_readme: water for 3
[info] host stopped sg_eventbus_readme
[info] host stopped sg_eventbus
ok sg_eventbus > a defined topic delivers validated payloads to server and clients
ok sg_eventbus > payloads that break the schema are refused with a path
ok sg_eventbus > clients publish through the server under a per-player rate limit
ok sg_eventbus > a topic belongs to the resource that defined it
ok sg_eventbus > stopping the owner removes its topics
--- server
- computercraft 1.121.0
[15:17:21] [main/ERROR]: No key layers in MapLike[{}]
[15:17:22] [Server thread/INFO]: Loading config from <minecraft-runtime>\worlds\run-Vx0IoO\sgverify\serverconfig\computercraft-server.toml
[15:17:22] [FileWatcher-1-thread-1/INFO]: Loading config from <minecraft-runtime>\worlds\run-Vx0IoO\sgverify\serverconfig\computercraft-server.toml
[15:17:23] [Server thread/INFO]: Done (1.242s)! For help, type "help"