Scripting with Cog

Your first script

Objects get behavior from Cog scripts. A script is one .cog file, attached to an object as a component. The engine calls the script’s hooks (on_ready when play starts, on_update every frame), and the script changes its object through self.

Make the script

  1. Select the cube from Your first project.
  2. In the Inspector, click Add Component, then New Component.
  3. Name it Spinner and click Create and Add.

Otter writes assets/scripts/Spinner.cog and attaches it to the cube. Open that file in any text editor. It starts like this:

// Spinner, a component script.
//
// Anything marked @export shows up in the Inspector, and can be set
// differently on every object this is on.

@component(Spinner)
@category(Scripting)

@export var speed: float = 1.0

// Once, when play starts. Where a script finds its other components.
fn on_ready() {
}

// Every frame while playing. `delta` is the frame's length in seconds.
fn on_update(delta: float) {
}

Make it spin

Make speed a number of degrees a second, and fill in on_update:

@export var speed: float = 90.0

fn on_update(delta: float) {
    var a = self.euler_angles
    self.euler_angles = Vec3(a.x, a.y + speed * delta, a.z)
}

Save the file and press Play. The cube turns about its vertical axis, a quarter turn a second. euler_angles are the angles the Inspector shows, in degrees; Vectors, rotations and colors has the other ways to read and set them.

Multiplying by delta is what makes the speed a speed. A frame is never exactly the same length as the last, so a script that added a fixed amount every frame would spin faster on a faster computer.

Change it from the Inspector

speed is marked @export, so it has a row under Spinner in the Inspector. Set it to 360 and press Play again: the cube spins four times as fast, a whole turn a second, and you didn’t touch the script.

Each object keeps its own exported values. Put Spinner on a second cube with a speed of -90 and the two spin opposite ways from one script.

What’s in a script

LineWhat it does
@component(Spinner)The name the Inspector and Add Component show.
@category(Scripting)Where Add Component lists it.
@export var speed: float = 1.0A value set per object in the Inspector.
var name = valueThe script’s own state. It lasts as long as the object.
fn on_update(delta: float)A hook. The engine calls it every frame while playing.