Problem with module after loading the same scene a second time

I have a problem where I cannot reload a scene, I have tried an intermediate scene but nothing, I don’t know what I’m doing wrong.

Game.lua loads a module called character.lua that creates a ragdoll, when the ragdoll falls out of the screen there is a Game Over and 2 buttons appear with “retry” and “quit”. Everytime I retry or quit and select play from the main menu, the game crashes with:

character.lua:612: attempt to perform arithmetic on field 'y' (a nil value)
stack traceback:
character.lua:612: in function 'getHead'
game.lua:156: in function 'func'
D:\a\corona\corona\platform\resources\init.lua:202: in function
<D:\a\corona\corona\platform\resources\init.lua:189>

Where the error comes from:

function R.getHead()
	local headPos = head.y -70
	return headPos
	
end

This does not give any errors on a fresh start.

Here is the game.lua part where getHead is called:

local function retryGame(event)
	Runtime:removeEventListener("enterFrame", gameover)
	composer.removeScene("game")
	composer.gotoScene( "intermediateScreen")

end

local function quitGame(event)
	Runtime:removeEventListener("enterFrame", gameover)
	composer.removeScene("game")
	composer.gotoScene( "titlescreen"  )

end

local function gameover(event)
	print(ragdoll.getHead())
	local y = ragdoll.getHead()
	if y > display.actualContentHeight then
		ragdoll.gameover()
		speed = 0.01

		local gameTransition = transition.to(game,{delay=500, time = 200, x= display.contentCenterX-250, transition= easing.outBounce})
		local overTransition = transition.to(over,{delay=500, time = 200, x= display.contentCenterX+250, transition= easing.outBounce})
		local retryTransition = transition.to(retry,{delay=500, time = 200, x= game.x+100, transition= easing.outBounce})
		local quitTransition = transition.to(quit,{delay=500, time = 200, x= over.x-100, transition= easing.outBounce})
		
		Runtime:removeEventListener( "axis", controlUnstuck)
		Runtime:removeEventListener( "key", selectLimb)
		Runtime:removeEventListener( "axis", move)
		Runtime:removeEventListener("enterFrame", heightIncrease)

		retry:addEventListener( "tap", retryGame )
		quit:addEventListener( "tap", quitGame )

		

	end

end

The ragdoll is inserted into a sceneGroup which gets destroyed in scene:destroy or am I using it wrong?
What can I do to reload my scene correctly as if it were a new scene?

Sorry for possible bad formatting, I am really new with lua and Solar2D, if there is the need for more code I will post more.
Thanks!

That error means that the table has been cleaned and there’s no y property in it anymore.

Given that the error occurs in the module, it would make sense to share more of the module’s code. In this case, however, the error may be caused by a simple misunderstanding.

When you require a module, it will be added to _G.package.loaded. The next time that you require the same module, it will be just loaded from there. Any and all changes that you’ve made within the module will be remembered and the code inside it will not be run again unless you first set the module to nil and remove references to it.

If you are creating head outside of the functions, this code would not run again when you re-require the module, which would explain that crash.

game.lua scene:create where I create the ragdoll

function scene:create(event)
	local sceneGroup = self.view

game = display.newImageRect("img/game.png",434,127 )
go:insert( game )

over = display.newImageRect("img/over.png",411,128)
go:insert(over)

retry = display.newImageRect("img/retry.png",284,68)
go:insert(retry)

quit = display.newImageRect("img/quit.png",203,81)
go:insert(quit)

--create the initial mountain and floor
foreground:insert(ragdoll.createRock())

--the character ragdoll is created and inserted into the foreground group
foreground:insert(ragdoll.createCharacter(display.contentCenterX-250,display.contentCenterY-220))

sceneGroup:insert(foreground)
sceneGroup:insert(go)

end

game.lua where I add the listener for the game over:

function scene:show(event)
	local sceneGroup =self.view
	local phase = event.phase

	if phase == "will" then
		game.x = -game.width
		game.y = 600

		over.x =display.contentWidth+over.width
		over.y = game.y

		retry.x = game.x 
		retry.y = game.y+200

		quit.x = over.x
		quit.y = retry.y 


	elseif phase =="did" then

		ragdoll.activatePhysics()
		ragdoll.setupGame()

		Runtime:addEventListener("enterFrame", heightIncrease)
		Runtime:addEventListener("enterFrame", gameover)
	end
end

character module where head is involved

function R.createCharacter(posX,posY)
--create new group 
local ragdoll = display.newGroup()

body = display.newImageRect("img/body.png",77,212)--77, 212
body.x = posX
body.y = posY
ragdoll:insert(body)
physics.addBody( body, "dynamic", {filter = bodyFilter,friction = 0.9, density= 0.2} )

