Solar2D and Corona SDK games — resource.car unpacked and its Lua decompiled back to source.
Every APK in the upload is searched for assets/resource.car, splits included.
The archive's index is read and every packed chunk is written out under its original module path.
Each chunk is standard Lua 5.1 bytecode and goes through the Lua decompiler. Anything it refuses is kept.
Upload the game's .apk or .xapk, or the resource.car on its own if you already have it. A normal APK decompiler shows you the Java that starts the Solar2D engine — a handful of generated classes. The entire game is Lua, compiled and packed into assets/resource.car, which no APK decompiler opens. The Java, resources and smali output is kept intact and a solar2d/ folder is added next to it.
A split bundle is fine. Store listings routinely split a game into a base APK plus per-architecture config splits. In the games measured here the resource.car is in the base APK while libcorona.so is only in config.arm64_v8a.apk, so neither file on its own identifies the game. Every split inside an XAPK is opened and searched.
solar2d/sources/ — the decompiled Lua, laid out in the project's original directory structure.solar2d/bytecode/ — chunks the decompiler could not reconstruct, kept as .luac rather than discarded.solar2d/README.txt — which archive was found, in which split, and how many chunks came back each way.resources/, sources/, smali/ — the normal Android output, untouched.A bare resource.car upload produces the same sources/ and bytecode/ pair with a DECOMPILATION-NOTES.txt beside them.
Solar2D compiles every .lua file in a project to bytecode and packs the results into one archive. It is a plain container: a short header, an index of name-and-offset records, then the payloads. Nothing is compressed and nothing is encrypted, which is why opening one needs no key and no external tool.
Files are stored under their module name rather than their path, so trials/trial_5_golems.lua is packed as trials.trial_5_golems.lu. The original directory tree is rebuilt from those names.
Each payload carries a 12-byte record header in front of it. Strip that and what is left is an ordinary Lua 5.1 chunk, signature and all — which is the single most useful thing to know about this format.
Corona and Solar2D bytecode is regularly assumed to be LuaJIT, and it is not. Every chunk across the shipped archives tested here begins with the standard Lua signature and a version byte of 5.1, compiled for 32-bit with 8-byte doubles. Solar2D's own repository vendors lua-5.1.3 and contains no LuaJIT at all.
This matters in practice: a LuaJIT decompiler will refuse these files outright, and a Lua 5.1 decompiler reads them. If you have been trying .lu files against a LuaJIT tool and getting nothing, that is why. Genuine LuaJIT bytecode belongs on the LuaJIT decompiler page instead, and standalone Lua chunks on the Lua decompiler.
L0_0 and upvalues as _UPVALUE0_.A single compiled Lua chunk as Solar2D names it inside resource.car. The name is the module path with dots for slashes, so scene.menu.lu was scene/menu.lua.
Yes. Corona SDK was renamed Solar2D when it became open source, and the archive format did not change — the 2016 builds tested here read exactly the same way as current ones.
No. Unlike Cocos, Solar2D does not encrypt its scripts. The archive is an index and a pile of bytes.
The APK contains lib/<abi>/libcorona.so, assets/resource.car, or both. In a split bundle they may be in different splits.
No, and it is a different format entirely. Assets.car is Apple's compiled asset catalog from an iOS app. For those, use the IPA decompiler.
Yes. A Windows or macOS Solar2D build keeps resource.car beside the executable; upload that file directly.