Discussion on reworking the game logic for performance reasons (poll)

The game performance has been talked about for quite a while now with effort going into finding the problems and talking about radical ways to improve the performance. These ideas about radically reworking the game has come up in other contexts as well.

Based on those points I think it’s finally time to talk this through and decide what to do (as Godot 4 is still not here, which might help a bit with the performance).

I’ll line out the main points first, then add a poll here (and one on the community forums: Discussion on reworking the game logic for performance reasons (poll) - Meta - Thrive Community Forum). At the end I’ll share my opinion and potential alternative future direction to decide based on whether this is done or not.

So the idea is that instead of relying on Godot Nodes to construct the microbes, chunks and other game elements, we would do our own game logic simulation. Then based on the simulation we can use Godot just to render the game. Of course we’d still fully use Godot for the game GUI as Godot’s GUI system is very good and it isn’t any kind of issue.

Why is this then such a big discussion? Well the reason is that I estimate it could take multiple months to complete this work. I think I could make this change happen in a month, but from experience I know that any programmer’s schedule estimates should be multiplied by 2-3 to get an accurate number. So at a non-optimistic schedule doing this gameplay logic rework would mean that there’d be one full release where I wouldn’t have time to make major changes for that release (so we’d likely have one very feature-bare release).

Here’s the poll on whether a lot of time should be put into reworking the game logic to get the performance problems under control (of course this isn’t a magic bullet for really slow computers where compound cloud simulation and just a couple of active cells already result in really low FPS):

Should the logic rework for more performance be done?
  • Yes
  • No
  • Yes, but not yet

0 voters

I put in the “not yet” option for people who think we should wait for Godot 4 or more of the game to be completed, though I must say that the more work goes into the microbe stage the more effort there’ll be in this kind of conversion later.

Now it’s time for my own opinion. Based on recent discussions about other related things and the ever present performance complains, I think this rework project should be undertaken. I’m right now going to work on a microbe benchmark next which will be one of the main tools I’ll use to get an early estimate on how well this kind of change would perform. I do want to work on some prototypes before undertaking this work, so I’d say if there’s enough “yes” votes, I’d start working on this around March.

It would be really nice to finally be able to get people to stop complaining about the performance.

And finally some thoughts on the future if “yes” wins. I think we should keep the game logic in C# so that development is easier (finding volunteers to write good quality C++ seems a lot harder), and moddability stays excellent. We’ll be giving up something like 30% of performance compared to C++, but I plan on utilising threading as much as possible so that when Thrive is ran on computers with 4 or more cores we can still have C++ level of performance without any of the difficulty.

One potential change which I’m unsure whether it would be good or not would be to go from an OOP approach to an ECS approach. Instead of just reworking the way the Microbe etc. classes interact with each other and the game physics, the refactor would go much deeper and would change the game to use an ECS to split the game entities into multiple separate components. I think this will increase the refactoring time quite a lot. My guess is that by just ripping out the Godot parts and redoing the graphics stuff, it’ll be actually kind of a doable change to move the logic to C# in about a month. If an ECS refactor is also done I think that’d take quite a bit of extra time and would also require everyone on the team to get familiar with how to structure code in the future and work with the new structure. But do we have any huge ECS fans who’d be in favour of this change? We could always do a second refactor to make the game logic neater with an ECS after the performance related refactoring. I found one good looking C# ECS that might serve as a good base: GitHub - sebas77/Svelto.ECS: Svelto ECS C# Entity Component System

One slightly complicating thing with the refactor to C# is that we anyway need to grab a physics engine. I think I’ll grab some C# bindings for the bullet physics as I think that’ll probably be the best option, but if anyone knows of any other promising alternatives please do mention them. Using bullet means that we’ll have a native library that needs to be compiled. For this my plan is to of course make scripts for compiling the library, but also a tool to automatically download precompiled version. That way the impact on anyone not updating the physics library compiling the game is relatively minor.

So my plan for the refactor is to first do that benchmark I mentioned above. Then do a quick proof-of-concept prototype using that benchmark just to validate that this approach can truly achieve at least 2x the number of cells (I’m hoping closer to like 10x) at the same FPS. After that validation is done, I’ll setup all of the compiling scripts etc. properly and go into the game codebase proper to refactor all the game entities and setup a new base system for worlds to simulate physics entities with the custom logic. It’ll probably also make sense to update the editors to use the new approach as making two separate ways to draw organelles (in the editor and in the stage) doesn’t seem like a good design decision to me.

1 Like

Some initial thoughts:

If you DONT do this refactor, do you have a way to avoid this problem in later stages? With current entity limits, even macroscopic stage might not be feasible when fleshed out with terrain, and if there is no other way to make that work your hand might be forced on this matter. On the other hand, if there’s an easy way to make the later stages better and this is just a case of microbe stage being bad legacy code, it might make sense to just wrap up microbe stage and shrug off the limitations while focusing on bigger parts of the game.

Would it be possible to time the refactor to a release where the rest of the team can be working on tiny stuff like rebalances? I imagine most PRs are going to be conflicting with such a change, so it would be wise to not knock out the rest of the team for a release too.

When making architecture choices I would favor understandability. I don’t have to tell you it’s hard to find people willing to learn a code base and style standards. It also sounds like this ECS approach is a separate chunk of work from the node refactor anyway, so I’d advise not conjoining them.

