Slowdown with "many" nodes

Godot Version

4.4

Question

I am trying to build a system in which the stuff shown depends on the player’s position, as in any proper rouguelike.

The theory is fine (somehow).

However, if my screen is say 1600x1000 and my items are 16x16, I have 6250 of them (at least!) in the screen, plus the player. And the game slows down a lot, it is untolerable. We’re talking 9-10 FPS on the profiler. Yuck.

If I reduce the screen size by 1/4 i.e. 800x500 (and the objects count become 1/4 as well) everything gets back to smooth.

6000 items should not be a problem. Of course, each “item” has something inside: it is not 6000 nodes therefore, the scene has about 30k nodes since each “item” has a shape, an area2D or two with its colliders, maybe animation players (doing nothing for now)… That said, only 6k of them are “_processing” (not physics processing).

For some reason, on the profiler I see about same time (50-60 ms) for both process AND physics_process, but the only guy doing physics_process is the “player” node, all the others are _process.

Whatever. Any suggestion on how to speed up this thing? is it normal that 6000 items processing and essentially doing some checks makes up for such a slowdown?

Unrelated question. Once upon a time the test window was a normal window with its nice standard buttons such as the close “X” button on the top right. Now it is filled with a lot of interesting stuff but no standard button. How to restore them?

Thank you very much

Don’t process. What do you need areas for? Get rid of them.
Consider using a tile map.

Go to the “game” tab (next to the 2d, 3d, and script tabs) click on the three dots menu option, turn off the embed game option

1 Like

“Consider using a tile map”

I would like. But, how do I decide what tiles to show and what to hide? How can I achieve the result of having a tile invisible because it is behind a tree wrt the players position?

I have no idea. It would depend on multiple things, and you haven’t shared much of the context.

Perhaps provide a more precise description of what exactly you’re making and how you need it to behave, or post a mockup or an example of an existing game. And beware of the infamous xy problem

1 Like

I assume most of your nodes are “dead” things in the background like floor tiles, walls or trees? Because in that case you should definitely look into tilemaps and use nodes for the “interesting” things that actually matter and have some kind of behavior.

Welcome to optimization. How long have you been game developing as overhead
should always come when your prototyping a game/system.
You must think scope, please give us more context on what

  • what game your making ?
  • What scripts are on these 6,000+ nodes
  • Why 1600x??? res and what system specs you have.
  • is it a pixel art game or ???

Good luck

Ok.

So first, why so many items.

Because I would like to use 16x16 sprites, and I would like to be able to fill a screen 1600x1000. My intended resolution is 1920x1080 but I am going to use the right 320 pixels for other stuff not world viewing.

Suppose that my world is made of grass and trees. The player must be able to see grass around him as long as his sight does not hit a tree. When that happens, what is behind the tree should be covered.

So I need “something” that

  • can be directed from the player to other objects, or vice versa
  • is able to detect what is along this direction, be it grass or tree
  • assuming that it starts from the player (one could work the other way around of course) them, as long as “it” detects grass, it must command them to “show”
  • when this “thing” detects a tree, it makes it visible, too, but not anything beyond

What is this “thing”?

  • a raycast?
  • a small Area2D, moving at constant pace (should not need to be a continuous movement; a tile per delta time should fine in principle) that detects what is overlapping

I tried with raycast as well and it sucks for speed. Also, raycast does detect only the first item, so I am left to write down what to do with the objects “behind” it.

So I opted for many tiny area2D.

Now this sucks in some respect because what I see is not “stable” in the following sense: when I fix the player position, some things are always visible, some are not -and this is fine at all- but some “borderline” things switch from visible to hidden, which sucks.

I plan to work on this. As I can see running the game with collision shapes enabled, sometimes the tiny area2D go past beyond “hard” stuff (trees in the above example) which should not happen.

My first attempt was to send areas from tiles. Sending them from the player instead is faster, but less stable in the sense stated above.

Since I work on a grid world, I might consider not using areas at all and using an array where I store “what” is at each (discrete) position, then use equations instead of overlapping areas to see if all this works. I will report on whether this method works or not.

All this being said, I would really appreciate if anyone tells how I can achieve my goal with a stable and fine method, maybe even working with tilemaps would be the top.

It would be hard to post code and node structure here. If you want I can upload the project here.

Use Tilemaps layer, turn on Y sort and you can always change the paint of the ordering as well.
good luck

  • edit… You can always put items in your tilemaplayer into a new ID… and check if you hit or enter that ID as well. It`s very powerful

Panic now.

I hit the 3 dots on the game debug window as someone suggested.

Now my debug game window has the aspect I wanted, but it does not detect inputs anymore!!!

I can’t move the player. What did I touch wrong?

Don’t raycast per frame. Raycast only once when the player moves from one tile to another.

Doing a custom visiblity test using bresenhams’s line instead of the raycasts may be preferable, though. Godot even has a method to construct the line in Geometry2D singleton.

The game view debug ? sometimes checking 2d/ and input is enabled

Ok found it.

Pheeeew paniiic

thnks

Don`t panic. Game aesthetics is the chill part, coding ? prepare for pain.

Ok.

I am working in continuous movement for the tests btw.

I will try that too

with “that” I meant the discrete line stuff.

The solution with the bresenham_line works way better.

Now I am going to try to use tilesets instead! It should be even faster; but even with nodes, in 1600x1000 it is fine.

Thank you.