Game fps severely drops

Just in case though, I do use tables to store the width, height, and health values of different sized asteroids:

local asteroidImageSizeTableX = {133, 140, 131, 195, 201, 207, 77, 81, 84, 195, 195, 134, 144, 84, 87} local asteroidImageSizeTableY = {114, 113, 110, 157, 170, 170, 63, 67, 63, 157, 156, 113, 116, 63, 63} local asteroidHealthTable = {350, 325, 280, 550, 610, 615, 180, 200, 190, 550, 550, 350, 335, 190, 195} --fragment of newAsteroid function newAsteroid = function(group, x, y, object) local random = mRand(1,15) width = asteroidImageSizeTableX[random] height = asteroidImageSizeTableY[random] local asteroid = display.newImageRect(group, "sprite/rock/asteroid".. random ..".png", width, height) asteroid.health = asteroidHealthTable[random] end

You need to think about this more efficiently… if you keep creating and destroying display objects like you are you will eventually drag.  I’m not sure if this is a GC/Corona implementation error or not but it is a thing for sure.

What you need to do is define a max asteroids value, say 50.  Then when your game loads you instantiate all 50 asteroids.  Have a flag on them like asteroid.isActive = true/false.  If this value is true then do work on it, if false then do not display it and do no work.

If you want to add a new asteroid, walk the array and find the first one that is isActive=false and activate it.  When your asteroid is hit set isActive = false and hide it.

This way you never have more than 50 objects and your memory allocation will stay constant, as will your FPS.

This is called object pooling and is totally something you need to learn.

So, when they are reactivated, I just reposition them…

Ok, I will try this out.

I found that I did not have to use a table to do this, I merely just detected when they were out of a certain range, than re-positioned them, but the problem still occurs:

--new code manageAsteroids = function(self) --enterFrame listener for each asteroid if (not display.isValid(self)) then return end local rawX = mAbs(self.x - asteroidObject.x) local rawY = mAbs(self.y - asteroidObject.y) local rawDistance = mPow(rawX, 2) + mPow(rawY, 2) local trueDistance = mSqrt(rawDistance) if trueDistance \> 2625 then local randomX = mRand(-2625, 2625) local randomY = mRand(-2625, 2625) if (((randomX \> fullw - centerX + 150) or randomX \< -(fullw - centerX + 150)) or ((randomY \> fullh - centerY + 90) or (randomY \< -(fullh - centerY + 90)))) then local rawX2 = mAbs(centerX - randomX) local rawY2 = mAbs(centerY - randomY) local trueDistance2 = mSqrt(rawX2 \* rawX2 + rawY2 \* rawY2) if trueDistance2 \< 2625 then self.x = asteroidObject.x + randomX self.y = asteroidObject.y + randomY end end end end