head = display.newImageRect("img/head.png", 150,135 )
head.anchorY = 1
head.x = body.x-25
head.y = body.y-body.height/2
ragdoll:insert(head)
physics.addBody(head, "dynamic", {radius = 150, filter=headFilter})

--joint section-----------------------------------------------------------------------------------------

neck = physics.newJoint("pivot", head, body , head.x , head.y)
neck.isLimitEnabled = true 
neck:setRotationLimits( -20, 20)


return ragdoll

end --end createCharacter

I omitted some code but basically createCharacter creates every part of the body plus the joints to connect them, getHead gets the y pos of the head and returns it to game.lua to calculate if the player is off the screen and starts the game over.

I tried:

local function retryGame(event)
	Runtime:removeEventListener("enterFrame", gameover)
	package.loaded["character"] = nil
	composer.removeScene("game")
	composer.gotoScene( "intermediateScreen")

end

local function quitGame(event)
	Runtime:removeEventListener("enterFrame", gameover)
	package.loaded["character"] = nil
	composer.removeScene("game")
	composer.gotoScene( "titlescreen"  )

end

But the same problem arises. Maybe I’m still doing it wrong

Well, that’s not the entire module’s code.

Also, based on that code, head, body and neck are global variables, so you may run into issues with those as well.

This is likely a simple issue, but I think you’d need to provide a small sample project that demonstrates the issue and then someone will have an easier time helping you. Currently you are just showing bits and pieces that are or aren’t related to the issue, while also omitting code that relates to the issue.

The entire module code:

--create  Ragdoll class
local R ={}
--define name of class
R.name ="character"
--start physics and immediatly pause them
local physics = require("physics")
physics.setDrawMode("normal")
physics.start()
physics.setContinuous("enabled")
physics.setReportCollisionsInContentCoordinates( true)
physics.pause()
--boolean variable used to check if a collision has happened
physicsWorldChange = false



--define the filters for collisions
local headFilter = {categoryBits = 1 , maskBits=384}
local bodyFilter =	{ categoryBits=2, maskBits= 448}
local armFilter = {categoryBits=4, maskBits=392}
local legFilter = {categoryBits = 8, maskBits=356}
local footFilter = {categoryBits=16, maskBits=354}
local pickaxeFilter = {categoryBits=32 ,maskBits=408}
local pickaxeTipFilter = {categoryBits=64, maskBits=410}
local footPicksFilter = {categoryBits=128, maskBits=359}
local rockFilter = {categoryBits=256, maskBits=255}

local floor

--create global variables for every limb
local body
local armUpRight
local armDownRight
local axeR
local tipR
local armUpLeft
local armDownLeft
local axeL
local tipL
local head
local legUpLeft
local legDownLeft
local footL
local legUpRight
local legDownRight
local footR
local nailL
local nailLtip
local nailR
local nailRtip



--create global variables for joints
local Rshoulder
local Relbow
local Lshoulder
local Lelbow
local neck
local Rhip
local Rknee 
local Lhip
local Lknee
local footLJoint
local footToPickL
local picktipL
local footRJoint
local footToPickR
local picktipR
local axeTipL
local axeTipR
local holdRAxe
local holdLAxe
local Rhit
local Rhit2
local Lhit
local Lhit2
local Lfoothit
local Lfoothit2
local Rfoothit
local Rfoothit2


local controlJoint
local leftControl = 0
local rightControl = 0
local gamestarted = 0



--global variable for selected limb
local selectedLimb = "left arm"
local tipDir
local tipDirX
local tipDirY
local indexNum


--global variables 
local leftTipCollision 
local rightTipCollision
--create table to insert rocks to climb on
local rockList = {}
local speed = 2.01

--class for creation of ragdoll character where all limbs and joints are generated 
function R.createCharacter(posX,posY)
--create new group 
local ragdoll = display.newGroup()

--local bodyOutline = graphics.newOutline(20,"img/body.png",200,100)

floor = display.newRect(0,0,1080,2100)
floor.anchorX = 0
floor.anchorY = 0
floor.x = 0
floor.y = display.contentCenterY+250
floor:setFillColor( 0,0.5,0 )
ragdoll:insert(floor)
physics.addBody(floor, "static", {bounce = 0, friction = 1, filter = rockFilter})

body = display.newImageRect("img/body.png",77,212)--77, 212
body.x = posX
body.y = posY
ragdoll:insert(body)
physics.addBody( body, "dynamic", {filter = bodyFilter,friction = 0.9, density= 0.2} )

