TypeScript
TypeScript and JavaScript mods: the build, the two runtimes and the widest library.
A TypeScript or JavaScript mod imports modlock and registers its handlers
when it loads:
import { command } from 'modlock'
command('hello', (player) => {
player.chat('Hello from TypeScript!')
})The guides show every call in TypeScript and JavaScript;
choose the language with the switch in the sidebar. Camera
curves and ProbeRun for testing are in
TypeScript only.
The build
The build starts from main.ts, or main.js, and type-checks a JavaScript mod
from its JSDoc comments. Each build writes the library's types to
node_modules/modlock for your editor and the type checker. It bundles your mod
with the copy of the library built into modlock, so you install nothing else.
src/wasm/wasm.proto
documents every call, its arguments and its result.
Two runtimes
Every build bundles your mod for QuickJS, an interpreter that runs any
JavaScript, so the build takes a moment. When your mod's frames take too long,
set "runtime": "RUNTIME_WASM" in its mod.json. modlock publish then
compiles it ahead of time to WebAssembly with scriptc,
which modlock downloads the first time. The compiled mod runs about 2.5 times
faster, but the compile takes about a minute and a few gigabytes of memory. To
check that build before you publish, run modlock build --release, which
compiles the same way.
In two cases the build falls back to the QuickJS bundle, and modlock publish
refuses to upload it unless you pass --allow-fallback:
- scriptc cannot compile part of the mod. The build lists each such place and the reason.
- The two builds behave differently. To find out, the build plays both in the sandbox through a start, a player joining, a world loading and five seconds of frames. Both builds share one clock and the same random bytes. Each event goes to the QuickJS build first, and whenever the WebAssembly build makes the same call, it gets the reply QuickJS got. The build prints the first event where their calls or answers differ and what each build did there. A run of server commands is compared as a set, because their order does not change the game. The check compiles QuickJS with scriptc's copy of Zig, once per scriptc version.