Log In  


I made a mistake in a method and wrapped an entire logical expression in a flr() statement instead of just the number. Instead of an error message the pico-8 would just hang when I tried to run it.

if (flr(self.bottomPaneX == 17)) del(objects,self) spawnWindow()

Above causes pico-8 to hang when you try and run the cart below doesn't

if (flr(self.bottomPaneX) == 17) del(objects,self) spawnWindow()

In a smaller scale test I found that it didn't hang running the following

cls()
test = {}
test.var = 0x42
if(flr(test.var==0x42)) print("reached")

Here is the code which can reproduce the error.

objects = {}
window = {}

function round(fract)
	if fract-flr(fract)>=0.5 then return flr(fract)+1 end
	return flr(fract)
end

function _init( ... )
	spawnWindow()
end

function spawnWindow()
	local obj = {}
	--dimensions for drawing. there are lots so that they can be slightly altered for spooky animations
	obj.topPaneX,obj.topPaneY,obj.topPaneW,obj.topPaneH = 51,27,25,11
	obj.bottomPaneX,obj.bottomPaneY,obj.bottomPaneW,obj.bottomPaneH = 51,30,25,10
	obj.frameX,obj.frameY,obj.frameW,obj.frameH = 51,27,25,21
	obj.colour = 12

	--the object state controls which animation the object is in
	obj.state = 2
	--update method for the object
	obj.update = function(self)
		if(self.state==1) then 
			if(self.bottomPaneY < 37) self.bottomPaneY += 0x0.8
		elseif self.state == 2 then
			self.topPaneX -= 0x1
			self.frameX += 0x1
			self.bottomPaneX -= 0x0.4
			self.bottomPaneW += 0x0.8
			self.bottomPaneY -= 0x0.4
			self.bottomPaneH += 0x0.4
           --This is the fated line top breaks bottom doesn't
			if (flr(self.bottomPaneX == 17)) del(objects,self) spawnWindow()
            if (flr(self.bottomPaneX) == 17) del(objects,self) spawnWindow()
		end
	end

	--draw method for the object
	obj.draw = function(self)
		--remember to save tokens we only need to delcare colour when we are drawing with a different colour to the last thing drawn
		--draw the frame
		rect(self.frameX,self.frameY,self.frameX + self.frameW,self.frameY + self.frameH,self.colour)
		--draw the top pane
		rect(self.topPaneX,self.topPaneY,self.topPaneX + self.topPaneW,self.topPaneY + self.topPaneH)
		line(self.topPaneX + round(self.topPaneW /2),self.topPaneY,self.topPaneX + round(self.topPaneW /2),self.topPaneY + self.topPaneH)
		--draw the bottom pane
		rect(self.bottomPaneX,self.bottomPaneY,self.bottomPaneX + self.bottomPaneW,self.bottomPaneY + self.bottomPaneH)
		line(self.bottomPaneX + round(self.bottomPaneW /2),self.bottomPaneY,self.bottomPaneX + round(self.bottomPaneW /2),self.bottomPaneY + self.bottomPaneH)

	end

	window = obj

	--adds the object to relevant tables
	add(objects,obj)	
end

function _update( ... )
	-- body
	for o in all(objects) do
		o:update()
	end

end

function _draw( ... )
	-- body
	for o in all(objects) do
		o:draw()
	end
end


I think you realized that line doesn't make sense anyway, but what happens is this:

  • self.bottomPaneX==17 => boolean (true/false)
  • flr(boolean) => 0 (I think the argument is ignored when not a number and flr() just returns 0)
  • if (0) ... <=> if (true) ... (anything else than nil and false evaluates to true) => del(objects,self) is ALWAYS executed.

so basically you're deleting everything on your first update, and there's nothing left to draw nor update. since there's not even a cls(), the screen stays as it is and the program loops doing nothing. but Pico-8 doesn't actually hangs.
hope that helps :)



[Please log in to post a comment]