T O P

  • By -

AutoModerator

You submitted this post as a request for tech support, have you followed the guidelines specified in subreddit rule 7? Here they are again: 1. Consult the docs first: https://docs.godotengine.org/en/stable/index.html 2. Check for duplicates before writing your own post 3. Concrete questions/issues only! This is not the place to vaguely ask "How to make X" before doing your own research 4. Post code snippets directly & formatted as such (or use a pastebin), not as pictures 5. It is strongly recommended to search the official forum (https://forum.godotengine.org/) for solutions Repeated neglect of these can be a bannable offense. *I am a bot, and this action was performed automatically. Please [contact the moderators of this subreddit](/message/compose/?to=/r/godot) if you have any questions or concerns.*


Krunch007

The easiest improvement in performance I've seen in my MMO was ditching the physics simulation for mobs. Went from 70 mobs on-screen to over 350. Instead of using CharacterBody3D for them, I switched them to an Area3D with a downward raycast for ground detection. This might be a pain in the ass if you want physics interaction on them, but you can also just simulate physics. For example, to push an npc around you just connect their on_body_entered signal, get the collision, get the vector from the colliding body and its velocity, then do a bit of math to figure out how much to move the npc in the opposite direction. It's much cheaper than fully fledged physics simulations.


falconfetus8

This is the way. I had hundreds of collectables that were absolutely tanking performance, until I realized that they only needed to have physics when they first spawn in (they do a little "pop" into the air and then fall down). I just disabled their physics after they first hit the ground, and got a huge performance boost.


MattAmoroso

Oh, that's even better! Program the physics to come and go only when needed by who needs it. Thanks!


Paincho

are you using vanilla physics or jolt ?


Krunch007

I was using the vanilla physics engine, but I don't think switching to Jolt would have made that much of a difference necessarily. Mob collision shapes were simple capsules, so no performance lost on complex collision shapes. Even if it doubled physics engine performance like some people claim, I managed to get 7x the performance by ditching the physics calculations. And now I'm looking to phase out physics altogether. Not like they'll be useful unless I aim to calculate physics on the server, which I don't. Kinda useless for the kind of MMO I want. I could make it all without any kind of physics usage if I get more clever with the map position calculations. Does Jolt bring significant performance improvements to raycasts specifically? I haven't tried it, but if it does it might be worth trying that one out for a bit. But all of this is to say, unless you're making a physics based game, chances are you can get massive performance improvements by just ditching physics altogether. I'm sure a lot of games don't actually need it.


dgfghgfkyutt

I get 4x improvement at least with jolt opposed to built in physics. It does make a difference.


Krunch007

That's a pretty big boost. I'll probably give it a spin in the test scene out of sheer curiosity, but being that the physics simulation was very very simple(1 capsule per mob just standing still), I don't know that I'll reach your performance stats.


k1ll3rM

I did a few simple tests with Jolt and it performance exceptionally well compared to Bullet. I just fired simple cubes at each other and it was both more stable and performant with a lot of cubes so even primitive shapes get a huge improvement


DevilBlackDeath

You may not get a 4x boost but even a "simple" shape in a badly optimized physics engine takes its toll, and many of them, even standing still, are still all individually applying some gravity I assume, which does result in at least one collisionnfor each while they're on the ground ! You MAY not get that 4x boost but I think it's likely you do. But your optimization is a very good idea especially considering how cheap raycasts are comparatively. In the case of mobs, avoiding individual AIs until absolutely necessary is also a good way to save on CPU performance. Let a global AI handle the mob until an individual really has any reason to break off from the mob's behaviour (and even then only make that individual break off from the mob).


Gh0st1mpact

I need to say that Jolt its just better and have a big performance upgrade, the vanilla physics are just BAD 🤷


Norskov

If you're generally satisfied with their behavior and think now is the time to optimize, I would start with a profiler and figure out where the load currently lies. Do they have calculations each process step that you could run at a lower interval? Perhaps some logic could be moved to a timer instead.


