Why am I getting "Maximum call stack size exceeded" in my HTML5 build?

I was attempting to make a web build of my game to test controls, mainly multiple input in HTML 5. However, every time I have build the project to HTML 5 and attempt to play the game, it will get to the first loading screen and it will freeze. This error message appears in the console: Maximum call stack size exceeded, RangeError: Maximum call stack size exceeded.

Here’s a screenshot of what I get:

Here’s a text version of all of it:

exception thrown: RangeError: Maximum call stack size exceeded,RangeError: Maximum call stack size exceeded
    at <anonymous>:wasm-function[349]:0x4299
    at <anonymous>:wasm-function[1401]:0x652cc
    at <anonymous>:wasm-function[517]:0xf037
    at <anonymous>:wasm-function[1151]:0x4abf7
    at <anonymous>:wasm-function[1394]:0x6480c
    at <anonymous>:wasm-function[1431]:0x68c87
    at <anonymous>:wasm-function[757]:0x2185c
    at <anonymous>:wasm-function[394]:0x7ab7
    at <anonymous>:wasm-function[413]:0x86fc
    at <anonymous>:wasm-function[702]:0x1ccce

My game builds fine within the Defold editor and I’ve not encountered this sort of error with other projects. My end goal is to have this project on HTML 5 and mobile, so I really need to get it to work.

The specific behavior I am attempting to do is asyn load a level that is rather large, I don’t know of any way to break it up smaller without harming gameplay.

I’ve looked through the project settings but haven’t found anything that looks like it may address this.

What can I do to my project to fix this error?

Async load how? A collection proxy?

It sounds like some kind of recursive function calling itself many times.

Yes, I am using a collection proxy.

I’ll look into this, I don’t believe I have anything recursive in my code, however, wouldn’t this sort of thing pop up in the editor and give me the same error?

Thanks for the quick reply!

I agree that it would probably show up when launching for other platforms (e.g. on desktop via the editor).

Looking at the callstack you posted, it keeps referring to “requestAnimationFrame” over and over, which is seems like a recursive call stuck in a loop (which might cause a callstack size exceeded).

Apart from that, I’m not sure why it would behave this way.

Which Defold editor/engine are you using?

I’m thinking that this might somehow be a weird discrepancy between Lua 5.1 and LuaJIT. Stick this bit of code into the first script that is loaded in your project:

local function print_debug_info()
	local info = debug.getinfo(2, "nlS")
	print(("Executing %s on line %d of file %s"):format(info.name or "code", info.currentline, info.source))
end

function init(self)
	debug.sethook(print_debug_info, "cl")
end

This will print every line of code that gets executed. That may help pinpoint if there’s loop somewhere.

I’m using version 1.2.178

I was able to add this code and found that it is not uniform in where it happens. Sometimes it will stop after loading in a script, this happens while the collection proxy is being loaded in. Sometimes it will stop between update functions, it could be after the camera or any number of other update functions that exist in my code. Sometimes it will happen after executing an input function.

The only thing uniform about where it stops is that it is always during the collection proxy loading in.

I tried swapping from “async_load” to “load” with the collection proxy and got it to only happen while loading in scripts from the proxy.

I made a build for windows and it also crashes when I try to load levels.

Can you share a project where this happens?

The files or the web / .exe build?

The project files. You can send them in an email (bjorn@defold.se)

I was able to duplicate what’s happening in another project that I have shared here.

This project is much smaller (the other one was over 350 MB because of art and music). That being said, I also had to take out the music components in order to get it small enough to share on here. I copied over the code from the main project that has been causing me problems. The components all work fine in the main project but are not connected here to illustrate the problem.

When you build to HTML 5 and hit play, it throws the error while building in the editor does not. Here it is:
rpg_template.zip (5.4 MB)

2 Likes

Thanks. I’ve isolated this down to a single collection with a script and a Lua module. It had very little to do with your code in general, BUT our code parser incorrectly parsed a block comment wrong which actually caused an infinite require cycle. This was handled by LuaJIT but unfortunately not Lua 5.1 (which we use in HTML5). The problem was this comment in formatDialogWithPlayerInfo.lua:

--[[
To use:
require("main.usefullCode.formatDialogWithPlayerInfo")
call FORMAT_DIALOG_WITH_PLAYER_INFO(dialog) with whatever is needed
]]--

When we bundle an application we strip all comments from the Lua files to reduce their size and in this case we didn’t parse the block comment properly. In Lua a block comment is defined as:

“Lua also offers block comments, which start with --[[ and run until the corresponding ]]”

Source: https://www.lua.org/pil/1.3.html

The page then goes on to describe a common trick which allows you to quickly toggle block comments when they are written like this:

--[[
print("hello")
--]]

Note the --]] in the example vs the ]]-- you had in your code. Our parser does not handle your block comment style (which is syntactically correct btw but not in the format recommended by Lua).

I will fix this in our parser and in the meantime you can solve it yourself by either fixing your comment, removing it or avoid putting the require() in the comment first on a blank line.

4 Likes

Thank you! I will avoid doing that in the future! I really appreciate all of your help!