Coming soon toSteam
Modding docsAPI 1

Models, pictures and objects

Model formats

FormatNotes
glTF .glb / .gltfRecommended. Meshes, node transforms, PBR materials, embedded or external PNG/JPEG textures. .gltf may reference a .bin next to it.
FBX .fbxBinary FBX 7.1 to 8.0, as Blender, Maya and 3ds Max export. Meshes, transforms, materials and textures (embedded or as files). ASCII FBX is not supported; export binary.
OBJ .obj + .mtlMeshes with a material library: colours and map_Kd textures.

What is not loaded: animations, skinning, cameras and lights inside the file. Addresses on the internet and paths outside your mod are refused. Missing textures are reported and the model loads without them.

Conversion. All three formats are right-handed with Y up, and the game is left-handed, so the loader mirrors Z and flips triangle winding, as most game engines do. FBX unit settings are respected: a model exported in centimetres comes in at the right size. Normals are generated when a file has none, and tangents are always generated.

Limits: 256 meshes, 256 materials, 500 000 vertices and triangles per mesh, 2 000 000 in total, and 4096 nodes. For blocks: 16 meshes, 16 materials, 100 000 vertices and 60 000 triangles.

Exporting from Blender: File ▸ Export ▸ glTF 2.0 (.glb) with "+Y Up" (the default), or FBX with "Apply Transform". Put textures in your mod and keep the paths relative.

Pictures

.png (8-bit, with or without alpha) and .jpg, up to 8192 pixels per side. Each mod may have 256 MB of pictures loaded at once. assets.usage() reports what is loaded.

local icon = assets.texture("ui/icon.png")                 -- colour picture (sRGB)
local bumps = assets.texture("textures/rock-n.png", "normal") -- data: normal maps, masks (linear)
log.info(icon.width, icon.height)

The second argument says how the picture is used: "color" (default), "normal" or "data" (linear), or "ui".

Materials

local paint = assets.material{ color = color("#c04020"), metallic = 0.2, roughness = 0.6, texture = "textures/metal.png" }
local glass = assets.material{ color = color("#80c0ff60"), alpha = "blend", doubleSided = true }
local neon  = assets.material{ color = color("#101010"), emissive = color("#40ffd0") }
paint:setColor("_BaseColor", color("#ff8040"))
paint:setNumber("_Smoothness", 0.8)
paint:setTexture("_BaseMap", assets.texture("textures/metal.png"))

Options: name, color, emissive, metallic, roughness, doubleSided, alpha (opaque, cutout or blend) and texture. The material uses the game's standard lit shader.

Objects in the world

With the world permission, client scripts place their own objects. Other players don't see them unless their copy of your mod places them too, typically in response to a message or replicated state.

local statue = world.spawn("models/statue.glb", { position = vec3(10, 0, 5), rotation = quat.euler(0, 45, 0), scale = vec3(2, 2, 2) })
local marker = world.shape("sphere", { position = vec3(0, 3, 0), scale = vec3(0.3, 0.3, 0.3), color = color("#f59e0b") })
local anchor = world.empty("lamp")

marker:addLight{ color = color("#ffd070"), range = 8, intensity = 2 }      -- call again to change it
marker:follow(statue, vec3(0, 3, 0))
marker:followPlayer(players.me(), vec3(0, 2.2, 0))
marker:lookAt(vec3(0, 0, 0))
statue:setMaterial(assets.material{ color = color("#9090a0"), metallic = 1, roughness = 0.2 })
statue.visible = false
statue:destroy()
FunctionDescription
world.spawn(model, options)Place a model from your mod
world.shape(shape, options)cube, sphere, capsule, cylinder or quad, with no model file needed
world.empty(name, options)An invisible object, to hold a light or sound or to follow something
world.me()Where your player stands
world.camera(){ position, forward, up, fov }
world.raycast(origin, direction, distance){ point, normal, distance, name } of the first thing hit, or nil
world.gravity()Gravity here, as a vector

Options for all three: position, rotation, scale, color, name, visible. Objects have no collision and do not affect physics. They are decorations, markers and displays. addLight{ color, range, intensity, shadows, spot, angle } adds a point light, or a spot light with spot = true.