armUpRight = display.newImageRect("img/FrontUpperRightV2.png",50,188)
armUpRight.anchorY = 0
armUpRight.x = body.x
armUpRight.y = body.y-body.height/2
ragdoll:insert(armUpRight)
physics.addBody( armUpRight, "dynamic" ,{filter=armFilter,density= 0.2})


--Rshoulder.isLimitEnabled = true

armDownRight = display.newImageRect("img/FrontRightV2.png",50,188)
armDownRight.anchorY = 0
armDownRight.x =armUpRight.x
armDownRight.y = armUpRight.y+armUpRight.height
ragdoll:insert(armDownRight)
physics.addBody( armDownRight, "dynamic",{filter=armFilter} )


local axeOutline = graphics.newOutline(2,"img/axe.png")
axeR = display.newImageRect ("img/axe.png",100,175)
axeR.x = armDownRight.x +30
axeR.y = armDownRight.y+armDownRight.height+40 
--axeR:rotate(120)
axeR:toBack( ) 
body:toBack( )
ragdoll:insert(axeR)
physics.addBody( axeR ,"dynamic",{outline = axeOutline, filter=pickaxeFilter})

local axeTipOutline = graphics.newOutline(10,"img/axePoint.png")
tipR = display.newImageRect ("img/axePoint.png",20,24)
tipR.x = axeR.x+axeR.width/2+10
--axeTipR.x = axeTipR.x +100
tipR.y = axeR.y-axeR.height/2+20
tipR:toBack( ) 
body:toBack( )
ragdoll:insert(tipR)
tipR.name = "right tip"
tipR.collision = tipCollision
physics.addBody( tipR ,"dynamic",{outline = axeTipOutline, filter=pickaxeTipFilter})

armUpLeft = display.newImageRect("img/BackUpperLeft.png",50,188)
armUpLeft.anchorY = 0
armUpLeft.x = body.x
armUpLeft.y = body.y-body.height/2
armUpLeft:toBack( )
ragdoll:insert(armUpLeft)
physics.addBody(armUpLeft, "dynamic",{filter=armFilter, density= 0.2})


------------------------------------------------------------------
armDownLeft = display.newImageRect("img/BackLeft.png",50,188)
armDownLeft.anchorY = 0
armDownLeft.x =armUpLeft.x
armDownLeft.y = armUpLeft.y+armUpLeft.height
armDownLeft:toBack( )
ragdoll:insert(armDownLeft)
physics.addBody( armDownLeft, "dynamic",{filter=armFilter} )

axeL = display.newImageRect("img/axe.png",100,175)
axeL.x = armDownLeft.x +30
axeL.y = armDownLeft.y+armDownLeft.height+40
axeL:toBack( )
ragdoll:insert(axeL)
physics.addBody( axeL ,"dynamic",{outline = axeOutline, filter=pickaxeFilter})

tipL = display.newImageRect ("img/axePoint.png",20,24)
tipL.x = axeL.x+axeL.width/2+10
--axeTipR.x = axeTipR.x +100
tipL.y = axeL.y-axeL.height/2+20
tipL:toBack( )
ragdoll:insert(tipL)
tipL.name = "left tip"
tipL.collision = tipCollision
physics.addBody( tipL ,"dynamic",{outline = axeTipOutline, filter=pickaxeTipFilter})

head = display.newImageRect("img/head.png", 150,135 )
head.anchorY = 1
head.x = body.x-25
head.y = body.y-body.height/2
ragdoll:insert(head)
physics.addBody(head, "dynamic", {radius = 150, filter=headFilter})

legUpLeft = display.newImageRect("img/LegLeft.png", 60, 160)
legUpLeft.anchorY = 0
legUpLeft.x= body.x+10
legUpLeft.y= body.y+body.height/2
legUpLeft:toBack( )
ragdoll:insert(legUpLeft)
physics.addBody(legUpLeft,"dynamic",{filter=legFilter})

legDownLeft = display.newImageRect("img/LegLeft.png", 60, 160)
legDownLeft.anchorY = 0
legDownLeft.x= legUpLeft.x
legDownLeft.y= legUpLeft.y+legUpLeft.height
legDownLeft:toBack( )
ragdoll:insert(legDownLeft)
physics.addBody(legDownLeft,"dynamic",{filter=legFilter})

footL = display.newImageRect("img/LeftShoe.png",110,50)
footL.x = legDownLeft.x+20
footL.y = legDownLeft.y+legDownLeft.height
footL.anchorX = 0.5 
footL.anchorY = 0
footL:toBack( )
ragdoll:insert(footL)
physics.addBody(footL,"dynamic",{filter=footFilter})

