Everyone always talks about their “fancy” entity systems for their tower defense games, but we never hear much about towers for some reason. I’ve noticed that in a lot of Roblox TD games, especially in the late game, recv spikes like crazy, and the FPS drops can be pretty bad. It’s not that I have a terrible device (it’s more of a mid-range one, close to decent), so I’m really wondering how to optimize this area.
I’ve heard people say I need to implement octrees, bytenet, and other advanced systems of which either sound good or questionable. So that’s why i would prefer to ask here first.
I’m not going to go in-depth as there are a lot of articles out there that will say the same thing, but the “best” optimization you can go for is creating a deterministic system, meaning the game is already “determined” based off calculations, allowing both the server and client to run their own versions. This allows for full client-sided rendering and you get to choose what and when to replicate to the client for important game updates.
Suphi Kaner has a great video on creating an optimized Tower Defense game in his video here (timestamp set to explaining a deterministic system):
Ping: You can minimize the packets the server send to clients via UnreliableRemoteEvents for non-important game updates and/or buffers for compressing and decompressing data which other people has already made into modules for you to use.
FPS: Allow players to change graphical settings for your game, i.e. limit how much VFX gets rendered. Players don’t need to see 200 different towers doing their little animation. Let the engine render ParticleEmitters based off graphics quality instead of manually firing like some games do. Minimize the usage of graphic intensive UI elements such as ViewportFrames. Avoid intensive calculations per frame or section them off via parallel scripting. There are many things you can do to improve FPS and frame times.
Yeah, I know that and already had it in mind to use buffers and UnreliableRemoteEvents and all that. Right now, I mainly only use important remotes so didnt have the chance to use URE. I’ve added some effects to be disabled when offscreen (enemies model update too), but that’s mostly for visuals; the data still updates.
Focusing on optimizing towers at the moment, I don’t really like the idea of both sides calculating the towers completely on their own. I prefer to keep the server sending basic data, like tower IDs with target IDs (buffers, right?), and only add additional data if absolutely necessary. Otherwise, I let the client handle damage and update the model, which isn’t present on the server, but (but the data like damage still calculates independently on the server).
Personally, I find viewports a bit annoying; the lighting isn’t that great, they have some downsides, and often just using a higher-quality image render looks better. The only time I’ve used viewports was in the shop for selecting specific ones.
I also had the idea of creating a common :BulkMoveTo() usage for objects that need normal CFrame updates. I plan to use it for towers when they need to rotate or update a beam when they shoot all in one scheduled frame. I mainly don’t create new beams for each shot; I just change the CFrame and visibility as no towers will shoot fast enough for that to be a problem.
I’m pretty sure I’m already quite far enough in therm of optimization for entities, so now it’s all about optimizing RAM/memory usage and reducing part count for fewer parts to move (which i am not good at.)
Either way, I’m not great at explaining things, and it’s pretty late, so my English tends to suffer when I’m tired (i used gpt to make my message clearer, just explained why, also no idea if it did any errors on the comprehension). So I’ll leave it at that! (tell me if i could do something different instead here i’m not really smart on optimization)