[Libgdx] Huge world with alot of entities fps drop [solved]

Hello,

i would love open a huge rpg world with alot of entities. But the fps drops alot more entities are on the map. Worth to metion entities who are outside of the player range are not rendererd.

        int count = 200000;

        blockArray = new Array<Creature>(true, count);

        while (count > 0) {
            blockArray.add(new Monster("Dragon", new Vector2(0, 5 * count), game.asset.getAtlas().findRegion("dragon")));
            count--;
        }

        // Set up the quad tree
        quadTree = new QuadTreeNode(0, new Rectangle(0, 0, Main.V_SCREEN_WIDTH / game.UNIT_SCALE, Main.V_SCREEN_HEIGHT / game.UNIT_SCALE));
        entitiesToCheck = new Array<Creature>(true, QuadTreeNode.MAX_ENTITIES);

Profiler:

Seems like each monster gets its own texture region - I don’t assume each monster has a unique look.

No they are not, how can i tackle this problem?

If they all look alike, just reuse one texture and draw it 2.000.000 times each frame…
But I really, really recommend to get your game first working with 20 monsters, then 200 maybe, …

How can i reuse the texture? Since i tried create it outside the loop and there is no difference on the fps increase:

        int count = 200000;

        blockArray = new Array<Creature>(true, count);

	dragonTexture = game.asset.getAtlas().findRegion("dragon");
        while (count > 0) {
            blockArray.add(new Monster("Dragon", new Vector2(0, 5 * count), dragonTexture));
            count--;
        }

        // Set up the quad tree
        quadTree = new QuadTreeNode(0, new Rectangle(0, 0, Main.V_SCREEN_WIDTH / game.UNIT_SCALE, Main.V_SCREEN_HEIGHT / game.UNIT_SCALE));
        entitiesToCheck = new Array<Creature>(true, QuadTreeNode.MAX_ENTITIES);

20k of entities is WAYY too many.

First, if you loop like for each entity, move, draw. Then, on a PC there is probably nothing to worry about.
Thing is, you want each entity to examine its surrounndings, make decisions, etc…

So, are these 20k entities on the screen? If not, then only draw what is actually on the screen.
The map is huge, so, unless you need actions from them across the world (unlikely in a single player game), why not just let them sleep if they are more than a few screens away?

In something similar, it didnt take much more than 50 entites with full decision making, etc, to start seeing an impact in performance on an android device (there were other limiters, but thats less important)

i hope you are not thinking of building an MMO game as the reasoning for so many active entities?

The thing is they are not getting drawn or render when they are outside the screen. Problem is bigger the array become more fps drops i notice. I think problem is with the creating new Texture for a monster 2milion times when i can do it once. Since they are using the same. But how can i reuse a texture?

Thats not quite right, just because it does not appear on screen, it will still make a draw call and process it as though it was on the screen.

What should i do? Since it should be possible to have a alot of creatures without any problems. Those Who are not displayed has a idleState and only checking if they are being seen or not.

Are you using Ashley?

Anyway, the answer will vary… How much of the world will the player be able see at any given time?
Is the entire world in a singular map?

How much processing will each entity be doing?
Can you limit how many checks to “isactive”? Consider; if(isActive) x 20k is going to be alot. So, Even if you have 20k predetermined entities walking around, you’ll need to split things up so you only consider a reasonable amount at any given time.

Lets say in a rogue type, you wouldn’t load the entities into memory until they are within a proximity, and even then probably keep them sleeping until appropriate…

No i’m not using Ashley.

The default state is idle. So they only check for when player is in screen. Also even tho they are not doing anything. I think the main cause, is that i’m loading everyone instant into the world.

It’s a single map that’s very small, but the monsters are positioned very far from eachother.

So i suspect that Array where i adding the dragon is to big and taking to long time to loop through it.

I’m using TMX map.

I’m not sure what you want us to tell you. You’re handling too many enemies at once. Decrease the number of enemies.

Do some profiling to figure out exactly where the bottleneck is. What do you spend the most time doing? Decrease the number of times you do that.