nailL = display.newImageRect("img/NailBackV2.png",60, 10 )
nailL.x = footL.x +30
nailL.y = footL.y +footL.height
ragdoll:insert(nailL)
physics.addBody(nailL,"dynamic",{filter = footPicksFilter})

nailLtip = display.newImageRect( "img/NailBackV2tip.png", 25, 10 )
nailLtip.anchorX = 0
nailLtip.x = nailL.x + nailL.width/2
nailLtip.y = nailL.y
ragdoll:insert(nailLtip)
nailLtip.name = "left foot tip"
nailLtip.collision = tipCollision
physics.addBody(nailLtip,"dynamic",{filter = footPicksFilter})

legUpRight = display.newImageRect("img/LegRightV2.png", 60, 160 )
legUpRight.anchorY = 0
legUpRight.x= body.x+10
legUpRight.y= body.y+body.height/2
ragdoll:insert(legUpRight)
physics.addBody(legUpRight,"dynamic",{filter=legFilter})


legDownRight = display.newImageRect("img/LegRightV2.png", 60, 160 )
legDownRight.anchorY = 0
legDownRight.x= legUpRight.x
legDownRight.y= legUpRight.y+legUpRight.height
ragdoll:insert(legDownRight)
physics.addBody(legDownRight,"dynamic",{filter=legFilter})

footR = display.newImageRect("img/RightShoe.png",110,50)
footR.x = legDownRight.x+20
footR.y = legDownRight.y+legDownRight.height
footR.anchorX = 0.5 
footR.anchorY = 0
footR:toBack( )
ragdoll:insert(footR)
physics.addBody(footR,"dynamic",{filter=footFilter})

nailR = display.newImageRect("img/NailFrontV2.png",60, 10 )
nailR.x = footR.x +30
nailR.y = footR.y +footR.height
ragdoll:insert(nailR)
physics.addBody(nailR,"dynamic",{filter = footPicksFilter})

nailRtip = display.newImageRect( "img/NailFrontV2tip.png", 25, 10 )
nailRtip.anchorX = 0
nailRtip.x = nailR.x + nailL.width/2
nailRtip.y = nailR.y
ragdoll:insert(nailRtip)
nailRtip.name = "right foot tip"
nailRtip.collision = tipCollision
physics.addBody(nailRtip,"dynamic",{filter = footPicksFilter})


--joint section-----------------------------------------------------------------------------------------
Rshoulder = physics.newJoint("pivot", body,armUpRight,armUpRight.x,armUpRight.y+20)
Rshoulder.isLimitEnabled = true 
Rshoulder:setRotationLimits( -170, 20)

Relbow = physics.newJoint("pivot",armUpRight,armDownRight, armUpRight.x,armDownRight.y)
Relbow.isLimitEnabled = true
Relbow:setRotationLimits( -170, 1 )

Lshoulder = physics.newJoint( "pivot", body,armUpLeft,armUpLeft.x,armUpLeft.y+20 )
Lshoulder.isLimitEnabled = true 
Lshoulder:setRotationLimits( -170, 20)

Lelbow = physics.newJoint("pivot",armUpLeft,armDownLeft, armUpLeft.x,armDownLeft.y)
Lelbow.isLimitEnabled = true
Lelbow:setRotationLimits( -170, 1 )

neck = physics.newJoint("pivot", head, body , head.x , head.y)
neck.isLimitEnabled = true 
neck:setRotationLimits( -20, 20)

Rhip = physics.newJoint("pivot", body,legUpRight,body.x,body.y+body.height/2 )
Rhip.isLimitEnabled = true 
Rhip:setRotationLimits( -120, 10)

Rknee = physics.newJoint("pivot", legUpRight,legDownRight,legUpRight.x ,legUpRight.y+legUpRight.height )
Rknee.isLimitEnabled = true 
Rknee:setRotationLimits( -1, 150)

Lhip = physics.newJoint("pivot", body,legUpLeft,body.x,body.y+body.height/2 )
Lhip.isLimitEnabled = true 
Lhip:setRotationLimits( -120, 10)

Lknee = physics.newJoint("pivot", legUpLeft,legDownLeft,legUpLeft.x ,legUpLeft.y+legUpLeft.height )
Lknee.isLimitEnabled = true 
Lknee:setRotationLimits( -1, 150)

footLJoint = physics.newJoint("pivot", legDownLeft,footL, footL.x-30,footL.y)
footLJoint.isLimitEnabled = true 
footLJoint:setRotationLimits( -20, 30)

footRJoint = physics.newJoint("pivot",legDownRight,footR, footR.x-30,footR.y)
footRJoint.isLimitEnabled = true 
footRJoint:setRotationLimits( -20, 30)

