Cross-Entity Calls

In Lemonate, game logic is defined through Entities — Lua scripts attached to Scene Objects. Sometimes, one entity script needs to call a function defined in another entity attached to a different object in the scene graph.

To enable this, Lemonate provides the :entity() method on the SceneObject type. This method allows you to access another entity scripts by specifying its script item name as a string.

How Cross-Entity Calls Work

In Lemonate, Lua does not have type names or reflection features like some other languages. This means you cannot refer to entity types directly. Instead, the :entity(scriptName) method retrieves the instance of a specific script attached to a node, using the script file name.

Note

The string you pass to :entity() must match the item name of the Lua script that defines the entity, not the name of the Entity that is created inside. This is necessary because Lua does not provide native support for type introspection.

Usage Example

Let’s say you have two scene objects:

  1. A Controller object with a script named MyController

  2. A Box object with a script named BoxController

You want the Controller to call a method on the Box each frame to move it upward.

BoxController

This script defines a method moveBox(translation) on the box entity:

local BoxEntity = Class.new(Entity)

function BoxEntity:moveBox(translation)
    self.node:withTransform(function(t)
        t.position.add(translation)
    end)
end

return BoxEntity

ControllerEntity

This script references the Box entity and calls its method during the update loop. Note that it is using the script item’s name “BoxController”, not “BoxEntity” which is the entity’s name created in the script.

local Vector3 = require 'engine/math/vector3'

local ControllerEntity = Class.new(Entity)

ControllerEntity:addProperty("box", Property.Node)

function ControllerEntity:update()
    self.box:entity("BoxController"):moveBox(Vector3.new(0, 1, 0))
end

return ControllerEntity

Explanation

  • self.box is a node property (set up via the editor or manually).

  • self.box:entity("BoxController") returns the entity script instance named BoxController attached to the node.

  • :moveBox(...) then calls the method on that script instance.

Best Practices

  • Make sure that the script name passed to :entity() matches the item name exactly.

  • Use addProperty(“nodeName”, Property.Node) to link scene objects to each other via the editor.

  • Always check that the target object and entity exist before calling methods in more complex scenarios.

Example with Null Check:

function ControllerEntity:update()
    if self.box then
        local boxController = self.box:entity("BoxController")
        if boxController then
            boxController:moveBox(0, 1, 0)
        end
    end
end

Summary

  • Use :entity(scriptItemName) to call methods on another entity script.

  • This enables communication between different objects in the scene graph.

  • Script names (not type names) must be used due to Lua’s limitations.

  • Use this feature when you want modular, decoupled components that interact via explicit links.