There are a number of approaches to this: for example you could split your world up into sections, and only handle enemies that are in that section.

But until you do some profiling, then everything we could tell you is just a guess. Profile first, and then think about optimizations.

I had already profiling image on the first post. Issue is not that they are too many enemies on the screen. Since those Who are not seen by the player are not moving, redering and etc… The issue is that if i add to many enemies to the array it seems to decrease the fps.

[quote=“printer,post:13,topic:59191”]
Yes, probably because you’re still iterating over all of the enemies and checking whether they’re on screen? Again, you need to profile to see what’s taking up the most time.

…what a trainwreck of a thread, holy shit.

First thing, your quadtree is basically getting ass-raped with a cactus right now with how you place your monsters, this structure is not ideal at all for an ever growing straight line of enemies. Try placing them randomly in a fixed size square region, that’ll suit your quadtree way better and is a more realistic representation of how they’ll be placed later in the real game anyway.

I mean this part:

new Vector2(0, 5 * count)

Try this instead:

new Vector2(random(min_X,max_X), random(min_Y,max_Y))

Second thing, where the hell is your main game loop, you didn’t post it here right? How is anybody going to be able to help you without that crucial piece of information?

The most interesting parts are how you check your units for processing and how you handle the quadtree, please post the whole thing.

Third thing, do you really think it is a good idea to make the quad-tree only as big as your screen, why do you even need the quadtree then?

new QuadTreeNode(0, new Rectangle(0, 0, Main.V_SCREEN_WIDTH / game.UNIT_SCALE, Main.V_SCREEN_HEIGHT / game.UNIT_SCALE));

Make it as big as your game world instead!

Fourth thing, implement some static global counter that counts how often certain methods (monster.idle()/update()/render() and whatever) are called per frame, so that you know what gets invoked how often. Do this for the monsters methods and everything else that gets called repeatedly.

Or use the profiler: [quote]Again, you need to profile to see what’s taking up the most time.
[/quote]
Listen to him, he’s right! You didn’t profile method calls/execution times yet. Instead you’ve just shown us instance counts.

My spidey-sense tells me you’re simply processing too many entities way too often, 200K is a lot.

entitiesToCheck = new Array<Creature>(true, QuadTreeNode.MAX_ENTITIES);

Does this line mean you “check” (whatever that means, we don’t know, post your code…) every entity? This is the perfect recipe for long execution times.
Just doing a simple check per entity is enough to bring down frame-times with your entity-count.

Agreed…

I first found that out when drawing shaperender stuff across tiled maps to make sure that things were being parsed correctly… it didnt take long for frame rates to drop.

I really dont see how you need 20k of entities that are being processed at any given time.

Better to start things small and then scale up… like, to get controls constrain it to a simple box that suits the test, etc.

Its a lot easier to get lost when you build a massive list of things that are partially done adn then sorting out the stuff that winds up breaking.

also, agreed, figure out where time is being lost…

Question, since i use a quad tree to handle collision. Should i also store objects inside there? Such as walls, trees, water tiles and etc… Since they are also collision object? Or is it bad practise

I think it would be a good idea to sort moving and static entities into two separate quad-trees, if you want a little bit of extra performance.

Walls, houses and roads do not change their position in the world (=> in the quad-tree).
Moving objects on the other hand change the tree when moving around, they for example split nodes, or collapse nodes, etc. When this happens, all the entities (even the static ones!) in these nodes need to be re-inserted. Having more objects in a node means more overhead when stuff changes!

This might be a total non-issue though depending on how your game utilizes the quad-tree.

I suggest you do whatever is more practical/easy for you to implement.

I agree with you to use seperate quad tree for objects. But If there is alot of collision objects on the screen. What is the optimal values for these two:

    public static final int MAX_ENTITIES = 4;
    private static final int MAX_LEVELS = 5;

Test different values when you have the game up and running :wink:

There is a perfect number for this and one could calculate it at least approximately, but that would be a waste of time for an unfinished project.