Skip to main content
The Projectile class represents a single in-flight projectile in RollingQuest. You create projectiles by calling LevelSection:createProjectile() with either a ProjectileRequest object or an inline property table. Once created, a Projectile lets you read and write its physics parameters, control its collision behaviour, and hook into fire, explode, and update events. The companion ProjectileRequest class is the recommended way to configure a projectile before launch.

Projectile

Properties

Identity

PropertyTypeRead-onlyDescription
skinstringVisual skin identifier of the projectile.
isActivebooleantrue while the projectile is in flight.
sectionstringID of the section whose projectile pool owns this instance.
isHomingbooleantrue when homingStrength > 0.

Transform

PropertyTypeRead-onlyDescription
positionVector3Current world-space position.
rotationQuaternionCurrent world-space rotation.
forwardVector3Normalised forward direction derived from rotation.
velocityVector3Current velocity vector.
angularVelocitynumberCurrent angular velocity (read-only derived value).

Movement

PropertyTypeRead-onlyDescription
lifetimenumberRemaining lifetime in seconds before the projectile auto-expires.
speednumberLinear speed along the forward axis.
accelerationnumberRate of change of speed per second.
angularSpeednumberRotational speed around the local axis.
angularAccelerationnumberRate of change of angularSpeed per second.
angularLocalAxisRotationVector3Local axis around which angular rotation is applied.
homingStrengthnumberStrength of the steering force toward the nearest ball.
maxHomingRangenumberMaximum distance at which homing tracking activates.

Collision Behaviour

PropertyTypeRead-onlyDescription
explodeOnCollideWithBlocksbooleanDetonate when hitting a block side.
explodeOnCollideWithItemsbooleanDetonate when hitting an item.
explodeOnCollideWithEnemiesbooleanDetonate when hitting an enemy.
explodeOnCollideWithBallsbooleanDetonate when hitting a ball.
explodeOnCollideWithDecorationsbooleanDetonate when hitting a decoration.

Methods

fire

Launch the projectile. Six overloads give you control over the starting position, rotation, and speed:
function Projectile:fire()

--- @param initialSpeed number
function Projectile:fire(initialSpeed)

--- @param position Vector3
function Projectile:fire(position)

--- @param rotation Quaternion
function Projectile:fire(rotation)

--- @param position Vector3
--- @param rotation Quaternion
function Projectile:fire(position, rotation)

--- @param position Vector3
--- @param rotation Quaternion
--- @param initialSpeed number
function Projectile:fire(position, rotation, initialSpeed)

explode

Detonate the projectile immediately:
function Projectile:explode()

--- @param rotation Quaternion
function Projectile:explode(rotation)

Event callbacks

You can attach Lua functions to three lifecycle events after creation:
--- @param event function
function Projectile:setOnFireEvent(event)

--- @param event function
function Projectile:setOnExplodeEvent(event)

--- @param event function  -- receives (projectile, deltaTime)
function Projectile:setOnUpdateEvent(event)

ProjectileRequest

ProjectileRequest is a configuration object you build before calling LevelSection:createProjectile(). Using it keeps your creation code readable and gives you access to all properties in one place.

Static Constructor

Three overloads create a new request:
--- @return ProjectileRequest
function ProjectileRequest.new()

--- @param skin string
--- @return ProjectileRequest
function ProjectileRequest.new(skin)

--- @param skin string
--- @param origin Vector3
--- @param rotation Quaternion
--- @return ProjectileRequest
function ProjectileRequest.new(skin, origin, rotation)

Properties

All ProjectileRequest properties are read/write.
PropertyTypeDescription
skinstringVisual skin identifier.
originVector3World-space spawn position.
rotationQuaternionInitial rotation at spawn.
tagstringOptional tag for lookup or categorisation.
powerintegerDamage power of the projectile.
lifetimenumberDuration in seconds before auto-expiry.
speednumberInitial linear speed.
accelerationnumberRate of speed change per second.
homingStrengthnumberSteering strength toward the nearest ball.
maxHomingRangenumberMaximum homing detection range.
autoFirebooleanWhen true the projectile fires immediately on creation.
explodeOnCollideWithBlocksbooleanDetonate on block collision.
explodeOnCollideWithItemsbooleanDetonate on item collision.
explodeOnCollideWithEnemiesbooleanDetonate on enemy collision.
explodeOnCollideWithBallsbooleanDetonate on ball collision.
explodeOnCollideWithDecorationsbooleanDetonate on decoration collision.
explodeOnCollideWithProjectilesbooleanDetonate on projectile collision.
onFirefun(projectile: Projectile): voidCallback invoked when the projectile fires.
onExplodefun(projectile: Projectile): voidCallback invoked when the projectile explodes.
onUpdatefun(projectile: Projectile, deltaTime: number): voidCallback invoked every update tick.

Creating and Firing a Projectile

You create a projectile through the LevelSection object. The example below fires a homing projectile from a side each time the ball rolls onto it:
function OnBallRoll(self, ball)
    -- self is a Side
    local section = Level.getSection(self.section)

    -- Build the request
    local req = ProjectileRequest.new("plasma_bolt", self.centerPosition, self.rotation)
    req.speed            = 8.0
    req.lifetime         = 5.0
    req.homingStrength   = 2.5
    req.maxHomingRange   = 20.0
    req.explodeOnCollideWithBalls = true
    req.autoFire         = false

    -- Attach a callback that logs the explosion
    req.onExplode = function(proj)
        Log.info("Projectile exploded at " .. proj.position.x .. "," .. proj.position.y)
    end

    -- Create the projectile and fire it manually
    local proj = section:createProjectile(req)
    proj:fire(self.centerPosition, self.rotation, 10.0)
end
You can also use the inline table overload for concise one-liners:
local proj = section:createProjectile({
    skin     = "fireball",
    origin   = self.centerPosition,
    rotation = self.rotation,
    speed    = 12.0,
    lifetime = 3.0,
    autoFire = true,
    explodeOnCollideWithBalls = true,
})