Skip to content

Sprites and events

Nothing in Katnip runs until it is inside an event handler, and an event handler can only live inside a sprite. This is the same rule Scratch has — a stack of blocks with no hat on top never fires.

sprite Cat {
private lives: num = 9;
proc pounce(power: num) -> void {
motion.forward(power);
motion.turn(90);
}
events.onFlag() {
pounce(40);
}
}

A sprite body holds three kinds of thing:

  • variables — sprite-owned, see Variables
  • procs — custom blocks available only to this sprite
  • event handlers — the scripts

Each sprite becomes one target in the .sb3, plus the stage.

Handlers come from the events and clone namespaces, and each maps to a Scratch hat block. The analyzer rejects them anywhere but a sprite’s top level.

events.onFlag() {
motion.goTo(0, 0);
looks.show();
}
events.onKey(Key.SPACE) {
clone.create("_myself_");
}

Key is a prelude enum: Key.SPACE, Key.LEFT_ARROW, Key.RIGHT_ARROW, Key.UP_ARROW, Key.DOWN_ARROW, Key.ANY, Key.NUM_0Key.NUM_9.

events.onClick() {
looks.say("ow", 1);
}
events.onBackdropSwitch("backdrop1") {
looks.say("new scene", 1);
}
events.onBroadcast("tally") {
looks.say(f"score is {score}", 1);
}
clone.onStart() {
looks.setSize(50);
motion.goTo("_random_");
wait(1);
clone.delete();
}

Broadcasts are how sprites talk to each other, since a sprite cannot call another sprite’s procedures.

events.broadcast("tally"); # fire and continue
events.broadcastAndWait("checked"); # block until every receiver finishes

The name can be a computed expression, not just a literal:

events.broadcast(f"level-{level}");
sprite Star {
events.onKey(Key.SPACE) {
clone.create("_myself_");
}
clone.onStart() {
looks.show();
motion.goTo("_random_");
for (i, 20) {
motion.forward(5);
}
clone.delete();
}
}

clone.create takes "_myself_" or the name of another sprite. Sprite-private variables are per-clone in Scratch, exactly as in the block editor.

A sprite can have as many handlers of a kind as you like. They become separate scripts and run concurrently, like separate stacks in Scratch:

sprite Cat {
events.onFlag() { drawSquare(); }
events.onFlag() { playMusic(); }
}
You want Do this
Share a value A top-level public variable — it lives on the stage
Trigger behaviour events.broadcast(...)
Wait for behaviour events.broadcastAndWait(...)
Read another sprite’s property sensing.getProperty("x position", "Cat")
Share a procedure Declare it at the top level, not in a sprite
  • self.x = 0, self.costume = "..." — sprite property initializers appear in some older examples but are not implemented. Set them in a green-flag handler instead:

    events.onFlag() {
    motion.goTo(0, 0);
    looks.show();
    looks.switchCostume("costume1");
    }
  • Costumes, backdrops and sounds. Every sprite gets the same default costume and there is no asset import. You can switch costumes by name, but the costumes have to already exist — which means editing the project after building. See Known gaps.