Reference

Cog API

Everything the engine gives a script, in one place. The guides explain how to use it: the language, hooks and events, working with objects and vectors, rotations and colors.

Hooks

The functions the engine calls on a script, each optional. How they fit together: Hooks and events.

HookCalled
on_ready()Once, when play starts. The place to find other objects and components. The script’s top-level vars were set before this.
on_update(delta)Every frame while playing. delta is how long the frame took, in seconds.
on_destroy()When the object is destroyed, or play stops.
on_collision(other, normal)This object starts touching another with a solid contact. normal points the way this object would have to move to get out. other is a handle to the other object.
on_collision_exit(other)They stop touching.
on_trigger_enter(other)Something enters this object’s sensor collider.
on_trigger_exit(other)It leaves.
on_ui_click(path)A button in this object’s Canvas is clicked.
on_ui_change(path, value)A slider moves or a text input changes in this object’s Canvas; value is the new value or text.
on_ui_submit(path, text)Enter is pressed in a text input in this object’s Canvas.

Annotations

@component(Name)What the Inspector and Add Component call the script.
@category(Name)Where Add Component lists it.
@export var name: type = valueA variable shown in the Inspector, set per object: int, float, bool, string, Vec2, Vec3, Color or Rotation.
@deprecated("note")Above a function or class: every use is warned about, with the note.

Objects

self, and the handles from Scene.find, Scene.find_all, Scene.with_tag, Scene.objects_within, Scene.spawn and a hook’s other. How to use them: Working with objects.

name, idThe object’s name and its unique number.
tags, has_tag(tag)The object’s tags.
position, rotation, euler_anglesIn the world: a Vec3, a Rotation, and its angles in degrees applied Y, then X, then Z. Assign to set: self.position = v.
local_position, local_rotation, local_euler_anglesRelative to the parent: the numbers the Transform holds and the Inspector shows. Assign to set. For an object with no parent they are the same as the world ones.
set_position(v), set_rotation(r)The same as assigning position and rotation.
velocity, angular_velocityHow fast it is moving and turning, as Vec3s, from its Rigid Body or Character Controller.
groundedWhether a Character Controller is standing on something.
get_component(name)The component’s properties and actions. An error when the object has none.
try_get_component(name)The same, or null.
set_property(type, property, value)Sets any component property, by the component’s type name and the property’s script name. See Components.
send(handler, args...)Calls a function on the object’s scripts. A name nothing there has is a warning in the Console, once.
after(seconds, callback, args...)Calls callback (a function, or a handler’s name) once, later. Gives back an id.
every(seconds, callback)Calls callback repeatedly. Gives back an id.
cancel(id)Stops a timer. Timers fire before on_update, in the order they were set.

Components are named without spaces: "RigidBody", "CharacterController", "Collider", "Renderer", "Animator", "Camera", "Script", "ParticleEmitter".

Changes are applied at the end of the frame, all together, so reading a value straight after setting it in the same frame still gives the old one. For the same reason one part of a transform property can’t be set on its own yet: self.position.x = 5 is an error that says to set the whole value.

Component actions

What get_component(name) gives you can do. The actions are the component’s, not self’s: an object without a Rigid Body has nothing to push.

ComponentActionDoes
"RigidBody"set_velocity(v), set_angular_velocity(v)Sets the speed outright.
"RigidBody"apply_force(v), apply_torque(v)Pushes for the next physics step only: call every frame for a steady push.
"RigidBody"apply_impulse(v), apply_torque_impulse(v)A kick: changes the velocity at once.
"RigidBody"set_gravity(scale)Scales gravity for this body.
"CharacterController"set_velocity(v)Sets its velocity; call every frame.
"CharacterController"set_gravity(scale)Scales gravity for this character.
"Animator"play(state)Plays the named state.
"ParticleEmitter"emit(count)Throws out count particles now, playing or not.
"ParticleEmitter"play()Starts emitting. On a non-looping emitter, starts its duration and burst over.
"ParticleEmitter"stop()Stops emitting; what is alive finishes.
"ParticleEmitter"clear()Removes every live particle at once.

Like every change a script makes, these take effect on the next frame.

Scene

Scene.find(name)The first object with that name, or null.
Scene.find_all(name)Every object with that name.
Scene.with_tag(tag)Every object with the tag.
Scene.objects_within(position, radius)Every other object within reach.
Scene.raycast(from, direction, max_distance){ point, distance, object, id } for the nearest collider hit, or null. point is a Vec3.
Scene.spawn(prefab, position)Places a prefab, by address. Gives back its handle.
Scene.destroy()Removes this object, at the end of the frame.
Scene.canvas(name)The Canvas on the object with that name, below.
Scene.restart()Starts this scene over, after this frame.
Scene.load(scene)Changes to another scene, by address.

