Entities
Your game is made up of entities each of which have an associated UUID, position, type and data. These fields can be edited and used alongside Entity Functions to create gameplay.

Types & Behaviour Scripting
Entities are divided into types, each of which have their own behaviour. This behaviour is determined by a script in the entity
folder. To create a new entity type, simply create a new file in this folder, call the file entity_type_name.lua
and add the stub code shown below:
-- entity_type_name.lua file
local function init(self)
end
local function update(self, dt)
end
local function message(self, msg)
end
return {init=init,update=update, message=message}
There must always be an Entity Type called player
which acts as the abstraction for both the player client and other players within the simulation.
These three functions init(), update(), and message() govern the behaviour of all entities of this type. Each must be referenced and returned in a table at the end of the file.
Init
The init() function is called when the entity is created and should be used to set initial state (for example, setting the Chunkloader or Data fields).
local function init(self)
end
Update
The update() function is called each tick to update the entity, for movement and repeating processes. The parameter dt
is the time since the last update in seconds.
local function update(self, dt)
end
Message
The message() function receives messages sent to this entity and processes them. Messages can come from other entities or the game client.
All messages sent from the game client are sent to the player
entity, and received by the message() function in player.lua
. If a message is sent from the client, its message's Client
field will be true.
local function message(self, msg)
end
The msg
argument supplied to this function is defined as follows:
Data
table
Contains the content of the message.
Client
bool
True, if the message was sent from a game client.
False, if sent from another entity on the server.
Entity Messaging
Messages between entities are sent using api.entity.Message()
. They are received by an entity's message
function.
For example, sending a message to a particular entity each tick would look like:
local function update(self, dt)
api.entity.Message(receiverid, {message="hello there", from=self.ID})
end
And be received like this:
local function message(self, msg)
print("The id of the sender is: ", msg.Data.from) -- prints self.ID
print("The message is: ", msg.Data.message) -- print "hello there"
end
Client Messaging
Messages can be sent manually from the game engine Client to the game server, using a message function in the SDK. By default the player entity on the server will receive all client messages. The message
function of the player.lua
file handles these messages.
Messages can be sent from a game engine to a specific entity on the server using the direct message function in the SDK. (Direct Messaging is in Beta and not available for all SDKs).

Messages are sent to every client automatically every tick, syncing the clientside entities' Data fields with those of the serverside Entity. These updates are typically accessible from the clientside entity itself or the script maintaining the connection to the server.

Messages can be manually sent to a specific player's game engine client using api.client.Message()
. These messages are received by the SDK's server-to-client messaging function.

Entities and Chunks
Entities won't load game world chunks, by default. If an entity tries to move into an unloaded chunk, it will delay processing until the chunk is loaded. Players and Chunkloader entities are not required to wait and will automatically load the required chunk.
Entities can access the data for the chunk they are in, using the chunk
variable.
Example Cat Entity
Below is the example cat.lua
script which exists in the default template repository. The comments provide further information on what each line is doing.
-- cat.lua
-- init called on creation of entity
local function init(self)
-- set self.Chunkloader = true means this entity's chunk will always remain loaded
self.Chunkloader = true
-- self.Data is an arbitrary table, this is persisted, populated here with target coordinates
self.Data.target = { x = math.random(-64, 64), y = math.random(-64, 64) }
end
-- update called each simulation step, with dt being the number of seconds since last step (float)
local function update(self, dt)
-- position must be fetched using self:GetPosition method
x, y, _ = self:GetPosition()
-- calculate distance from target on x and y axis
local dx = self.Data.target.x - x
local dy = self.Data.target.y - y
-- if we're close enough then consider ourselves successful
if dx * dx < 4 and dy * dy < 4 then
self.Data.target = { x = math.random(-chunk.Size+1, chunk.Size*2-1), y = math.random(-chunk.Size, chunk.Size*2-1) }
else
-- determine largest direction of motion
if dx * dx > dy * dy then
dx = dx < 0 and -1 or 1
dy = 0
elseif dy * dy > dx * dx then
dy = dy < 0 and -1 or 1
dx = 0
else
dx = dx < 0 and -1 or 1
dy = dy < 0 and -1 or 1
end
-- self:Move(dx, dy, dz) moves relative to current position
-- by multiplying by dt we move at a constant speed regardless of performance
-- we also have self:MoveTo(x, y, z) which moves to an absolute position
-- note that z is left as 0 as this is a 2D game
self:Move(dx * dt, dy * dt, 0)
end
end
-- called when this entity receives a message
local function message(self, msg)
end
-- entity file must return table of this format
return { init = init, update = update, message = message }
Entity API
A number of API calls are available for certain entity-related actions such as spawning entities, they are accessed by interfacing with the api.entity
object in the global scope within all server-side scripts.
Entity
Fields
Chunkloader (Premium Only)
bool
If true, the chunk containing this entity will remain loaded even if no players are present.
Methods
Each of these methods takes the entity object self
as its first parameter. Hence you may use self:Move(dx, dy, dz)
instead of self.Move(self, dx, dy, dz)
.
None
x: float
y: float
z: float
Get the current position of the entity. Returns individual coordinates x, y, z.
dist: float
Entity[]
Get entities within the specified distance. Within a 3x3 grid of chunks around the entity.
dimension: string
x: float
y: float
z: float
None
Transport this entity to coordinates (x,y,z) in the dimension specified.
The x, y, and z fields are optional and default to 0.
Init
Update
Message
self: Entity
msg: table({
Data: table
Client: bool
)}
None
A necessary function, to receive messages to an entity.
Last updated