Cocos2d-x simulator and on-device debugging with ZeroBrane Studio

There has been recent interest in getting ZeroBrane Studio to work with Cocos2d-x, so I decided to put my notes together on how this can be accomplished.

Debugging with ZeroBrane Studio requires using luasocket and because it can be integrated with a Cocos2d-x project in different ways, you may have several options to consider.

Debugging using luasocket as an external library.

This option uses luasocket dll/dylib/so library that comes with ZeroBrane Studio. This is probably the easiest way to get the debugging working, but it won't work when your application is running in the Android/iOS simulator or on the device. Still, since it's easy to setup, let's review the steps.

First, take HelloLua demo and compile HelloLua executable (this is all on Windows, but this should work on other platforms as well).

Add a call to the debugger to hello.lua file (see the code below):

local function main()
    ...
    cclog("debugging...")
    require('mobdebug').start() --<-- this line
    require "hello2"
    cclog("result is " .. myadd(3, 5))

Next, follow the instructions on remote debugging (especially Setup Environment for Debugging section). I just have a simple batch file that sets LUA_PATH and LUA_CPATH such that they point to lualibs/mobdebug/mobdebug.lua and bin/clibs/?.dll files so that socket and mobdebug modules are properly loaded from ZBS. The last line simply runs HelloLua.exe.

Now open ZeroBrane Studio and load hello.lua file in the editor. Set the project directory to the folder where you have hello.lua. Start debugger server by going to Project | Start Debugger Server; (these are all instructions from the page referenced earlier).

If you run the batch file now, you should get an error that it can't find lua51.dll. luasocket needs it and it's in ZBS/bin folder. You can either add that folder to PATH or copy the dll to the folder with your executable.

Run it again and you should see the green arrow pointing to the instruction next to the start() call and you should be able to debug your application and use the stack view, breakpoints, and other debugger features.

iOS simulator and on-device debugging with integrated luasocket (instructions courtesy of Andres Ispani).

The last project I worked on was an iOS only project based on cocos2d. For our next project, we were searching for something cross platform that would also allow us to iterate faster. There are many frameworks out there that promise this (you can code in JavaScript, C#, Lua, etc), but we chose Cocos2d-x because it's open source and it allows us to have greater control of what is happening behind the scenes. We can code most of our game in javascript or lua, and still tweak any rough edges in c++. Also being able to use our previous experience with Cocos2d didn't hurt.

I would not start any serious long term project without a working debugger though, so I started looking at ways to debug lua code running on an iPhone, and I found ZeroBrane. All you need is getting luasocket running in cocos2d-x. I found this old forum post explaining how to do it. Unfortunately it's really old. You are supposed to get the luasocket implementation from a github cocos2d-x fork, but the repo has since deleted luasocket support. So I looked through github history looking for the revision mentioned in the post. Then I followed this modified steps from the forum thread:

  • Download that revision of cocos2d-x.
  • Copy it's lua/exts folder to your project's libs folder, and add them to your XCode target. Remove wsocket.c from your target.
  • Open libs/lua/cocos2dx_support/CCLuaStack.cpp and add this include:
extern "C" {
  #include "lualoadexts.h"
}
  • At the end of bool CCLuaStack::init(void) add:
luax_loadexts(m_state);

Then, copy mobdebug.lua to the Resources folder, add require('mobdebug').start("IDE.machine.ip.address") to the main lua file, and now you can debug lua from either the iOS simulator or an actual device in the same network.

Android simulator and on-device debugging with integrated luasocket (instructions courtesy of Peter Yiap, slightly updated).

I managed to find a working luasockets integration from the DualFace github:

  • Download dualface/quick-cocos2d-x.
  • Copy over the luasockets source into cocos2d-x-2.1.4\scripting\lua\lua_extensions and integrate it into the liblua project. You will need to use lua_extensions.c and lua_extensions.h included below.
  • Add luaopen_lua_extensions(m_state); to CCLuaStack::init(). I added it below toluafix_open(m_state);
  • Within the HelloLua test project, link against the Ws2_32.lib file since luasocket had a dependency on winsock on the win32 platform. The other platforms were fine. Add the new luasocket files to the cocos2d-x-2.1.4\scripting\lua\proj.android\Android.mk file.

I use Cygwin on my PC to do android builds; use this tutorial to get your environment. Once the ndk stuff is all setup you should just be able to navigate to cocos2d-x-2.1.4\samples\Lua\HelloLua\proj.android and execute build_native.sh script. When that's compiled you'll need to create the eclipse project and publish to the device.

// ----- lua_extensions.h -----

#ifndef __LUA_EXTRA_H_
#define __LUA_EXTRA_H_

#if defined(_USRDLL)
    #define LUA_EXTENSIONS_DLL     __declspec(dllexport)
#else         /* use a DLL library */
    #define LUA_EXTENSIONS_DLL
#endif

#if __cplusplus
extern "C" {
#endif

#include "lauxlib.h"

void LUA_EXTENSIONS_DLL luaopen_lua_extensions(lua_State *L);
    
#if __cplusplus
}
#endif

#endif /* __LUA_EXTRA_H_ */
// ----- lua_extensions.c -----

#include "lua_extensions.h"

#if __cplusplus
extern "C" {
#endif

// socket
#include "luasocket.h"
#include "mime.h"

static luaL_Reg luax_exts[] = {
    {"socket.core", luaopen_socket_core},
    {"mime.core", luaopen_mime_core},

    {NULL, NULL}
};

#include "tolua_fix.h"

void luaopen_lua_extensions(lua_State *L)
{
    luaL_Reg* lib = luax_exts;
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "preload");
    for (; lib->func; lib++)
    {
        lua_pushcfunction(L, lib->func);
        lua_setfield(L, -2, lib->name);
    }
    lua_pop(L, 2);

    // load extensions script
    luaopen_socket_scripts(L);
}

#if __cplusplus
} // extern "C"
#endif