Canvas

From Scene.canvas(name). Elements are named by path: "menu/start".

set_text(path, text)Sets a label’s or button’s text.
set_visible(path, visible)Shows or hides an element.
set_enabled(path, enabled)Enables or disables an element.
set(path, property, value)Sets any property of an element.
get(path, property)What an element shows now.

Input

Input.axis(action)-1 to 1, from an axis action.
Input.held(name)Down this frame.
Input.pressed(name)Went down this frame.
Input.released(name)Came up this frame.
Input.mouse_position()The pointer, in pixels from the top left of the game, as a Vec2.
Input.mouse_delta()How far the mouse moved this frame, as a Vec2. Use it for a mouse-look camera.

name is an action, a key ("Space", "R") or a mouse button ("MouseLeft"). See Input.

Camera, Time and Engine

Camera.forward, Camera.rightThe active camera’s directions, as Vec3s.
Time.deltaThis frame’s length, in seconds.
Time.elapsedSeconds since play started.
Time.frameFrames since play started.
Engine.quit()Ends the game. In the editor, stops play.
Engine.max_fps, Engine.set_max_fps(n)The frame-rate cap; 0 is none.

Save

Progress, in slots. How to use it: Saving data.

Save.write(slot, value)Keeps any value (object, list, number, text, true/false, null, Vec2, Vec3, Rotation, Color) in a slot, replacing what was there. Gives nothing back; a failed write is an error naming the file and the reason.
Save.read(slot)The value as it was written (a Vec3 is a Vec3, a whole number stays whole), or null when the slot is empty.
Save.exists(slot)Whether the slot has a save.
Save.delete(slot)Removes the slot and its backup. A slot that is not there is already gone.
Save.list()[{ name, saved_at }], newest first; saved_at is seconds since 1970.

A slot name is plain text such as "slot1": not empty, with no slashes, no dots and none of the characters : * ? " < > |. Anything else is an error that says so. A slot is the file user://saves/<slot>.json. A value that cannot be saved (a function, an object in the world, a number that is not a number) is an error naming where in the value it is, such as the value at .items[1].f.

Save.set, get, has, remove, load, and Save.write without a value are the old store’s calls. They still work and warn; see Moving from the old Save.

Settings

What the player prefers, kept apart from saves. How to use it: Saving data.

Settings.set(key, value)Keeps any value Save can hold. Written to disk by the end of the frame, and when the game ends. Setting what is already there writes nothing.
Settings.get(key, default)The value, or default (null when it is left out) when none is set. A list or object is a copy.
Settings.has(key)Whether a value is set.
Settings.remove(key)Forgets it. A key that is not there is already forgotten.

The settings are the file user://settings.json. The key cannot be empty.

File

Files of your own, by address. How to use it: Files. A path outside the two places below is an error that says what is allowed, and a failed write or a refused path is thrown, so try and catch can take it.

Address
user://...This game’s folder: read and write.
assets://...The game’s own files: read only.
File.read_all_text(path)The file’s text, or null when there is no file. A file that is not text is an error.
File.write_all_text(path, text)Writes the text, making folders as needed. user:// only.
File.read_json(path)The value in a JSON file (a whole number is an int), or null when there is no file. A user file that does not parse is read from its backup.
File.write_json(path, value)Writes the value as JSON. user:// only.
File.exists(path)Whether there is a file. A folder is not one.
File.delete(path)Deletes a file and the backup beside it. A file that is not there is already gone; a folder is an error. user:// only.
File.list(folder)The names in a folder, sorted; a folder’s ends in /. A folder that is not there is empty. On assets:// the names come from the project’s asset list, the same in the editor and the built game.

A path is user:// or assets:// and then names separated by /. These are refused: an empty part (//), . and .., backslashes, #, a name ending in a dot or a space, a character that cannot be in a file name on every computer (: * ? " < > | or a control character), and the names Windows reserves for devices (CON, NUL, COM1 and the like).

File.write_json writes plain JSON. A Vec3 is {"x", "y", "z"}, a Vec2 {"x", "y"}, a Color {"r", "g", "b", "a"} (0 to 1) and a Rotation its quaternion {"x", "y", "z", "w"}. None reads back as its type; Save is for that.

log

log.info(...), log.warn(...), log.error(...) write to the Console.

math