Log: Jan 24 04:14:15.445 FPS = 60 Jan 24 04:14:16.567 FPS = 59.3 Jan 24 04:14:17.685 FPS = 59.9 Jan 24 04:14:18.804 FPS = 59.7 Jan 24 04:14:19.925 FPS = 59.9 Jan 24 04:14:21.046 FPS = 59.5 Jan 24 04:14:22.165 FPS = 59.9 Jan 24 04:14:23.284 FPS = 59.5 Jan 24 04:14:24.405 FPS = 59.7 Jan 24 04:14:25.525 FPS = 59.9 Jan 24 04:14:26.645 FPS = 60 Jan 24 04:14:27.766 FPS = 60 Jan 24 04:14:28.886 FPS = 59.7 Jan 24 04:14:30.005 FPS = 60 Jan 24 04:14:31.124 FPS = 59.7 Jan 24 04:14:32.246 FPS = 60 Jan 24 04:14:33.366 FPS = 59.9 Jan 24 04:14:34.486 FPS = 59.7 Jan 24 04:14:35.606 FPS = 59.5 Jan 24 04:14:36.727 FPS = 60 Jan 24 04:14:37.846 FPS = 59.8 Jan 24 04:14:38.967 FPS = 60 Jan 24 04:14:40.086 FPS = 59.7 Jan 24 04:14:41.207 FPS = 60 Jan 24 04:14:42.327 FPS = 59.9 Jan 24 04:14:43.446 FPS = 59.8 Jan 24 04:14:44.566 FPS = 60 Jan 24 04:14:45.686 FPS = 59.7 Jan 24 04:14:46.807 FPS = 59.5 Jan 24 04:14:47.927 FPS = 60 Jan 24 04:14:49.047 FPS = 59.8 Jan 24 04:14:50.166 FPS = 59.7 Jan 24 04:14:51.287 FPS = 60 Jan 24 04:14:52.407 FPS = 59.8 Jan 24 04:14:53.528 FPS = 60 Jan 24 04:14:54.648 FPS = 59.7 Jan 24 04:14:55.766 FPS = 59.8 Jan 24 04:14:56.888 FPS = 60 Jan 24 04:14:58.009 FPS = 59.7 Jan 24 04:14:59.131 FPS = 59.9 Jan 24 04:15:00.252 FPS = 59.9 Jan 24 04:15:01.371 FPS = 59.8 Jan 24 04:15:02.493 FPS = 59.9 Jan 24 04:15:03.614 FPS = 59.8 Jan 24 04:15:04.734 FPS = 59.7 Jan 24 04:15:05.855 FPS = 58.6 Jan 24 04:15:06.977 FPS = 59.7 Jan 24 04:15:08.110 FPS = 57.9 Jan 24 04:15:09.264 FPS = 56.3 Jan 24 04:15:10.451 FPS = 55.9 Jan 24 04:15:11.584 FPS = 54 Jan 24 04:15:12.774 FPS = 49.1 Jan 24 04:15:14.030 FPS = 47 Jan 24 04:15:15.220 FPS = 56.1 Jan 24 04:15:16.464 FPS = 55.8 Jan 24 04:15:17.957 FPS = 46.4 Jan 24 04:15:19.506 FPS = 48.2 Jan 24 04:15:20.777 FPS = 53 Jan 24 04:15:22.277 FPS = 49.2 Jan 24 04:15:23.797 FPS = 46.2 Jan 24 04:15:25.554 FPS = 38.9 Jan 24 04:15:27.387 FPS = 33.2 Jan 24 04:15:29.382 FPS = 30.8 Jan 24 04:15:31.431 FPS = 32 Jan 24 04:15:33.433 FPS = 39.2 Jan 24 04:15:35.676 FPS = 31 Jan 24 04:15:37.888 FPS = 32.1 Jan 24 04:15:40.045 FPS = 29.6 Jan 24 04:15:42.320 FPS = 30.7 Jan 24 04:15:44.545 FPS = 31.9 Jan 24 04:15:46.800 FPS = 31.3 Jan 24 04:15:49.124 FPS = 27.2 Jan 24 04:15:51.442 FPS = 27.4 Jan 24 04:15:53.713 FPS = 32.8

Currently, I have an enterFrame listener for each asteroid.

Would it be better to put the enterFrame, or even a timer, on one table filled with the asteroids, and just traverse the table, and then reposition them. Could this work?

Also, I noticed that System Memory continuously increases. 

FYR: My games manage 30k+ display objects and hit a constant 30 FPS (the speed I set my games to run at) so if you can’t manage 200+ then you are seriously doing something wrong.

Your FPS is mad… Check for crazy coding like dropping/recreating objects per frame leaving orphaned physics bodies, etc.  Adding enterFrame() events per frame, etc.

With proper object pooling your memory and FPS should remain constant - have you done what I suggested?

For the sake of $5 I can highly recommend this pooling library:

https://marketplace.coronalabs.com/plugin/gbc-object-pool

I would also suggest not using print statements to monitor your FPS as constantly spamming the log may affect the very thing you’re trying to measure. Create some on-screen text and update that instead.

I did that, but I am not sure if it is 100% right. Plus, its not even 200+ objects, its less than 100…

