Physics Scripting
Lemonate's physics simulation runs in the engine; scripts interact through SceneObject methods (forces, velocities), the Physics module (raycasts), and events (collisions). Editor setup for gravity, layers, and colliders is covered in Physics.
SceneObject physics methods
On any physics-enabled object you can read and write simulation state:
local Vector3 = require 'engine/math/vector3'
-- Impulses and forces
self.node:applyCentralImpulse(Vector3.new(0, 8, 0))
self.node:applyImpulse(Vector3.new(1, 0, 0), Vector3.new(0, 0.5, 0))
self.node:applyForce(Vector3.new(0, -10, 0), Vector3.new(0, 0, 0))
self.node:clearForces()
-- Velocity
self.node:setLinearVelocity(Vector3.new(3, 0, 0))
local v = self.node:getLinearVelocity()
self.node:setAngularVelocity(Vector3.new(0, 1, 0))
-- Sync transform with physics world explicitly when needed
self.node:setPhysicsPosition(Vector3.new(0, 5, 0))
self.node:setPhysicsRotation(quaternion)
Use impulses for instant kicks (jumps, explosions). Use forces for continuous effects (thrusters, wind). Prefer deltaTimeMs from Lifecycle Methods when integrating custom movement alongside physics.
Raycasts
The Physics module tests line segments against colliders:
local Physics = require 'engine/physics'
local Vector3 = require 'engine/math/vector3'
Physics.raycast(
Vector3.new(0, 10, 0),
Vector3.new(0, -10, 0),
Physics.RaycastType.Closest,
{"Default"} -- optional layer name filter, or nil for all
):next(function(hit)
if hit.hit then
print("Hit at", hit.point.x, hit.point.y, hit.point.z)
local obj = SceneObject.findById(hit.object)
end
end)
Physics.RaycastType.AllHits returns every intersection along the ray as a table.
Batch raycasts — same API shape with arrays of start/end vectors:
Physics.raycastMany(starts, ends, Physics.RaycastType.Closest, nil):next(function(results)
for i, hit in ipairs(results) do
-- ...
end
end)
Typical uses: ground checks, line-of-sight, weapon traces, click-to-world placement.
Collision events
Listen for physics collision pairs globally:
local Events = require 'engine/events'
function MyBehaviour:init()
Events.on('physicsCollisions', function(e)
for _, pair in ipairs(e.data) do
local a = SceneObject.findById(pair.object1)
local b = SceneObject.findById(pair.object2)
-- respond to contact
end
end)
end
See Events for event registration and cleanup behaviour.
Layers
Assign layers on scene objects to filter raycasts and collisions:
Layer names used in Physics.raycast match the project's physics layer configuration in the editor.
Global gravity
Change world gravity from scripts via the Project API:
local Project = require 'engine/project'
local Vector3 = require 'engine/math/vector3'
Project.setGravity(Vector3.new(0, -9.81, 0))
Constraints and advanced features
Hinge, slider, and cone-twist constraints are available on the Physics module. See Physics for the full reference.
Vehicles
Wheel-based vehicles use SgVehicle with a dedicated setup workflow. See SgVehicle for editor steps and a driving script example.
Further reading
- Physics — editor physics settings
- Physics API — raycast, constraints, sweep tests
- Scene Graph — SceneObject physics helpers
- Events —
physicsCollisionsevent