Very mysterious frame drops?!

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
RonanZero
Citizen
Posts: 90
Joined: Mon Oct 20, 2014 3:33 am

Very mysterious frame drops?!

Post by RonanZero »

My game experiences very weird and mysterious frame drops.

Simple math like this, ran a few too many times per second:

Code: Select all

local shouldDraw = (kk > math.floor((GameState:getPlayer().x-260)/16) and kk < math.floor(((GameState:getPlayer().x+260)/16)));
Which was originally meant as an optimization, actually causes extreme slowdown, but only while my player is in certain positions.

(I have drastically reduced this lag by only looping through and drawing tiles in the player's view, but it still comes back with some lines of code such as the above and below.)

For example, I go very far to the right of the level and very far down, and the lag spikes get worse and worse the further I get. Removing that line fixed it.

Another example, when I spawn more than just a couple bat entities of which this is the code:

Code: Select all

-- commented some stuff out for testing; nothing changed
function bat.new(x, y)

	local self = setmetatable({}, bat)

	self.x = x;
	self.y = y;

	self.batSprites = {};

	self.box = aabb.new(true, 0, 0, 20, 14);
	
	self.lastHit = 0;
	self.health = 4;
	self.dmg = 3;

	--self.hitSound = love.audio.newSource("res/snd/enemyhit.wav");
	--self.dieSound = love.audio.newSource("res/snd/explosion.wav");

	self.isEnemy = true;
	self.respawn = true;

	return self;
end

function bat:keyPress() end

function bat:tick(dt)
	if (self.dead) then return end;

	--all tick code removed, still no difference in lag
end

function bat:draw()
	if (self.dead) then return end;
	-- all drawing code removed, still no difference in lag
end

return bat;

Code: Select all

-- and for gamestate object, updating and drawing respectively

for k, v in pairs(self.entities) do
	if (v ~= nil) then
		v:tick(dt);
	end
end

for k, v in pairs(self.entities) do
	if (v ~= nil) then
		v:draw();
	end
end
Even with the comments, the exact same levels and sort of position-based frame drops seen with the first small line of code above that one, persists.

Keep in mind, my amount of entities [the amount of times my game has to loop and run a few functions] is very small, right now it doesn't even reach 20, and yet with the addition of a couple of bat entities everything goes wrong if I'm standing in the wrong place.

What should I do to figure out precisely what's causing any and all frame drops? I just don't get it.
while true do end;
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Very mysterious frame drops?!

Post by raidho36 »

Do you by any chance create new entities all the time? The two highlighted functions are time-consuming but only when you actually call them. Lag spikes caused by them indicates that you are in fact calling them a lot.
User avatar
RonanZero
Citizen
Posts: 90
Joined: Mon Oct 20, 2014 3:33 am

Re: Very mysterious frame drops?!

Post by RonanZero »

No, I only create entities when the game/level starts. Here's an example of that "position-based" lag:
LAG IS SEEN AT 1:20


Is there a way I can see how each function takes to execute while the game is running?
while true do end;
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: Very mysterious frame drops?!

Post by nyenye »

Look into profilers. Dunno if there is one for lua, but it shouldn't be hard to do one.
User avatar
ivan
Party member
Posts: 1912
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Very mysterious frame drops?!

Post by ivan »

Yep, there are a few Lua profilers out there, and I wrote one myself too:
viewtopic.php?f=5&t=80759
It's fairly well tested and works fine, I like to reset the profiler stats every 100 frames or so
and print the results on screen so that I can see the bottlenecks while playtesting.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Very mysterious frame drops?!

Post by kikito »

Without being able to look at your whole source code, it is nearly impossible to know what is really happening.

I can tell you however that your approach for skipping drawing stuff is upside-down.

Instead of "going through all objects in the scene, and checking a condition to see which ones should be drawn and which ones shouldn't", it is much more faster to "go over the objects which are visible, and draw them, ignoring all others".

If your game is tile-based, and your tiles are in a bidimensional table, this can be done very easily; instead of doing this:

Code: Select all

function drawTiles(map, player)
  for x=1,map.width do
    for y=1,map.height do
      local tile = map:getTile(x,y)
      if shouldDrawTile(tile) then
        drawTile(tile)
      end
    end
  end
end
You do something like this:

Code: Select all

function drawTiles(map, player)
  local minX, minY, maxX, maxY = getScreenTileCoordsAroundPlayer(player)
  for x=minX,maxX do
    for y=minY,maxY do
      drawTile(map:getTile(x,y))
    end
  end
end
If your game isn't tile-based, you need to use something called a "spatial hash". Here's a good article which explains them: https://gamedevelopment.tutsplus.com/tu ... -cms-27586.

Spatial Hashes or tiles will also help you when you need to do collision detection. Speaking of which, my library, bump, comes with a build-in spatial hash ;)
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests