Runtime limitations
TypeScript is the source language, but generated code runs inside KILLSCRIPT’s restricted XLua environment with Lua 5.4 semantics. It is not Node.js, a browser, Roblox Luau or unrestricted desktop Lua.
The compiler rejects patterns that would emit globals the game does not expose. This turns a late Lua failure into an earlier build error.
Unsupported patterns and alternatives
Section titled “Unsupported patterns and alternatives”| Do not rely on | Why | Use instead |
|---|---|---|
try/catch, throw, runtime typeof | Require unavailable pcall, error or type | Validate inputs and branch explicitly |
async, await, generators | Require unsupported coroutine/runtime helpers | Scheduler callbacks |
dynamic import() or direct require() | The game loader does not resolve project paths reliably | Static relative imports bundled by the compiler |
| runtime npm imports | Arbitrary package runtimes are not bundled safely | Put implementation helpers in src/ |
| browser/Node globals | They do not exist in XLua | The typed game API or compile-time packages |
| passing or destructuring SDK compiler handles | Lowering requires a direct, statically known use site | Import the handle, then call its property or method directly |
client Scheduler.OnTick | Not exposed in client context | scheduler.frame() or a time/tick guard |
server Scheduler.OnFrame | Reflex has no render frames | scheduler.tick() |
Type-only npm packages are safe because they disappear. SDK imports are also safe: compiler macros are replaced and only the necessary generated helpers remain.
Static multi-file architecture is supported
Section titled “Static multi-file architecture is supported”Organize code normally:
import "./features/status-hud";import "./features/world-marker";Use extensionless relative imports. Every reachable file is bundled into
scripts/main.lua or scripts/server.lua, so the game never needs to resolve
features/status-hud itself.
Only reachable files are included. A runtime package import outside src/ is
rejected unless it is type-only or an SDK compiler import.
Arrays are not all the same
Section titled “Arrays are not all the same”Ordinary TypeScript arrays are supported. reduce() and reduceRight() need
an explicit initial value:
const total = values.reduce((sum, value) => sum + value, 0);Native LuaArray userdata is indexed from one and must use
Game array helpers or an explicit 1..Length
loop.
Current game bugs
Section titled “Current game bugs”These calls are typed because they exist, but their current runtime behavior is not reliable:
- several raw
Network.SendTablecalls during one tick collapse to one; usedefineNetwork()for ordered batching; InputAction.Disable()changesIsPressed()but may not suppress an existingOnPerformedcallback; guard the callback with your own state;- Reflex
AgentInput.SetButtonState,SetLookRotationandSetMoveDirectionreturn successfully but do not affect the actually controlled player; - the module settings UI may temporarily stop displaying default bindings after an action-map refresh even though those bindings still work.
The game-specific issues above have been reported to the developer. They are documented here temporarily so code and AI assistants do not infer working behavior from a successful call alone.
When a build fails, read the first compiler diagnostic and use Troubleshooting for common project and sync problems.