math.pi
sqrt, abs, floor, ceil, round, pow, exp, sign
log(x), log(x, base)
min(...), max(...)Of any number of numbers.
clamp(x, lo, hi)
lerp(a, b, t)Numbers.
sin, cos, tan, asin, acos, atan2Radians.
random(), random(lo, hi)
length(v), distance(a, b), normalize(v), dot(a, b), cross(a, b)Deprecated: a vector does these itself, v.length, a.distance(b), v.normalized, a.dot(b), a.cross(b).

Every built-in function says what it takes when given the wrong number of arguments: math.sqrt takes 1 argument, got 2.

Values

int(x), float(x), str(x)Conversions.
range(n), range(a, b), range(a, b, step)Numbers for a for loop.

Vec3 and Vec2

How to use them: Vectors, rotations and colors. All four types are values: assigning one copies it.

Vec3(x, y, z), Vec2(x, y)Makes one.
v.x, v.y, v.zIts numbers; v.x = 3 changes v.
Vec3.up, down, left, right, forward, backOne unit along each axis. forward is -Z, the way a camera looks. Vec2 has none.
Vec3.zero, Vec3.one, Vec2.zero, Vec2.one
v.lengthHow long it is.
v.normalizedThe same direction, one unit long. Zero stays zero.
v.dot(w)
v.cross(w)Vec3 only.
v.distance(w)How far apart two points are.
v.move_toward(target, step)step closer to target, never past it.
Vec3.lerp(a, b, t), Vec2.lerp(a, b, t)t of the way from a to b.
+, -, * n, / n, -v, ==Between vectors, and with a number. Two vectors don’t multiply: use dot or cross. == is exact: to ask whether two points are close, compare a.distance(b) with a distance.
vec3(x, y, z)Deprecated: Vec3(x, y, z).

Rotation

Rotation.from_euler(x, y, z), Rotation.from_euler(v)From angles in degrees, applied Y, then X, then Z: the numbers the Inspector shows.
Rotation.from_axis_angle(axis, degrees)A turn about an axis.
Rotation.look_toward(forward, up)Facing forward, with its top toward up (Vec3.up when left out).
Rotation.from_to(a, b)The turn that takes direction a to direction b.
Rotation.from_quaternion(x, y, z, w)From a quaternion’s four numbers. There is no bare Rotation(...): four numbers that look like angles aren’t a rotation, and the error says which constructor to use.
Rotation.identityNo turn.
r.euler_anglesIts angles in degrees, as a Vec3.
r.axis, r.angleThe axis it turns about, and how far, in degrees.
r.forward, r.right, r.upWhich way its front, right and top point.
r.x, r.y, r.z, r.wIts quaternion.
r.inverseThe turn back.
r.slerp(other, t)t of the way to other.
r * other, r * v, ==r * other turns by r, then by other; r * v turns the vector v. == is exact, and a quaternion equals its negation.

Color

Channels run from 0 to 1, as a color picker shows them.

Color.from_rgb(r, g, b), Color.from_rgba(r, g, b, a)Channels from 0 to 1.
Color.from_bytes(r, g, b), Color.from_bytes(r, g, b, a)Channels from 0 to 255.
Color.from_hex(text)"#rrggbb", "#rrggbbaa" or "#rgb".
Color.from_hsv(hue, saturation, value), with an optional alphaHue in degrees, the others 0 to 1.
Color.white, Color.black, Color.clearclear is fully transparent. There is no bare Color(...).
c.r, c.g, c.b, c.aIts channels; c.a = 0.5 changes c.
c.bytes, c.hex, c.hue, c.saturation, c.valueThe same color the other ways.
Color.lerp(a, b, t)t of the way from a to b.
+, -, *, / n, ==* takes a color (a tint) or a number.

Where the types come from

self.position, self.local_positionVec3
self.rotation, self.local_rotationRotation
self.euler_angles, self.local_euler_anglesVec3, degrees
self.velocity, self.angular_velocityVec3
Camera.forward, Camera.rightVec3
Input.mouse_position(), Input.mouse_delta()Vec2
A raycast’s pointVec3
A component’s color propertyColor

An @export can be any of the four: @export var tint: Color = Color.white shows a color picker in the Inspector.

Text

s.len(), s.length, s.upper(), s.lower(), s.trim(), s.contains(part), s.starts_with(part), s.ends_with(part), s.replace(from, to), s.split(sep), s.substring(start, end). Each is also string.name(s, ...): string.len(s).

Arrays

a.length, a.push(x), a.pop(), a.contains(x), a.index_of(x) (-1 when it isn’t there), a.remove(x), a.map(f), a.filter(f), a.copy().

Objects

o.keys(), o.values() (in key order), o.has(key), o.copy().