1. General idea
Jumpfall uses Lua for map scripts. This allows simple custom events without external loaders and without touching the game root folder.
The runtime uses MoonSharp embedded in Unity. Players do not need to install Lua on Windows, macOS or Linux.
.jsm file.
2. Important folders
| Folder | Use |
|---|---|
Documents\jumpfall\levels\assetslocal\lua | Local Lua scripts while creating a map. |
Documents\jumpfall\levels\assetslocal\sound | Local sounds used by scripts or soundtrack settings. |
Documents\jumpfall\levels\assetslocal\backgroundimg | Local PNG backgrounds used by the Level Editor. |
Documents\jumpfall\levels\workshop\{workshopid}\assetlocal\lua | Lua scripts installed from a Workshop map package. |
The default entry file is main.lua. If the compiled map does not include that file, the map loads without Lua.
If a map should not use Lua, its configuration can leave lua.enabled as false.
3. First script
Create this file:
Documents\jumpfall\levels\assetslocal\lua\main.lua
Basic example:
function on_level_start()
jf.log("Lua loaded in " .. jf.map_name)
end
function on_update(dt)
local pos = jf.player.position()
if pos.y < -20 then
jf.player.damage(999)
end
end
function on_trigger_enter(trigger_id, x, y)
jf.log("Touched trigger: " .. trigger_id)
if trigger_id == "finish_level" then
jf.level.finish()
end
end
Save the map, enter playtest with F5 and check the Unity console or the in-game dev console.
4. Available API
Events
| Function | When it runs |
|---|---|
on_level_start() | One frame after loading the map, when the player object should already exist. |
on_update(dt) | Every frame while the map is active. |
on_trigger_enter(trigger_id, x, y) | When the player enters a runtime trigger. In a lua_event trigger, the first value is the configured event name. |
on_trigger_enter_ex(event_name, raw_trigger_id, x, y) | Extended version that gives both the event name and the real trigger id. |
on_lua_event(event_name, x, y) | Only called when the player touches a lua_event trigger. |
lua_event trigger
A lua_event trigger does not change maps and does not finish the level. It only notifies the Lua script with the configured event name.
Place it from trigger mode with F6. To configure it, enable Object Edit with F4, select the trigger and press E.
function on_lua_event(event_name, x, y)
if event_name == "open_door" then
jf.log("Open a door from Lua")
end
end
General functions
| Function | Use |
|---|---|
jf.log(text) | Writes a message to the console. |
jf.time() | Returns Unity time. |
jf.dt() | Returns the last registered delta time. |
Simple variables
jf.vars.set("coins", 0)
jf.vars.add("coins", 1)
local coins = jf.vars.get("coins")
Only simple values should be stored: nil, booleans, numbers and text.
Player
| Function | Details |
|---|---|
jf.player.position() | Returns a table with x and y. |
jf.player.set_velocity(x, y) | Changes the Rigidbody2D velocity with internal limits. |
jf.player.add_force(x, y) | Applies a limited impulse. |
jf.player.damage(amount) | Damages the player. |
jf.player.heal(amount) | Heals the player. |
jf.player.set_gravity(value) | Changes player gravity between 0 and 12. |
jf.player.set_move_speed(value) | Changes base movement speed between 0 and 30. |
jf.player.set_jump_force(value) | Changes jump force between 0 and 60. |
Level
| Function | Details |
|---|---|
jf.level.finish() | In playtest, shows a finish message. At runtime, returns to Menugame. |
jf.level.change("map") | Loads a .jfue by name through the compiled map loader. |
Audio
function on_level_start()
jf.audio.play("bell.ogg", 0.8)
end
Sounds must be in assetlocal\sound and should use .wav or .ogg.
5. How Lua is included in a .jsm package
A Workshop map package should include the compiled playable map and the local assets it needs.
example.jsm
map.jfue
manifest.json
preview.png
assetlocal/
lua/main.lua
sound/
backgroundimg/
Do not publish the editable .jmap inside the .jsm. That file is for editing, not for public runtime loading.
6. Security and limits
- Lua runs in a restricted environment.
- Scripts should not read arbitrary files outside the map asset folders.
- Scripts should not start external programs.
- Keep events small and predictable.
- Avoid heavy loops in
on_update.
7. Testing and debugging
- Start with a small
main.lua. - Use
jf.log()to confirm that events run. - Test with
F5before compiling. - Use a
lua_eventtrigger for custom interactions. - Compile with
F8and test the compiled.jfue.
If nothing happens, check the file path, trigger name, event name and whether Lua is enabled for the map.