Razorbill
Scripting API

Physics & Raycasting

Forces

apply_force

Apply a continuous force to a rigidbody (world space). Force is applied over the physics step.

bool apply_force(ScriptContext* ctx, EntityHandle entity, const float force[3]);
ParameterTypeDescription
entityEntityHandleEntity with Rigidbody component
forceconst float[3]Force vector [fx, fy, fz] in Newtons

apply_impulse

Apply an instant velocity change to a rigidbody.

bool apply_impulse(ScriptContext* ctx, EntityHandle entity, const float impulse[3]);
ParameterTypeDescription
entityEntityHandleEntity with Rigidbody
impulseconst float[3]Impulse vector [ix, iy, iz]

apply_torque

Apply rotational force to a rigidbody.

bool apply_torque(ScriptContext* ctx, EntityHandle entity, const float torque[3]);
ParameterTypeDescription
entityEntityHandleEntity with Rigidbody
torqueconst float[3]Torque vector [tx, ty, tz] in Newton-meters

Velocity

get_linear_velocity

bool get_linear_velocity(ScriptContext* ctx, EntityHandle entity, float out_velocity[3]);

set_linear_velocity

bool set_linear_velocity(ScriptContext* ctx, EntityHandle entity, const float velocity[3]);

get_angular_velocity

Get rotational velocity in radians/second per axis.

bool get_angular_velocity(ScriptContext* ctx, EntityHandle entity, float out_velocity[3]);

set_angular_velocity

bool set_angular_velocity(ScriptContext* ctx, EntityHandle entity, const float velocity[3]);

Mass

get_rigidbody_mass

bool get_rigidbody_mass(ScriptContext* ctx, EntityHandle entity, float* out_mass);

set_rigidbody_mass

bool set_rigidbody_mass(ScriptContext* ctx, EntityHandle entity, float mass);

Kinematic

is_kinematic

Check if a rigidbody is kinematic (script-driven, not physics-driven).

bool is_kinematic(ScriptContext* ctx, EntityHandle entity, bool* out_kinematic);

set_kinematic

bool set_kinematic(ScriptContext* ctx, EntityHandle entity, bool kinematic);

Raycasting

raycast

Cast a ray and get the first hit.

bool raycast(ScriptContext* ctx,
             const float origin[3],
             const float direction[3],
             float max_distance,
             uint32_t layer_mask,
             RaycastHit* out_hit);
ParameterTypeDescription
originconst float[3]Ray start position [x, y, z]
directionconst float[3]Normalized direction [x, y, z]
max_distancefloatMaximum ray length
layer_maskuint32_tBitmask of collision layers (0xFFFFFFFF = all)
out_hitRaycastHit*Output hit info (caller-allocated)

Returns true if something was hit.

raycast_all

Cast a ray and get all hits sorted by distance.

uint32_t raycast_all(ScriptContext* ctx,
                     const float origin[3],
                     const float direction[3],
                     float max_distance,
                     uint32_t layer_mask,
                     RaycastHit* out_hits,
                     uint32_t max_hits);

Returns the number of hits found (up to max_hits).


Example: Projectile with Physics

void OnUpdate(ScriptContext* ctx) {
    // Fire projectile on click
    if (ctx->is_mouse_button_down(ctx, 0)) {
        EntityHandle bullet = ctx->spawn_entity(ctx, "Bullet");

        float pos[3];
        ctx->get_position(ctx->self, pos);
        pos[2] -= 1.0f; // Offset forward
        ctx->set_position(bullet, pos);

        // Apply forward impulse
        float impulse[3] = {0, 0, -50};
        ctx->apply_impulse(ctx, bullet, impulse);
    }
}

Example: Ground Check with Raycast

void OnUpdate(ScriptContext* ctx) {
    float pos[3];
    ctx->get_position(ctx->self, pos);

    float origin[3] = {pos[0], pos[1] + 0.1f, pos[2]};
    float direction[3] = {0, -1, 0};

    RaycastHit hit;
    bool grounded = ctx->raycast(ctx, origin, direction, 0.3f, 0xFFFFFFFF, &hit);

    if (grounded) {
        // Snap to ground
        pos[1] = hit.position[1];
        ctx->set_position(ctx->self, pos);
    }
}

On this page