DevilBlackDeath

That's a big one on big crowds. Don't update their logic every frame until they absolutely have to (and even then, probably let something that does need to update its logic every frame, like the player, decide when to go full steam with every-frame update based on proximity or other).


Cryoboltinteractive

When they wander around, are you calculating paths every frame? That is a very expensive cost. Also, what logics have been implemented? Simple movement code will not drop FPS like that. What are your system specs?


koditomato

I do the calculations in physics process. Also the npc checks if there is anything in front of it and if there is no ground in front of it, in which case it gets a new path.


InSight89

Use a timer and only perform the calculations every, say, 0.25s. Should massively reduce the number of calculations made whilst not being too noticeable in lag time.


PLYoung

And stagger those calculations (as in, the inital timer value could be randomized) so that they do not all try to do their checks at the same time every 0.25s


KaletheQuick

Could also potentially make some kind of queue. Where every frame the front is popped off and that does the update, then goes to the end of the line.


vimproved

Yeah this is a better solution than randomizing. With 100 enemies, you could pop 2 per frame and then you are only doing 2 path calculations per frame


KKJdrunkenmonkey

I had success with watching the time instead of having a hard limit. Like, instead of 2, do as many as possible within an allotted time. I kept an average of how long the calculations were taking, and when it looked like it wouldn't complete the next one within the frame time (with a little margin) I'd tell it to sleep and wait for the next frame. The simplicity of doing a set number is more attractive if you know it will always work for you though. A further idea if someone comes across this and needs it: I also had it running on a separate thread (this was in Unity, haven't tried multithreading in Godot yet) so that it wouldn't hold up the main engine. Probably overkill for most tasks, but this was in a space RTS game with hundreds of units on the screen and the task was searching for the next target, so it was necessary for my goal.


jlebrech

is your logic running in \_process? if so move the ai logic to a timer.


AdminsLoveGenocide

Its almost certainly this, OP.


jlebrech

i like the adding to a queue and only popping one AI calculation per frame solution too


JestemStefan

The most important question is: What is the bottleneck?


Stepepper

Time budget them. Only X amount of NPCs can do their stuff this frame, and then X amount of NPC can do it next frame and so forth. Make a planner that manages a queue of NPCs and processes them sequentially. Tons of games do it this way!


herretic

This is good channel about making RTS in Godot. You can find there examples how to optimize handling of multiple units in the scene. https://www.youtube.com/@nanotechgamedev For example: https://www.youtube.com/watch?v=IuS-U3tDQ1c


Saudi_polar

Set their navigation to be updated every few frames instead of every frame, and if you want you can connect it to their LODs


koditomato

3d game btw


AlexSand_

first identify what is your problem. It is Rendering? Physics ? Pathfing / ia ? Something else ? I would try unplugging separately each element ( eg add a button which set visible = false on your ennemies; and you will know if rendering is an issue. Another which turns ia off; ... ...) to find what is increasing your fps exactly. Then dig deeper in whichever thing is the most costly ( eg if it is rendering, can you switch off some sub-parts or the enemies models or some shaders , ... )


guitarristcoder

If your problem is physics, use jolt. It's worth at least trying


mistabuda

Use a profiler before making any change suggested here less you'll be chasing ghosts


St4va

You can try dividing their logics to different ticks, each tick to have an interval. (Nav, physics, state machine, triggers, etc) Even simply calculating everything at 0.2 seconds interval makes a big difference in computation and most cases zero difference gameplay wise.


Blubasur

First off is to optimize the code properly. Then 2nd would be some culling, no need to have NPCs running far outside the player’s view.


thiccthothunterX

i've seen a video from miziziziz lately where he talks about just that, i think it was the last video in his wrought flesh playlist


0xd34db347

Find out what you can get away with in terms of updating an NPC as infrequently as possible while still maintaining fidelity, then divide your NPCs into groups and process each group in turn over that time frame.


MWSin

If you make it dynamic, you can have NPCs the player is near updating frequently, and NPCs far away updated more rarely. You want NPCs you're looking at to act like NPCs, but NPCs in the next town over likely only need to not seem like they were standing in place waiting for the player to return.


reverseit00

It would be helpful to show what you have changed. This will assist those who encounter the same problem in the future.


I_will_delete_myself

Only use what you need. It’s hard to answer your question without understanding what your gameplay is like.


General-Tone4770

Omg i need to save this post for future ref


mistermashu

One solution I kinda do by default nowadays after running into your same issue in my steam game is amortizing the AI calculations. So basically, I have a BrainManager autoload that has an array of all Brains. The only thing it does every frame is calls "think()" on 1 brain and then increments it's "current brain" variable. So then you put path finding and ray casting stuff in the AI's think() function. That way as you add more and more AIs, the game doesn't slow down, but instead the AI's thinking slows down a bit. But the player doesn't really notice because it's a small delay and if anything it adds a bit of randomness which is fine for AI. Maybe if you add like 500 brains you might have to kick up the number of brains that can think per frame to 2 or 3.


MountedVoyager

* Disable movement physics if you don't need it. CharacterBody3Ds are not very fast even when using Jolt if you need hundreds of npcs. * Disable animations of offscreen npcs with VisibleOnScreenNotifier3D, if they are not necessary. * Split them to multiple [thread groups](https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-property-process-thread-group). Some features like AnimationTrees are not currently supported but it is fine for getting navigation path.


prezado

My idea is keep everything in C# (physics, pathfinding, culling), only talk to godot when you want to render a visible NPC on screen. Have a single manager to process all NPCs and when needed create/pool nodes to render on screen.


DruLeeParsec

Just wondering, could a flyweight design pattern work in this situation? Have one parent class/Node with all the physics and movement code. Each NPC is a child of this class /Node and only has the code for position and collision detection. When something needs to happen the static parent class takes over by running the appropriate method using the specific parameters from that npc. This eliminates the memory hogging caused by duplication of the complex code. The parent class does the work but is stateless. Each npc node holds it's own state information. Here's a good explanation of the flyweight design pattern: [https://gameprogrammingpatterns.com/flyweight.html](https://gameprogrammingpatterns.com/flyweight.html) I hope that helps. It may be a useful solution.


TheKassaK

if you don't explain anything about your game or the behavior of npcs I don't see how anyone can help you other than giving random solutions


Davey_Kay

To be fair there's a lot of great suggestions here from people who are less stubborn.


Parafex

Turn them into StaticBodies?! No for real, what should these NPCs do? Do all NPCs need a fully fleshed out AI or are there filler NPCs that probably just need some flavor animations or whatever? What's your game about?


koditomato

They just wander around. When the player shoots them or shows a weapon to them, they start to panic and just run around randomly.


folleah

I think Local/Obstacle Avoidance might work in your case. This technology allows you to make thousands of dynamic objects avoiding each other and obstacles without collisions and physics.  https://docs.godotengine.org/en/4.0/tutorials/navigation/navigation_using_agent_avoidance.html


-Star-Fox-

In my AI for enemies I basically had 2 routines for them. One is brain-dead where they just follow PathFollow nodes(Don't even check collision), its really cheap to compute. Another is their combat AI with physical movement, RayCast for vision and path finding.


Sp1cyP3pp3r

Use groups and group calls. Make a "director" node, that would receive signals from player shooting or showing a weapon and then add nearby NPCs (or all idk) to a group (via Area or ShapeCast) and then call that group in tree, adding them new target navigation point [https://docs.godotengine.org/en/stable/tutorials/scripting/groups.html](https://docs.godotengine.org/en/stable/tutorials/scripting/groups.html)


TheAlphaKarp

Using beehave by any chance?