footToPickL = physics.newJoint("weld",footL,nailL, nailL.x,nailL.y-5)
footToPickL.isLimitEnabled = true 

picktipL = physics.newJoint("weld",nailL,nailLtip,nailLtip.x,nailLtip.y)
picktipL.isLimitEnabled = true

footToPickR = physics.newJoint( "weld", footR, nailR, nailR.x,nailR.y-5 )
footToPickR.isLimitEnabled = true

picktipR = physics.newJoint("weld",nailR,nailRtip,nailRtip.x,nailRtip.y)
picktipR.isLimitEnabled = true

axeTipR = physics.newJoint("weld",axeR,tipR, tipR.x,tipR.y)
axeTipR.isLimitEnabled = true

axeTipL = physics.newJoint("weld",axeL,tipL, tipL.x,tipL.y)
axeTipL.isLimitEnabled = true

axeR:rotate(150)
axeL:rotate(150)

holdRAxe = physics.newJoint("weld",armDownRight,axeR, axeR.x,axeR.y)
holdRAxe.isLimitEnabled = true 
holdLAxe = physics.newJoint("weld",armDownLeft,axeL, axeL.x,axeL.y)
holdLAxe.isLimitEnabled = true 
----------------------------------------------------------------------------------


--correct positions of limbs
head:toBack( )
axeR:toBack()
body:toBack()
legUpLeft:toBack()
legDownLeft:toBack()
footL:toBack()
--missing footL pick
armDownLeft:toBack()
armUpLeft:toBack()
axeL:toBack()
tipL:toBack()


--place arms in front of the characters or there is a chance they could get stuck
armDownLeft.x =body.x +100
armDownRight.x =body.x +100

function R.getHead()

	

	local headPos = head.y -70
	return headPos
	
end

--listeners for when mountain equipent's tips collide with something
tipL:addEventListener( "collision", tipL)
nailLtip:addEventListener( "collision", nailLtip )
tipR:addEventListener( "collision", tipR)
nailRtip:addEventListener( "collision", nailRtip )



return ragdoll

end --end createCharacter

--function to activate the physics of the ragdoll
function R.activatePhysics()

	physics.start()

end --end activatePhysics

--function to pause the physics
function R.pausePhysics()

	physics.pause()

end -- end pausePhysics


function R.setupGame()

	Rhip:setRotationLimits( 0,0)

	Rknee:setRotationLimits( 0,0)

	Lhip:setRotationLimits( 0,0)

	Lknee:setRotationLimits( 0,0)

	footLJoint:setRotationLimits( 0,0)

	footRJoint:setRotationLimits( 0,0)

	controlJoint = physics.newJoint("weld", body, floor, body.x,body.y)

end 

function startGame(event)

	if rightControl == "hit" and leftControl == "hit" then
		gamestarted = 1

		Rhip:setRotationLimits( -120, 10)

		Rknee:setRotationLimits( -1, 150)

		Lhip:setRotationLimits( -120, 10)

		Lknee:setRotationLimits( -1, 150)

		footLJoint:setRotationLimits( -20, 30)

		footRJoint:setRotationLimits( -20, 30)
		controlJoint:removeSelf( )
		Runtime:removeEventListener( "enterFrame", startGame )	

	end

	
end 


--function to create rocks to climb on
function R.createRock()

	--Create mountain poli to climb on 
	local mountainOutline = graphics.newOutline( 3, "img/mountain2.png" )
	local mountain  = display.newImage("img/mountain2.png", 1000,  3500 )
	--mountain.x= display.actualContentWidth
	--mountain.y = 200
	mountain.anchorY = 1
	mountain.anchorX = 0
	mountain.x = display.contentCenterX
	mountain.y = display.contentHeight
	mountain.name = "mountain"
	mountain.enterFrame = gamescroll
	Runtime:addEventListener("enterFrame",mountain)
	mountain:toBack( )


	physics.addBody( mountain, "static",{outline=mountainOutline, density= 4, filter= rockFilter}  )
	table.insert(rockList,mountain)
	return mountain
end

function speedIncr()
	if gamestarted == 1 then
	speed = speed +0.0001
	end
end

function R.getspeed()
	return speed
end

function gamescroll(self, event)

	if gamestarted == 1 then 
		self.y = self.y + speed
		floor.y = floor.y +speed
	end 


end

function speedIncr(event)
	if gamestarted == 1 then
	speed = speed +0.0001
	end
end

--function called by pressing a button on the game screen 
function R.changeLimb(newLimb)

	selectedLimb =newLimb 
	--the new selection is saved in a variable to be used later by the function moveLimb()
	return selectedLimb
