Event Systems in Roblox Lua (Part 1 – The Problem)

Hey everyone. Lately I’ve been considering the many ways to create event systems for Roblox Lua. You may already be familiar with native events, a.k.a. RBXScriptSignal, in Roblox. You connect your function to one of these, and when the engine detects the occurrence, it calls your function with the relevant arguments. BasePart.Touched is one of the most common examples.

But what if you’re making your own objects, like in my object-oriented programming tutorial? If your custom objects want to define events, you have a ton of different options for implementing this pattern. In this tutorial series, I will explore the different methods you can use to implement an event-listener pattern.

Before we look at the different ways we could create a system like this, let’s define exactly what we’re trying to code up. We want to be able to create an event and connect any number of functions to it. In addition, we want to send arguments to the connected functions when this event is fired. Finally, we need to be able to disconnect a connected function from this event. So, no matter what systems we end up making, we should be able to do something like this (for example, in a round-based game):

local function announceGameOver(finalScore)
	print("Game over!")
	local message = Instance.new("Message")
	message.Text = "Game over! Your score: " .. finalScore
	message.Parent = workspace
	wait(2)
	message:Destroy()
end

local function cleanUpTheGame()
	-- Destroy the map if we have one
	if workspace:FindFirstChild("Map") then
		workspace.Map:Destroy()
	end
	-- Clean up any debris on the ground
	while workspace:FindFirstChild("Debris") do
		workspace.Debris:Destroy()
	end
end

local onGameOver = Event.new()
onGameOver:connect(announceGameOver)
onGameOver:connect(cleanUpTheGame)

-- ...somewhere else in your code...
onGameOver:fire(69)

A couple things to note:

  • It ought not matter in which order our functions announceGameOver and cleanUpTheGame will run; in a perfect world we’d have them happen at the same time. (In reality, one will always happen before the other and it’s the order in which we connect these functions that may ultimately play a part in what order they are actually called.)
  • Not all connected functions will need to use all the arguments sent by the event, such as cleanUpTheGame  not needing the final score we sent.
  • Not all connected functions will need to stay connected – we might need to disconnect functions as a cleanup measure.
  • For brevity, I will be skipping over writing a wait method to yield until an event is fired.

With those things in mind, let’s see the different ways we can make event systems in Roblox Lua!

Click here to proceed to part 2 of this tutorial series.

Author: Ozzypig

Roblox developer and computer scientist. I love all things coding and game design!