Worried about optimization of a game with lots of moving parts

So here’s some footage of a new puzzle game I’ve been working on:

Mainly, I’ve been focusing on programming individual object classes, a lot of which you see in the video. Turrets, mines, wall crusher, laser, magnets that pull magnetic objects towards itself, and barrels that can explode depending on environment.

I purposely put a large number of turrets on a random level to see how the game does performance-wise, and script activity definitely does increment slightly, it goes up around 3-4% utilization.

I’m not saying I have a desire to create super large levels with tons of these game objects, however I feel like optimization may be necessary at one point or another to assure smooth gameplay.

Currently what I’m doing is for every game object, I create a new “class” instance depending on object type. Each class has different implementations such as an :Update() method, which will be ran every frame or so to update that object depending on its needs. However, I implement tick() timers to assure an object only runs necessary functions (like raycasting) when it’s necessary.

not every class has an implementation of :Update(), as it’d be stupid to update a Mine every frame as it’s specifically wired to explode upon contact with a player, so I used an initialization event for stuff like that to set up .Touched events, or so fourth.

Not 100% sure how I could optimize what I’m doing, because honestly I think I’ve done a decent job considering how complex these game mechanics are.

I’ve also rendered the entire game client-sided for optimal performance. Definitely not the best option but for the type of game that I’m making, it’s more about player experience.

Any help is appreciated, I can clarify if needed. Thanks for reading :slight_smile:

Well there are many methods you could use to optimize your game.
But one you should use to avoid any yieldings and slowdowns to your scripts, is multi-threading.
Like that you will make more things in a certain amount of time. You can learn about coroutines here. @ReturnedTrue made a great post explaining their usage and how to use them in your own game.

Another method would be the simulation-replication it is good for avoiding high ping, and a higher network activity usage, this method is basically letting the clients make the changes of the game, and not stressing the server to update each client with the changes made by one certain client. Basically a client that made the change, fires a remote event to the server, then the server fires another remote to all clients to make the change. Like that the server doesn’t have to use its own resources to make updates to the game, instead it leaves this task to the clients.
You can read more about it and how to implement it to your game here.

And a method I use to get more players playing, is letting players choose the game quality in a settings gui, what effects they want to be used, if the want textures, the graphics quality level, lighting etc…
This is a great method for making the game compatible with low-end devices, as the players could improve their FPS amount.

I hope I gave you some ideas and methods you could use to optimize your game. Even though I didn’t really explain too good how they work, you could check the posts I linked. They might offer you a better explanation.

4 Likes

To add onto what @Wqund said, make sure you also utilize object pooling. The action where you take objects and reuse them for the same purpose. This will help with performance if done correctly.

Luckily, somebody created a module to assist with this:

1 Like

That looks quite cool, and that’s definitely something I could implement easily for stuff like the turret.

However, how could I determine how many premade parts to make??

1 Like

You could try and doing like 100 as a pool for 1-2 turrets. Polling will help with memory build up and it would be less lag than removing and making a new instance each shot.

Reason is that maybe you have a big puzzle with long ranges is the reason of how high I thought but you would get the idea.

I should try the module also actually.

1 Like

That’s neat. So I guess the only other question I have would be like, when a bullet hits a target and is ready to be ‘destroyed’, I would set it’s parent to nil rather than destroying the instance directly I’m presuming?

1 Like

It has its own removal function. By setting it to nil would kind of defeat the purpose of tha module. What it dose is when it technically removes it is that it’s moving the part thousands of studs away and when gets called from pool it goes to where the location is needed at.

Edit : I suggest playing with the module to figure it out and look at the post for it.

1 Like

I tried using part cache, but to my surprise, there was little to no difference in terms of script activity.

Kind of weird :confused:

edit

I just realized I was still creating new BodyForce objects in each bullet using the part cache module, however, despite commenting that out so literally all I do for the turret firing is reposition the bullets and set their velocity, it actually increased script activity.

Quite strange