end

function R.moveLimb(speedX, speedY)

	if selectedLimb == "left arm" then
		armDownLeft:setLinearVelocity(speedX,speedY)

	elseif selectedLimb == "right arm" then 
		armDownRight:setLinearVelocity(speedX,speedY)
	elseif selectedLimb == "left leg" then
		footL:setLinearVelocity(speedX,speedY)
	elseif selectedLimb == "right leg" then 
		footR:setLinearVelocity(speedX,speedY)

	end 


end


function tipCollision(self, event)

	if (event.other.name == "mountain") then 

		if ( event.phase == "began") then
			tipDir = self.name
			tipDirX = event.x 
			tipDirY = event.y
			indexNum = table.indexOf( rockList, event.other )
			print( table.indexOf( rockList, event.other ))
			physicsWorldChange= true
		end
	end 

end

function createPivot(event)
	if physicsWorldChange == true then 
		print("WOW THE WORLD CHANGED")
		if tipDir == "left tip" then 
			Lhit = physics.newJoint( "weld", tipL, rockList[indexNum],tipDirX,tipDirY )
			Lhit.isLimitEnabled = true
			Lhit2 = physics.newJoint( "weld", axeL, rockList[indexNum],tipDirX,tipDirY )
			Lhit2.isLimitEnabled = true  
			physicsWorldChange=false
			leftControl = "hit"

		end

		if tipDir == "right tip" then 
			Rhit = physics.newJoint( "weld", tipR, rockList[indexNum],tipDirX,tipDirY )
			Rhit.isLimitEnabled = true 
			Rhit2 = physics.newJoint( "weld", axeR, rockList[indexNum],tipDirX,tipDirY )
			Rhit2.isLimitEnabled = true 
			physicsWorldChange=false
			rightControl = "hit"
		end

		if tipDir == "left foot tip" then 
			Lfoothit = physics.newJoint( "weld", nailLtip, rockList[indexNum],tipDirX,tipDirY )
			Lfoothit.isLimitEnabled = true
			Lfoothit2 = physics.newJoint( "weld", nailL, rockList[indexNum],tipDirX,tipDirY )
			Lfoothit2.isLimitEnabled = true  
			physicsWorldChange=false
		end

		if tipDir == "right foot tip" then 
			Rfoothit = physics.newJoint( "weld", nailRtip, rockList[indexNum],tipDirX,tipDirY )
			Rfoothit.isLimitEnabled = true
			Rfoothit2 = physics.newJoint( "weld", nailR, rockList[indexNum],tipDirX,tipDirY )
			Rfoothit2.isLimitEnabled = true  
			physicsWorldChange=false
		end
	end

end


function R.unstuck()

	print("unstucking in character module")
	if selectedLimb == "left arm"  then
		--print("Yo i'm controlling if unstuck")
		leftControl = 0
		display.remove(Lhit2)
		return display.remove(Lhit)
		
	elseif selectedLimb == "right arm"  then 
		rightControl = 0
		display.remove(Rhit2)
		return display.remove(Rhit)

	elseif selectedLimb == "left leg" then
		display.remove(Lfoothit2)
		return display.remove(Lfoothit)
	elseif selectedLimb == "right leg" then 
		display.remove(Rfoothit2)
		return display.remove(Rfoothit)

	end 

end 



function R.gameover()

	Runtime:removeEventListener( "enterFrame", createPivot )
	display.remove(Lhit)
	display.remove(Lhit2)
	display.remove(Rhit)
	display.remove(Rhit2)
	display.remove(Lfoothit)
	display.remove(Lfoothit2)
	display.remove(Rfoothit)
	display.remove(Rfoothit2)
	gamestarted = 0
end



Runtime:addEventListener( "enterFrame", speedIncr )
Runtime:addEventListener( "enterFrame", createPivot )
Runtime:addEventListener("enterFrame", startGame)
--Runtime:addEventListener( "enterFrame", gameOver )


return R

the entire game code:

--define requirements
local composer = require("composer") 
local physics = require("physics")
local ragdoll = require("character")
local vjoy = require "com.ponywolf.vjoy"
physics.setDrawMode("normal")
physics.start( )

local scene = composer.newScene( )

--create groups
local background = display.newGroup( )
local foreground = display.newGroup( )
local hud = display.newGroup()
local go = display.newGroup( )

--create variables
local focus 
local speedX = 0
local speedY = 0

-- obsolete variables ???
--local focusedLimb
--local movX = 0
--local movY = 0

--stamina variables
local stamina=500
local wait =1000
local isMoving = false

