figured out the problem. somewhere in my 2000+ line main.lua (first corona project, it’s messy), there were calls to remove event listeners that came above when the functions were written. just written, there weren’t any calls to remove an event listener before it had been first “acknowledged”, and it had already been used in the game. it was just the writing order. seems like at the start of every frame and every “scan” of the code, a function has to be “rediscovered” in the order before it can be removed.
here’s a very simple code example of the problem:
-- moving state starts off as off local moving = false -- create a square in the top left local square = display.newRect( 0, 0, 100, 100 ) -- forward declare refresh. this is because touchsquare() at the top calls refresh(), but there may be things in refresh that call touchsquare, so it needs to be above local refresh -- when you touch the square, it reverses state. if reversing to false, remove the enterFrame listener for moving the square local function touchsquare(event) if ( event.phase == "began" ) then if(moving == false) then moving = true else moving = false Runtime:removeEventListener( "enterFrame", movesquare ) end refresh() end end -- add the event listener for this touching the square function square:addEventListener( "touch", touchsquare ) -- our enterframe function for moving the square local function movesquare() square.x = square.x + 1 end -- this is called when we touch the square. if moving has been turned to "true", we add the enterframe event listener function refresh() if(moving == true) then square.x = 0 Runtime:addEventListener( "enterFrame", movesquare ) end end -- this calls refresh at the very beginning, when the app first loads refresh()
note that each time you click on the square, it resets to x=0 but just keeps speeding up, because listeners are being duplicated for the enterFrame.
moving the “touchsquare” function below “refresh” fixes it. but thing is, there might be important things in touchsquare that means it has to above certain other functions (it might be a really complicated enterFrame itself). so it seems like the order could become impossible (even if you forward declare things, which is the usual solution)
kinda frustrated and struggling to make sense of this in my head, but maybe things will click into place just fine if i keep this in mind from the start with future projects
edit: even simpler demo-
local square = display.newRect( 0, 0, 100, 100 ) local function touchsquare(event) if ( event.phase == "began" ) then print("touching but not removing") Runtime:removeEventListener( "enterFrame", movesquare ) end end square:addEventListener( "touch", touchsquare ) local function movesquare() square.x = square.x + 1 end Runtime:addEventListener( "enterFrame", movesquare )