Would you like me to post the entire file?

Note: I am not using a table to manage the asteroids.

As I’ve said before… I am not going to debug your entire project (I am far too busy for that)… if you need that level of support then roaminggamer offers that as a paid service.

Thank you for this… but I would rather learn how to do this on my own. I have been reading about it, and it is a very important skill that I should pick up.

@anon63346430, how many enter frame listeners would you say you have running at any point in your game?

I have a feeling I know what might be making my FPS sharply drop. I think I have about… 65 enterFrames and collision listeners running at any point.   :mellow:

Yeah, I don’t think I followed your instructions particularly well… Or at least I’m not sure.

I am not creating or destroying any of them, but at the same time I am not “deactivating” them when they go off screen.

I have two main ones… one controls the main game loop and another controls my rendering.  I do have other ones for various animations and other effects and some that start and stop (for things like loading and saving).

Each object in my game has an onFrame() function that gets called from my main loop at various intervals to update its status/runtime values.

I will suggest a starting point for you…

asteroid.lua

local m function m:create(x,y) &nbsp; \<create object\> end function m:destroy() &nbsp; \<completely remove object\> end function m:onFrame() &nbsp; \<move and animate object\> end function m:onCollision() &nbsp; \<disable object but do not destroy it\> end function m:start() &nbsp; \<enable object again - new level, etc\> end function m:stop() &nbsp; \<disable object but do not destroy it - end of level, etc\> end return m

game.lua

local asteroid = require("asteriod") local asteroids = {} --start of level for i = 1, 100 do &nbsp; local x, y = math.random(0, 480), math.random(0, 800) &nbsp; asteroids[i] = asteroid:create(x, y) asteroids[i]:start() end .... --main loop for i = 1, 100 do&nbsp;&nbsp; asteroids[i]:onFrame() end .... --end of level for i = 1, 100 do asteroids[i]:stop() end .... --start of new level for i = 1, 100 do &nbsp; asteroids[i]:start() end .... --end of game for i = 100, 1, -1 do asteroids[i]:destroy() end ....

Ah, so I don’t add the enterFrame and collision to each individual asteroid, I just control that in the main loop.

--squares.lua local M = {} function M:new(x, y) local square = display.newRect(x, y, 10, 10) square.type = "square" return square end function M:destroy() display.remove(self) self = nil end return M --main.lua local squares = {} for i = 1, 10 do squares[i] = square:new(mRand(15, 400), mRand(15, 300)) end timer.performWithDelay(1500, function() squares[4]:destroy() end, 1)

This is a sample project to test object pooling. But when the timer goes off, I get an error saying “Attempt to call method ‘destroy’ (a nil value)”. I am not sure what I am doing wrong.

OMG, this thread is all over the place!  I’d offer to help, but honestly I can’t figure out what the current subject is.

As far as your most recent post, you never assign M’s “destroy” to “square”, so the error is correct - there is no method “destroy” on any of your “squares”, the error is already telling you EXACTLY what the problem is.

No worries, I figured this one out. Anyways, the original thread was about managing my FPS since it sharply drops about a minute into my game, but now I am trying to work on object pooling which is apparently much more efficient when it comes to managing object memory.

Hi guys, probably my mistake for posting a design pattern rather than actual code.  I am trying to show “how to” structure your code not posting “here is final code”.

It is merely a starting point… nothing more.  The onus is on the OP to research the subject.

But for what its worth, you declare square in new() as local so it will immediately go out of scope.  Square should be local to the module.

Maybe this pattern is something Corona docs should focus on more because it really is dev 101…

what is that game?   30k objects??      Great…I am a noob…!

@decoder

He has two big games and a third coming: https://play.google.com/store/apps/dev?id=5640292770246134663

Have a look on how many times functions are call with lua glider and how many time they took to execute. Have a look on your algo because perhaps you calculate things and it’s exponential to the number of object (ex: calculate the distance between every objects).

I have also thousands of moving object with no difficulties