local sky
local joy1
local btnLA
local btnRA
local btnLL
local btnRL

local heightInd
local heightText 
local height = 0
local speed 

local game
local over
local retry
local quit 

local t= {}


function scene:create(event)
	local sceneGroup = self.view

--define sky texture TEMPORARY!!!!!!
sky =display.newRect(0,0,1080,2400)
sky:setFillColor( 0 , 0.7 , 0.9999 )
background:insert( sky )

heightInd = display.newText( "Height", 0,0)
hud:insert( heightInd )

heightText = display.newText( height,0,0 )
hud:insert( heightText )

--create joystick for limb movement
joy1 = vjoy.newStick(1)
hud:insert(joy1)

--create button to select the left arm
btnLA = vjoy.newButton (70,"left arm")
hud:insert(btnLA)

--create button to select the right arm
btnRA = vjoy.newButton (70,"right arm")
hud:insert(btnRA)

--create button to select the left leg
btnLL = vjoy.newButton (70,"left leg")
hud:insert(btnLL)

--create button to select the right leg
btnRL = vjoy.newButton (70,"right leg")
hud:insert(btnRL)

game = display.newImageRect("img/game.png",434,127 )
go:insert( game )

over = display.newImageRect("img/over.png",411,128)
go:insert(over)

retry = display.newImageRect("img/retry.png",284,68)
go:insert(retry)

quit = display.newImageRect("img/quit.png",203,81)
go:insert(quit)

--create the initial mountain and floor
foreground:insert(ragdoll.createRock())

--the character ragdoll is created and inserted into the foreground group
foreground:insert(ragdoll.createCharacter(display.contentCenterX-250,display.contentCenterY-220))

sceneGroup:insert(background) 
sceneGroup:insert(foreground)
sceneGroup:insert(hud)
sceneGroup:insert(go)

end--end function scene create 


--[[
local staminaContainer = display.newRect(0,0 , 500 ,100)
staminaContainer:setFillColor(0, 1, 0 ,0.5)
staminaContainer:setStrokeColor( 0.1 )
staminaContainer.strokeWidth = 5
staminaContainer.anchorX=0
staminaContainer.anchorY=0
staminaContainer.x = 0 
staminaContainer.y = 0

local staminaBar = display.newRect(0,0 , 500 ,100)
staminaBar:setFillColor(0, 1, 0 ,0.5)
staminaBar.anchorX=1
staminaBar.anchorY=0
staminaBar.x = 500
staminaBar.y = 0
--]]

local function heightIncrease(event)

	speed = ragdoll.getspeed()
	if speed > 0.01 then
		height = (height+speed)
		heightText.text = math.floor(height)
	end
end--end function


local function retryGame(event)
	Runtime:removeEventListener("enterFrame", gameover)
	package.loaded["character"] = nil
	display.remove(foreground)
	composer.removeScene("game")
	composer.gotoScene( "intermediateScreen")

end

local function quitGame(event)
	Runtime:removeEventListener("enterFrame", gameover)
	package.loaded["character"] = nil
	composer.removeScene("game")
	composer.gotoScene( "titlescreen"  )

end

local function gameover(event)
	print(ragdoll.getHead())
	local y = ragdoll.getHead()
	if y > display.actualContentHeight then
		ragdoll.gameover()
		speed = 0.01

		local gameTransition = transition.to(game,{delay=500, time = 200, x= display.contentCenterX-250, transition= easing.outBounce})
		local overTransition = transition.to(over,{delay=500, time = 200, x= display.contentCenterX+250, transition= easing.outBounce})
		local retryTransition = transition.to(retry,{delay=500, time = 200, x= game.x+100, transition= easing.outBounce})
		local quitTransition = transition.to(quit,{delay=500, time = 200, x= over.x-100, transition= easing.outBounce})
		
		Runtime:removeEventListener( "axis", controlUnstuck)
		Runtime:removeEventListener( "key", selectLimb)
		Runtime:removeEventListener( "axis", move)
		Runtime:removeEventListener("enterFrame", heightIncrease)

		retry:addEventListener( "tap", retryGame )
		quit:addEventListener( "tap", quitGame )

		

	end

end



function scene:show(event)
	local sceneGroup =self.view
	local phase = event.phase

	if phase == "will" then
