General notes
- Disable other Lua debugger extensions before using LuaDebug.
- Start the editor debugger first, then the game.
- Copy runtime files from the extension
luadebugfolder into a require-able path. - Use
LuaDebugjit.luafor LuaJIT;LuaDebug.luafor PUC-Rio Lua.
Cocos (Creator / cocos2d-x Lua · 2.x / 3.x)
Preparation
- Copy
LuaDebug.luaorLuaDebugjit.luainto your script tree. - Require early in the entry script (e.g.
main.lua) and hook the callback to the scheduler:
local breakSocketHandle, debugXpCall = require("LuaDebugjit")("127.0.0.1", 7003)
cc.Director:getInstance():getScheduler():scheduleScriptFunc(breakSocketHandle, 0.3, false)
Add a debug configuration
- No launch.json → create and pick LuaDebug.
- Existing → Add Configuration… →
LuaDebug: Cocos2-launch(macOS) orLuaDebug: Cocos2-launch (Windows); for remote attach useLuaDebug: Cocos remote.
Local launch example (macOS)
{
"name": "Cocos2-launch",
"type": "lua",
"request": "launch",
"runtimeType": "Cocos2",
"localRoot": "${workspaceFolder}",
"commandLine": "-workdir ${workspaceFolder}/.. -writable-path ${userHome}/Documents -console enable -write-debug-log ${userHome}/Documents/cocos_debug.log -file src/main.lua",
"port": 7003,
"exePath": "${workspaceFolder}/../runtime/mac/your-player.app/Contents/MacOS/your-player",
"fileExtNames": [".lua", ".txt", ".lua.txt", ".bytes"],
"printType": 1
}
The snippet pre-fills localRoot, commandLine, writable-path, and other common options. Usually you only change exePath: replace your-player with your player name and align the path with your runtime/ layout.
On Windows set exePath to ${workspaceFolder}/../runtime/win32/your-player.exe. If the entry script is not src/main.lua, change -file in commandLine; if the project root is not the parent of the workspace folder, adjust -workdir.
localRoot is the Lua workspace root (the folder you open in the editor) for stack path mapping — not the same as -workdir.
Remote / device attach example
{
"name": "COCOS(remote debugging)",
"type": "lua",
"request": "attach",
"runtimeType": "Cocos2",
"localRoot": "${workspaceFolder}",
"port": 7003,
"fileExtNames": [".lua", ".txt", ".lua.txt", ".bytes"],
"printType": 1
}
StartDebug host on device: use 127.0.0.1 on the same machine; use your PC's LAN IP on a real device. If you see module 'socket.core' not found, see FAQ.
Common Cocos commandLine flags
commandLine in launch is passed to the simulator. Common flags:
| Flag | Meaning |
|---|---|
-workdir | Project directory (same as Open Project → Project Directory) |
-file | Entry script; may be ignored on Cocos 4.0+, see below |
-writable / -writable-path | device.writablePath; defaults to project dir if omitted |
-package.path | Extra Lua module paths, separated by ; |
-size | Screen size, e.g. 1280x720 |
-scale | Scale factor, e.g. 0.5 |
-console / -disable-console | Show console; e.g. -console enable |
-write-debug-log / -disable-write-debug-log | Write debug.log; optional path, e.g. -write-debug-log /path/to/cocos_debug.log |
Cocos 4.0 notes
Cocos 4.0 changed CLI behavior: -file may no longer work. Follow official 4.x launch docs and ensure the entry script still loads the debugger.
Tip: open only your script folder (e.g. src) and keep launch.json there.
local breakSocketHandle, debugXpCall = require("LuaDebugjit")("127.0.0.1", 7003)
cc.Director:getInstance():getScheduler():scheduleScriptFunc(breakSocketHandle, 0.3, false)
Unity · xLua
DoString / AddLoader
With luaEnv.DoString, the second argument (chunkname) must be the real file path/name. If chunkname includes .txt and breaks mapping, try dropping the suffix. Custom AddLoader must also expose mappable chunk names.
Wire up debugging
- Copy runtime files into the Lua script folder.
- Require and StartDebug in Lua startup.
- Launch with
LuaDebug: Unity-xlua, runtimeType Unity.
{
"version": "0.2.0",
"configurations": [
{
"name": "Unity-xlua",
"type": "lua",
"request": "attach",
"runtimeType": "Unity",
"localRoot": "${workspaceFolder}",
"port": 7003,
"fileExtNames": [".lua", ".txt", ".lua.txt", ".bytes"],
"printType": 1
}
]
}
Order: editor F5 → run Unity until StartDebug runs. Set "luadebug.apiType": "xlua" for API hints (unrelated to breakpoints).
Unity · sLua
Older sLua (before ~1.5.1) may lack LuaSocket — integrate socket first.
- Copy runtime files and StartDebug in Lua startup.
- Launch with
LuaDebug: Unity-slua. - Ensure runtime scripts match editor sources (watch AssetBundles).
{
"name": "Unity-slua",
"type": "lua",
"request": "attach",
"runtimeType": "Unity",
"localRoot": "${workspaceFolder}",
"fileExtNames": [".lua", ".txt", ".lua.txt", ".bytes"],
"port": 7003,
"printType": 1
}
Unity · uLua / toLua
- Copy the matching runtime into the Lua folder.
- Require + StartDebug in startup Lua.
- Launch with Unity-ulua; toLua also uses runtimeType Unity — point localRoot at scripts.
- Custom loader / DoFile chunknames must map to real paths.
{
"name": "Unity-ulua",
"type": "lua",
"request": "attach",
"runtimeType": "Unity",
"localRoot": "${workspaceFolder}",
"fileExtNames": [".lua", ".txt", ".lua.txt", ".bytes"],
"port": 7003,
"printType": 1
}
Suggested order: breakpoints + editor debug → run Unity → confirm hits.
OpenResty
- Open the project; script root may be
src(any name). - Copy OpenResty / JIT runtime files and StartDebug during init.
- Add
LuaDebug: OpenRestyto launch.json. - Mind worker processes: enable only where needed and open the port.
{
"name": "OpenResty",
"type": "lua",
"request": "attach",
"runtimeType": "OpenResty",
"localRoot": "${workspaceFolder}",
"port": 7003,
"fileExtNames": [".lua"],
"printType": 1
}
Standalone (non-Cocos / non-Unity)
Any runtime that loads Lua with LuaSocket can call StartDebug at entry. Use attach and set localRoot to the script root.
Real-device debugging
- Phone and PC on the same LAN.
- StartDebug host = PC LAN IP (not 127.0.0.1).
- Port matches launch; allow through firewall.
- Editor F5 first, then launch the app on the device.
loxodon-framework-xlua
If breakpoints never bind, check:
- DoString / loader chunkname is a real path;
- Runtime loads packed bytecode / AB out of sync with editor sources;
localRootpoints at where the framework keeps Lua.
Hook StartDebug where Lua text actually runs; chunkname must be mappable.