Note on debugging in the iOS simulator.

As Lua files included with your application are copied to a different location when the application is packaged to run in the simulator, the debugging may be triggered for files in the packaged application, rather than in your project folder. This may affect some of the debugging features as the breakpoints you toggle in the IDE are set on files in your project folder, not on files in the packaged application.

The current version of ZeroBrane Studio in the repository starts debugging using the project files, but earlier versions of ZBS (v0.38 and before) may use files in the packaged application (which is likely to break breakpoints).

When this remapping is active (this should work in v0.39 and later), you may see a message similar to the one below in the Output window:

Mapped remote request for '/users/..../library/application support/iphone simulator/6.1/applications/13e34ef7-594a-4d62-a2c7-9451d726275c/luatest2.app/' to '/Users/..../Documents/Projects/LuaTest2/LuaTest2/Resources/'.

You should get a copy of my slick ZeroBrane Studio IDE.

10 Comments

Hi Paul , I set my enviroment with your guide in my ios app. But my app exit without any log when my script run "require('mobdebug').start()"

i use "iOS simulator and on-device debugging with integrated luasocket (instructions courtesy of Andres Ispani)." can you help ?

Hi paul, how can i use zerobrane debug original ios app by cocos2d-x ? i configured my ios app accroding to this article, but the ios simulator can't run, how can i debug my ios app by zerobrane ?

Hi paul , how can id debug my ios app by zerobrane ? I configured my ios app by this article, but the simulator can't be launched by zerobrane, i must start it from xcode. What's the process to debug orignal ios app by using zerobrane ? Can u help me ,Great thx!

Hi paul , how can id debug my ios app by zerobrane ? I configured my ios app by this article, but the simulator can't be launched by zerobrane, i must start it from xcode. What's the process to debug orignal ios app by using zerobrane ? Can u help me ,Great thx!

Tks paul, i have fix this problem. i should set my zerobrane project path to the ios app directory.

Hi Ryan, glad you resolved the issue. For others who may want to follow the discussion, the thread is here.

hi, i want use zeroBrane to debug my cocos2d-x games. but it can not recognize some cocos2d objects. like cc.Scene etc. Could i configure something to fixed that?

Does it work with cocos2d 3.7 on linux?

I would try to "live coding", but it did not work :( Also in the text http://studio.zerobrane.com/doc-remote-debugging.html there is an error:

export LUA_CPATH = "$ ZBS / bin / linux / x86 / ?. dll; $ ZBS / bin / linux / x86 / clibs / ?. dll"

in linux should be a ".so" extensions. And library files are not the same as in windows (I do not know whether it is correct)

@mmm, yes, I expect it to work with cocos2d 3.7, but I haven't tested it. I updated the instructions on the remote debugging page; thank you for the report.

Hi, about 'remapping', only those lua files in app director can be mapped? I want to mapped writeable path to my LUA folder. And now I set my LUA folder as current director, but when I start app, it doesn't show "Mapped remote" information. And I can not debug my LUA files. So what should I do?

Leave a comment

what will you say?
(required)
(required)
Close