--activate the physics of the ragdoll
		sky.x = display.contentCenterX
		sky.y = display.contentCenterY

		heightInd.x = 100
		heightInd.y = 250 

		heightText.x = heightInd.x +200
		heightText.y = heightInd.y

		joy1.x = display.contentWidth-250
		joy1.y = display.contentCenterY+400

		btnLA.x = 150
		btnLA.y = joy1.y

		btnRA.x = btnLA.x+200
		btnRA.y = btnLA.y

		btnLL.x = btnLA.x
		btnLL.y = btnLA.y+200

		btnRL.x = btnLL.x +200
		btnRL.y = btnLL.y

		game.x = -game.width
		game.y = 600

		over.x =display.contentWidth+over.width
		over.y = game.y

		retry.x = game.x 
		retry.y = game.y+200

		quit.x = over.x
		quit.y = retry.y 


	elseif phase =="did" then

		ragdoll.activatePhysics()
		ragdoll.setupGame()

		Runtime:addEventListener("enterFrame", heightIncrease)
		Runtime:addEventListener("enterFrame", gameover)
	end


end--end scene show



--function to select limb after pushing a button
local function selectLimb(event)
	--change selection only when the button in being pushed down
	if event.phase=="down" then
		--save the selected limb in a variable to be used later
		focusedLimb = ragdoll.changeLimb(event.keyName)

	--print("change limb xd ".. event.keyName)

	end--end if 
end--end function

--function that manages the movements of the limbs 
local function move(event)

	if event.axis.number == 1  then
     	speedX = event.normalizedValue * 500
     	--movX = event.normalizedValue
  	end--end if 

  	if event.axis.number == 2  then
    	speedY = event.normalizedValue * 500
     	--print("Y= "..event.normalizedValue)
     	--movY = event.normalizedValue
  	end-- end if 

  	--call the moveLimb function from character module and give speedX and speedY variables to apply force to the selected limb
  	ragdoll.moveLimb(speedX,speedY)

  
end--end function 
--[[
local function move(event)
	
	isMoving = true
	if staminaBar.x >0 then
		staminaBar.x = staminaBar.x -2
	end
	
  if event.axis.number == 1 and staminaBar.x > 0 then
     speedX = event.normalizedValue * 500
     --print ("X= "..event.normalizedValue)
     movX = event.normalizedValue
  else 
  	speedX = 0 
  	--movX = 0
  end

  if event.axis.number == 2 and staminaBar.x > 0 then
     speedY = event.normalizedValue * 500
     --print("Y= "..event.normalizedValue)
     movY = event.normalizedValue
  else
  	speedY = 0
  	--movY = 0
  end

  ragdoll.moveLimb(speedX,speedY)

  isMoving = false
end

local function rest(event)

	if isMoving == false then
		wait = wait -5
		if wait <= 0 and staminaBar.x <500 then 
			staminaBar.x = staminaBar.x +2
			wait = 1
		end
	else
		wait = 1000
	end 
end
--]]


--function that calls the removal of the pivot that attaches the tip to the mountain after a delay of 500 msecs
local function actualUnstuck()
	--call unstuck function from ragdoll module
	ragdoll.unstuck()

end--end function

--to simulate a struggle the player needs to point the joystick in the opposite direction of the mountain
local function controlUnstuck(event)
	--print(event.time)
	--if the player is moving the joystick in the opposite direction of the mountain ...
	--print("i'm inside controlUnstuck")
	if speedX < 0 then

		--for 500 msecs, the function actualUnstuck will be called
		--print("Hello movX is less than 0")
		timer.performWithDelay( 500, actualUnstuck,"unstuck" )-- IMPORTANT DEFAULT 500 for android phones 100 or less IDK WHYYYYYYYY
		
	else 
		--if the player changes direction or stops pulling the other way, the timer will stop
		timer.pause("unstuck")
	end
end




function scene:hide(event)

	local sceneGroup = self.view
    local phase = event.phase
 
    if ( phase == "will" ) then
        -- Code here runs when the scene is on screen (but is about to go off screen)
        
		physics.pause()


 
    elseif ( phase == "did" ) then
        -- Code here runs immediately after the scene goes entirely off screen
 		Runtime:removeEventListener("enterFrame", gameover)
 		
    end

end

function scene:destroy(event)
	local sceneGroup = self.view

end


--Runtime:addEventListener("enterFrame", rest)
--check if the player tries to unstuck the tip everytime the joystick is used
Runtime:addEventListener( "axis", controlUnstuck )
--listener for player interaction with buttons to change limb
Runtime:addEventListener( "key", selectLimb )
--everytime the player moves the joystick, move the limb
Runtime:addEventListener("axis", move)



-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------
 
return scene

it is easier if you zip the entire project folder and upload it as an attachment here

I used to have similar problems, but I recently avoid all possible causes to that, like turning off listeners, and timers, and most importantly use local variables and unload non local variables manually

I found a solution, it was the listeners.
I removed everything from memory, removed scenes correctly and removed groups.

Also yeah, getHead, I know.