Skip to main content
RollingQuest includes a script editor built directly into the level editor. You do not need any external tools — you open the editor, write your Lua code, attach the script to a game entity, and play your level to see the result. This page walks you through the complete workflow, from opening the editor to running your first script.

What the script editor is

The script editor is a text editor embedded inside the RollingQuest level editor. It lets you write Lua scripts that hook into game events and control what happens at runtime. Each script you create is stored as a named file inside your level project and can be attached to one or more game entities.

The script-per-entity model

Every game entity in RollingQuest can have its own script:
  • Level — runs for the whole level (start, update, win, lose)
  • Blocks — individual cube blocks in the world
  • Sides — the faces of a block that a ball can roll across
  • Items — collectible objects in the level
  • Enemies — enemy entities
  • Balls — the player-controlled ball(s)
  • Decorations — visual decoration objects
Each entity’s script is a separate file identified by name. Attaching the same script name to multiple entities makes them all share the same code, which is useful for standardized behavior (for example, every moving block in a section could share one “move-and-bounce” script).
Scripts are not executed directly. The game reads them and calls specific hook functions you define inside them when corresponding events occur. If a hook function is not defined in your script, the game simply skips that event for that entity.

Writing and attaching a script

1

Open the level editor

Launch RollingQuest and open the level you want to work on in the level editor.
2

Open the script editor

Open the Script Editor by pressing the C key or from within the “Script” panel of any entity. Pressing the C key automatically opens the Script Editor with all the scripts contained in the level. If you open it from the “Script” section of any entity, you can also select which script you want to link to that entity.
3

Create a new script

In the script editor, create a new script file and give it a descriptive name such as level_intro or moving_block. The name identifies this script so you can attach it to entities and reference it with import, include, or require.
4

Write your hook functions

Type your Lua code into the editor. Define the hook functions you need. The example below is a Level script that shows a message when the level starts:
function OnStart(self)
  Dialog.createTemporary("Level started! Good luck.", 3)
end
5

Attach the script to an entity

Select the entity you want the script to run on (for example, the level itself). In its properties panel, find the Script field and enter the name of the script file you just created. Save your changes.
6

Play the level to test

Start the level in play mode. The game will call your hook functions automatically when their events occur. If something does not work as expected, use the Logger (see below) to print diagnostic information to the logs console.

Loading other scripts: import, include, and require

As your project grows, you will want to split shared code into separate script files and load them from other scripts. Three global functions handle this.

include(scriptName)

include loads the contents of another script directly into the current script’s environment, as if you had typed the code inline. Use it to bring in shared constants, utility functions, or helper tables.
-- loads everything defined in "utils" into this script
include("utils")

-- now any functions or variables defined in utils.lua are available here
local result = myUtilFunction(42)

import(scriptName)

import loads a script and returns its contents as a table. This is useful when you want to access definitions from another script without polluting the current script’s namespace.
local config = import("level_config")

-- access values defined in the level_config script
local maxTime = config.maxTime
local title   = config.levelTitle

require(scriptName)

require loads a script as a module. If the script returns a value (using return at the top level), require gives you that return value. Unlike include, the same script is only loaded once per session — subsequent require calls return the cached result.
-- in "constants.lua":
-- return { MAX_LIVES = 5, START_SCORE = 0 }

local constants = require("constants")
print(constants.MAX_LIVES)  -- 5
include("shared_helpers")

-- shared_helpers functions are now available directly
greetPlayer("Hero")

Debugging with the Logger

The Logger namespace lets you print messages to the in-game logs console while you are testing your level in the editor. Log messages do not appear during normal gameplay — Logger.isEnabled is true only in editor mode, so your logging calls are silently ignored in the final published level.

The four log levels

FunctionWhen to useConsole style
Logger.log(msg)General output; no special stylingDefault
Logger.info(msg)Informational messages about normal program flowStyled as information
Logger.warning(msg)Something unexpected happened but execution continuesYellow background
Logger.error(msg)A serious problem that needs your attentionRed background

Examples

function OnStart(self)
  Logger.info("Level started. Current lives: " .. tostring(Level.currentLives))
end

function OnBallRoll(self, rollIn, side, ball)
  if rollIn then
    Logger.log("Ball rolled onto block: " .. tostring(self.name))
  end
end

function OnDeath(self)
  Logger.warning("Ball died! Remaining lives: " .. tostring(Level.currentLives))
end
Wrap verbose logging in an if Logger.isEnabled then guard if you want to be explicit about it, though it is not strictly required since the Logger silently skips its work when disabled.
function OnUpdate(self, deltaTime)
  if Logger.isEnabled then
    Logger.log("Frame time: " .. tostring(deltaTime))
  end
end

Your first complete level script

Here is a finished example you can copy into a new script file and attach to your level entity. It prints a log message in the editor, shows a welcome dialog to the player, and logs another message when the level is won.
-- Script name: level_main
-- Attach to: the Level entity

function OnStart(self)
  Logger.info("OnStart called — level is beginning.")

  Dialog.createTemporary("Welcome! Collect all the keys to proceed.", 4)
end

function OnWon(self)
  Logger.info("OnWon called — player completed the level.")
end

function OnLost(self)
  Logger.warning("OnLost called — player failed the level.")
end
Attach this script to your level, enter play mode, and you will see the welcome dialog immediately on start. Switch to the editor logs console to see the Logger.info messages as each hook fires.
Ready to learn about hook functions in depth? Head to Hooks to see every event available for each entity type.