Events and communication between scripts
In a game, one script often needs to tell another script that something happened. The script that collects a star tells the score script; the script whose timer runs out shows a button. This page explains three ways to do that.
The code below was tested on 2026-10-29: we created scripts with the same code in a launched game, attached them to entities and ran them (1 run each). Creating the script files works the same way as in Create and attach a new script.
Three ways
| Method | When to use | Pros and cons |
|---|---|---|
Game-wide events (this.app.fire/on) | When you don't need to know who receives it. Score, game over | The sender doesn't need to know the receiver. If you misspell the event name, nothing happens and there's no error |
Entity events (entity.fire/on) | When only a specific entity should be notified | The narrow scope avoids confusion. You have to find the receiving entity |
Direct calls (entity.script.name.function()) | When the target is fixed and you need the result immediately | The simplest. Both scripts have to know about each other, which makes changes harder |
Game-wide events
Sender (star):
Star.prototype.initialize = function () {
this.entity.collision.once('triggerenter', function (other) {
this.app.fire('star:collected', 1);
this.entity.enabled = false;
}, this);
};
Receiver (score):
Score.prototype.initialize = function () {
this.score = 0;
this.app.on('star:collected', this.onStar, this);
this.on('destroy', function () {
this.app.off('star:collected', this.onStar, this);
}, this);
};
Score.prototype.onStar = function (amount) {
this.score += amount;
this.entity.element.text = 'Score ' + this.score;
};
In our test, when a falling Box passed through the trigger StarT, the score became 1, the text of Text changed to Score 1, and StarT was disabled. After that, we destroyed the score script and fired the same event again, and the score stayed at 1. That's because off in destroy removed the connection.
- Event names are strings. Naming them as
what:how, likestar:collected, makes them easy to find. - Values from the second argument of
fireonward are passed as-is to the receiving function. - If you connected with
this.app.on, remove it withoffwhen the entity is destroyed (Script structure and lifecycle). - If you use Korean characters in the score text, the font must include those characters (Change score and message text).
Entity events
Entities have the same fire/on. Collision events (collisionstart) and button events (click) work this way too. We ran and confirmed this.entity.collision.on('collisionstart', …) (Receive collision events) and this.entity.button.on('click', …) (Make a button).
var door = this.app.root.findByName('Door');
door.fire('open');
The receiver listens with door.on('open', function () { … }). In our test, we added on('open') to Plane and fired fire('open'), and it was received.
Find other entities
| Method | Code | Notes |
|---|---|---|
| By name | this.app.root.findByName('Ball') | If several entities share the name, returns the first one. Run and confirmed in a launched game |
| By tag | this.app.root.findByTag('star') | Returns a list. Add the tag in the entity's Tags first. In our test, a Box tagged star was found |
| Via an attribute | attributes.add('target', { type: 'entity' }) | Drag and drop in the editor. The link doesn't break if the name changes |
In AI-generated games, entity names can differ from one generation to the next. Before editing code that finds entities by name, check that it matches the actual name in HIERARCHY.