The Real Escape Canada
Embedding Lua in an Escape Room Engine
A scripting layer that made it possible to build, test, and adjust escape room puzzles without recompiling the underlying engine.
Bring me to the demo!Overview
Shortening the Development Cycle
Certain features in an escape room (such as the puzzles or environment) often need to be adjusted repeatedly during development. The engine I was given was written purely in C++, and any changes (no matter how small) required full recompilation. Requiring recompilation for every change caused the design loop to be slower than it needed to be.
I designed and implemented an embedded Lua integration that moved puzzle and room behavior into scripts the engine could load and execute at runtime.
The scripting workflow eliminated the need to recompile the engine for routine puzzle changes and reduced overall room development time. It also allows for concurrent development as puzzle and room environment logic can be programmed and tested without the needing full engine and hardware. This allowed for the use of development tools that simulated this behaviour.
This Lua integration allowed for faster design, programming, and testing, dramatically increasing iteration while keeping the engine responsible for lower level room functions and hardware control.
The Technicals
Lua & C++,
partners inline
Lua is a lightweight language designed to be embedded in other programs. This is due to it's small runtime footprint and C API, making it a practical way to add scripting behaviour on top of an existing program.
The C++ engine creates and owns the Lua virtual machine. I used the sol3 framework to wrap Lua's C API and register the functions and values that scripts need. The engine can call a script, pass in room state, and read the result without exposing the underlying hardware implementation.
Lua handles the high-level puzzle and room behaviour, while C++ remains responsible for resource management, performance-sensitive systems, and hardware control. Because the scripts are loaded at runtime, changing a puzzle entails editing a script and reloading it, rather than rebuilding the entire engine.
My favourite examples of Lua in Games (and hardware)

Hades
Hades runs on a rewrite of its old C# game engine. This new engine is C++ based and built on The Forge framework. That made it possible to embed Lua, allowing Lua scripts to describe gameplay logic, environment layout, encounters, and dialogue.
The Forge FrameworkInteractive runtime prototype
Real puzzles you can try!
The demos below are puzzles written in Lua, akin to the ones written for the escape rooms I worked on. These Lua scripts are interfaced with a C++ engine that handles the creation and management of the Lua Virtual Machine.
By clicking the Watch Code button, you can slow down execution and watch each line of the script being ran.
Each demo runs a Lua puzzle script through the C++ runtime. The runtime handles the puzzle logic and state, while the Javascript game framework Phaser renders that state in the browser. Button input is sent to Lua, and the resulting state is passed back to Phaser to draw.
The following demos are inspired by puzzles I made for The Real Escape Canada's Train Robbery room .
Live Demo