9.0 KiB
BlockLua
Lua scripting for Blockland
How to Install
- Install RedBlocklandLoader
- Copy
lua5.1.dllinto your Blockland install folder, next toBlockland.exe - Copy
BlockLua.dllinto themodulesfolder within the Blockland folder - Optional: Copy the
lualibfolder intomodules
Quick Reference
From TorqueScript
'print('hello world') - Execute Lua code in the console by prepending a ' (single quote)
luaeval("code"); - Eval Lua code
luacall("funcName", %args); - Call a Lua global function
luaexec("fileName"); - Execute a Lua file. Path rules are the same as executing .cs files.
luaget("varName"); - Read a Lua global variable
luaset("varName"); - Write a Lua global variable
From Lua
bl.eval('code') - Eval TorqueScript code
bl.funcName(args) - Call a TorqueScript function
bl.varName - Read a TorqueScript global variable
bl['varName'] - Read a TorqueScript global variable (i.e. with special characters in the name, or from an array)
bl.set('varName', value) - Write a TorqueScript global variable
Accessing Torque Objects from Lua
bl.objectName - Access a Torque object by name
bl[objectID] - Access a Torque object by ID (or name)
object.fieldOrKey - Read a field or Lua key from a Torque object
object:set('field', value) - Write a field on a Torque object
object.key = value - Associate Lua data with a Torque object
object:method(args) - Call a Torque object method
object[index] - Access a member of a Torque set or group
for childIndex, child in object:members() do - Iterate objects within of a Torque set or group. Indices start at 0 like in Torque.
Advanced
sched = bl.schedule(timeMs, function, args...) - Schedule a Lua function to be called later, similar to schedule in Torque
sched:cancel() - Cancel a previously scheduled timer
Raycasts and Searches
hitObject, hitPos, hitNormal = bl.raycast(vector{startPosX,y,z}, vector{endPosX,y,z}, 'objtype'/{'objtypes',...}, ignoreObjects...?) - Cast a ray in the world over objects of the specified type(s) (possibly excluding some objects), and return the object hit, the position of the hit, and the normal vector to the surface hit. See the Types section for a list of valid object types.
for object in bl.boxSearch(vector{centerX,y,z}, vector{sizeX,y,z}, 'objtype'/{'objtypes',...}) do - Find all objects in the world of the specified type(s) whose bounding box overlaps with the specified box. See the Types section for a list of valid object types.
for object in bl.radiusSearch(vector{centerX,y,z}, radius, 'objtype'/{'objtypes',...}) do - Find all objects of the specified type(s) whose bounding box overlaps with the specified sphere. See the Types section for a list of valid object types.
Server-Client Communication
bl.addServerCmd('commandName', function(client, args...) code() end) - Register a /-command on the server
bl.addClientCmd('commandName', function(args...) code() end) - Register a client command on the client
bl.commandToServer('commandName', args...) - Execute a server command as a client
bl.commandToClient('commandName', args...) - As the server, execute a client command on a specific client
bl.commandToAll('commandName', args...) - As the server, execute a client command on all clients
Packages/Hooks
bl.hook('packageName', 'functionName', 'before'/'after', function(args) code() end) - Hook a Torque function with a Lua function.
args is an array containing the arguments provided to the function. If the hook is before, these can be modified before being passed to the parent function.
If args._return is set to anything other than nil by a before hook, the parent function will not be called, and the function will simply return that value. Also in this case, any after hook will not be executed.
In an after hook, args._return is set to the value returned by the parent function, and can be modified.
bl.unhook('packageName', 'functionName', 'before'/'after') - Remove a previously defined hook
bl.unhook('packageName', 'functionName') - Remove any previously defined hooks on the function within the package
bl.unhook('packageName') - Remove any previously defined hooks within the package
Classes and Types
bl.type('varName', 'type') - Register the type of a Torque global variable, for conversion when accessing from Lua. Valid types are 'boolean', 'object', and nil (default is nil, which applies automatic conversion).
bl.type('funcName', 'type') - Register the return type of a Torque function, for conversion when calling from Lua. Valid types are 'bool', 'object', and nil - all other conversion is automatic. Already done for all default functions.
bl.type('className::funcName', 'type') - Register the return type of a Torque object method.
bl.class('className') - Register a Torque class to be used from Lua (Already done for all built-in classes)
bl.class('className', 'parentClassName') - Same as above, with inheritance
bl.bool(thing) - Manually convert a Torque boolean (0 or 1) into a Lua boolean.
bl.object(thing) - Manually convert a Torque object reference (object ID or name) into a Lua object.
File I/O
Lua's builtin file I/O is emulated, and is confined to the same directories as TorqueScript file I/O.
Relative paths (./) are allowed. .. is not allowed.
file = io.open('./file.txt', 'r'/'w'/'a'/'rb'/'wb'/'ab') - Open a file
file:read(numberOfChars/'*a') - Read an opened file (must be opened in 'r' (read) or 'rb' (read binary) mode)
file:write(string) - Write an opened file (must be opened in 'w' (write), 'a' (append), 'wb' or 'ab' mode)
file:close() - Close an opened file
Reading files from ZIPs is supported, with caveats. Null characters are not allowed, and \r\n becomes \n. Generally, text formats work, and binary formats don't.
When reading from outside ZIPs, binary files are fully supported.
Modules and Dependencies
dofile('Add-Ons/Path/file.lua') - Execute a Lua file. Relative paths (./file.lua) are allowed. .. is not allowed.
require('modulePath.moduleName') - Load a Lua file or or external library.
Require replaces . with / in the path, and then searches for files in the following order:
./modulePath/moduleName.lua./modulePath/moduleName/init.luamodulePath/moduleName.lua(Relative to game directory)modulePath/moduleName/init.lua(Relative to game directory)modules/lualib/modulePath/moduleName.luamodules/lualib/modulePath/moduleName/init.luamodules/lualib/modulePath/moduleName.dll
Like in standard Lua, modules loaded using require are only executed the first time require is called with that path. Subsequent calls simply return the result from the initial execution. To allow hot reloading, use dofile.
TBD
- bl.class
- bl.new
- bl.datablock
- vector
- Extended standard library functions
Type Conversion
When a TorqueScript function is called from Lua or vice-versa, the arguments and return value must be converted between the two languages' type systems.
TorqueScript stores no type information; all values in TorqueScript are strings. So it's necessary to make some inferences when converting values between the two languages.
From TorqueScript to Lua
- Any numeric value becomes a Lua
number, except as specified withbl.type, which may convert a value into abooleanor a Torque object container. - The empty string "" becomes
nil - A string containing three numbers separated by spaces becomes a
vector - A string containing six numbers separated by spaces becomes a table of two vectors
- Any other string is passed directly as a
string
From Lua to TorqueScript
nilbecomes the empty string ""trueandfalsebecome "1" and "0" respectively- Torque containers become their object ID
- A
vectorbecomes a string containing three numbers separated by spaces - A table of two vectors becomes a string containing six numbers separated by spaces
- Any
stringis passed directly as a string - Tables cannot be passed and will throw an error
I/O and Safety
All Lua code is sandboxed, and file access is confied to the default directories in the same way TorqueScript is.
BlockLua also has access to any C libraries installed in the modules/lualib folder, so be careful throwing things in there.
Unsafe Mode
BlockLua-Unsafe.dll can be used in place of BlockLua.dll, to remove the sandboxing of Lua code. This allows Lua code to access any file and use any library, including ffi.
Please do not publish add-ons that require unsafe mode.
Other Reference
List of Object Types
'all' - Any object
'brick' - Bricks with Ray-Casting enabled
'brickalways' - All bricks including those with Ray-Casting disabled
'player' - Players or bots
'item' - Items
'vehicle' - Vehicles
'projectile' - Projectiles
Other types: 'static', 'environment', 'terrain', 'water', 'trigger', 'marker', 'gamebase', 'shapebase', 'camera', 'staticshape', 'vehicleblocker', 'explosion', 'corpse', 'debris', 'physicalzone', 'staticts', 'staticrendered', 'damagableitem'