Does Thrive need a physics engine? The only physics in the current microbe stage I can think of is when two microbes bump into each other and stop moving. You don’t need realistic physics for that; RTS games were doing it in the 90s. Other than things needing to fall down sometimes in Aware stage, I can’t think of a future time that a physics engine would be important.

1 Like

I think that microbe stage is pretty uniquely terrible in terms of performance because of a few things like: all the environmental chunks being constantly pushed by currents and the way the microbe physics and rendering is setup. I have not tested but I would not be surprised to be able to easily have multiple times more creatures moving around in the later game with a static world collision, just the creatures being physics bodies, and them being rendered as a single animated mesh (or a single multimesh per creature as in the current prototype).

Well taking 0.6.1 as an example, there’s been only a few things that would have conflicted with gameplay refactoring changes had I already started working on this over a month ago.

I think this kind of refactor will have smaller impact (or maybe similar) than when I had to refactor base classes for all the editors and stage scenes. Those caused a few conflicts, but it wasn’t too bad.

We need pilus collisions, toxin collisions. Pushing around chunks. The list of stuff we need is so long that I’d say it is much easier to use a physics engine rather than try to fix those case by case.

I’m not confident enough in my 3D math skills to write the code to determine if a ray cast (for a weapon) hits a complicated shape or it misses it. And on top of that physics engines use quadtrees and all kinds of tricks to cut down on how many collision checks they do.

If we for some reason wouldn’t use a physics engine, I foresee a future were we eventually end up just making a much worse version of a physics engine.

1 Like

One question first, if we DON’T do the refactor, will godot 4 solve some of our problems?

I think that’s entirely unknown at this point. I vaguely remember someone saying Godot 4 has some performance improvements, but whether those would even apply to our use case is unknown. Overall the hope is small, but if we could get extra performance for free that’d be of course very good ratio of effort to benefit. Overall I’m no longer content on waiting for Godot 4 as it seems to be never coming out, and instead want to do something that’s in our control.

Edit: actually I just answered a related question on the community forums that I don’t think we can switch to Godot 4 anytime soon (even 4.0 is not out and we probably need to wait at least until 4.1): Discussion on reworking the game logic for performance reasons (poll) - #7 by hhyyrylainen - Meta - Thrive Community Forum

1 Like

My say in this is that it’s probably better now than later. Performance has always been a big issue with our player-base, and being able to fix that at least somewhat will make for a great update even if it’s not full of new toys and content. I’m sure the players will forgive you for releasing less content if they can actually play the multicellular prototype at more than 5 fps.

Also, and forgive me if I’m overreaching with my limited understanding of programming, but could this not make the switch to godot 4 a little easier once it does release? My assumption being that less reliance on the engine means less needs to change to continue working.

1 Like

This is entirely possible. Though, considering the comments from the few people who already tried converting Thrive to Godot 4 with the automatic converter is that even our GUI is not safe and our theme for some reason doesn’t work. There’s a lot more GUI elements than other Godot scenes in Thrive, so even if it does help, it likely won’t reduce the overall required work that much.

Looks like the yes option won here and also on the community forums, so this will be something I’ll start working on soon. As I said in the OP I want to do some work on the prototypes before jumping into this.

1 Like

Realised I forgot to reply here.

I’m definitely in favour of performance-related work and I think this is the best option we have at the moment.

But I am worried that if it does take an entire release cycle and prevents other development, we risk ending up with nothing if this isn’t as effective as we’d hoped. What’s the minimal amount of work you think you can get away with to test whether this will actually help?

Like I said before. Had I worked on this for it to be done with 0.6.1, there’s like basically no work that got done that conflicted. Of course as volunteers are unpredicatable, that doesn’t guarantee that 0.6.2 work cycle won’t have a bunch of stuff that would conflict.

Well I did the benchmark, which allows a of an easier way to convert only parts of the code for an initial test. But I’d expect that that isn’t a ton faster, only like 20-40% faster to get that done first before tackling all of the code in the game.

And also even if this doesn’t help for performance, this is basically required for @Kasterisk’s multiplayer work as that is not doable due to how limited the way you can interact with the physics engine when used through Godot is.

1 Like

Since we are deciding to go this route, maybe we might want to reconsider using c++ for some of the logic as well.

The way I see this going is in three layers:

  • Gui & Graphics handled by Godot

  • Main game logic handled in c#. This is where most dev time will be spent.

  • Low-Level Physics and Performance Demanding Code - This is basically a performance layer, containing stuff like membrane generation and other demanding tasks.

That is possible and just a bit more difficult to do. Moving the membrane generation or compound cloud simulation to C++ in the same step as the other logic conversion is not going to save any work, so I’m not planning on doing it at the same time.

One bit tricky thing is balancing the number of used threads as we can’t obviously run the same number of C# and C++ threads as there are cores in a computer. That and handling precompiled C++ modules are probably the only really tricky parts that need thought. I think it’s maybe worth it to do this later, but if we only get like 20% more speed in compound cloud simulation. That’s not going to be that huge deal. Also membranes might cause slightly smaller lag spikes. The cache I added for membranes makes the tradeoff of using a bunch of extra memory but reducing the CPU processing lag spikes to basically zero for spawning microbes of a species that has already spawned at least once.