Entity System help for my tower defense game

Hey guys! I’m Dbands and I’m making a game called Galactic Reckoning and I still need to work on my entity system which will need to be able to handle 300-700 enemies. (My original goal was to run 2000-3000 but at the moment I’m going to start small instead of reach for a high goal.)

I’ve tried MoveTo and TweenService (Which didn’t go well as MoveTo hurts my performance and lags a BUNCH and TweenService has high RECV and hurts my performance again when moving that many enemies client sided or server sided.)

If anyone could help me out in learning lerp or give me tips,suggestions,etc for how’d I be able to achieve this goal of running 300-700 Enemies smoothly please let me know. (my old posts: Post 1 and this where I stopped using tween as i tried running 800-1000 enemies Post 2 )

10 Likes

just dont use part, u can use table or vector3value to move enemy in server side and client side to handle enemy model

2 Likes

300-700 is still ambitious, something more realistic would be around 100.
I once heard that up to 500 could be controlled with a custom character system, but that was an experiment not a game (in which you have a lot of other things).

Anyway, your best bet would be to make a custom controller (no TweenService, everything should be with CFrame) and divide the control between the clients. Each client would have control of a handful of enemies, the server would just replicate their states. Animations should be 100% client-side.

a lot of work to do.

Edit:

According to your other posts, what you want is a tower defense. In that case you can make some optimizations, for example handling waves, similar to Zombie Attack. You can also reuse enemies, once they are dead or reach their target, re-spawn them. You also don’t have to do PathFinding, because you can save the routes beforehand (if your routes are curves you could use mathematical equations instead, polynomials). The character controller would be much simpler because it should only go through a preset path (remember to always use CFrames).

4 Likes

If you have unused entities, put them somewhere out of workspace or delete them, but why do you need 300-700, that will cause a lot of lag

4 Likes

The whole point of the post is to try to make an entity system that doesn’t cause a lot of lag. I need a bunch of enemies because my game will have a bunch of different modes consisting of those amounts of enemies, and what do you mean by unused enemies? why would I keep the enemies inside of workspace. I keep all the enemy models in RS.

3 Likes

What exactly Is a character controller? and The animations were already originally client sided as I’m trying my best to make everything client sided so there isn’t big recv and huge performance loss.

Edit: Many other Tower Defense games have made 300-700 work fine and It’s not that ambitious and I’ve tried mainly everything from optimizing walktos but those dont work.

3 Likes

By unused entities i mean entities that are currently not needed or will not be used in game

3 Likes

Yea I don’t keep any unused enemies in the workspace I keep them all in replicated storage.

3 Likes

Alright, firstly if each entity is a model, put them in object files instead of models, less parts = more performance and can reduce lag

2 Likes

are you tweening from the server?

I tried tweening 500 parts from the client and it was smooth.

2 Likes

Nah, I was tweening from the client as the server was horrible. Thats the thing though, you’re tweening parts and I’m tweening models.

2 Likes

What do you mean by this? I put each enemy in their respectful folder and we used blender for the enemies so the models aren’t unoptimized at all.

1 Like

Make your own form of tween service, firstly you prepare a path and then you move these entities according to the pre-cooked path with your tweening module. All you have to do is store this data in entity’s movement system. All you have to know, all the data you need is very few in numbers. You can easily install LOD system to this. But let’s not get chaotic.

Let me break it down into parts how you could optimize your Tower Defense like game.

  1. Create your own efficient tweening system.
    Since there is only one path defined with pre-defined waypoints, which is stored in array, you will always start path from the 1st point. That means you can give entity class WaypointA = 1; WaypointB = 2; Progress = 0; LastMove = tick(); Health… and also a set of methods for movement, displaying the entity statement and the handler for it’s death and the entity speed. This method also allows to avoid lags, since you can move these characters on client side and the difference between client and server in placement of these entities will be almost the same, especially if you calculate the lag.

  2. Since of how your system is built from the first part, you can now create a LOD system. It will be easy, because the LOD system will be focused on the camera only. You can pre-define camera’s 2d grid system that is a shape of a circle from the top and on the side (with slight tilt) looks like a cylinder. And again, because how it’s built (LOD grid around camera), you won’t need to move the grid itself and that’s a big plus to performance. And now on client side you can check if the entity is within the range of LOD grid and depending on how far it is you adjust the quality of model and how often it gets to get updated.

  3. Server would send positions every 10 seconds, to correct client if he miscalculated entity positions, because of this you will have to rely on system which relies on entity identification system with help of UID.

  4. For units with attacks could be optimized too, since you know what’s the cooldown and when they are going to fire, you can reduce complexity of the algorithm to O(1) at best. Simply you create use_weapon_request in your special query system. Though this system would not be easy to set up since of the advanced algorithms behind it like O(log n) in time complexity for insertion into the array of a value, which gets sorted automatically.

2 Likes

its own name says it. In roblox it is the Humanoid Instance. You should create your own, but with much less states, maybe just walk at first. In the forum you will find some ideas.

As for replication, I would recommend you to study the WeaponKit roblox module replication. That will give you an idea of what I meant.

Did you really see a 700 tower defender, most 3D tower defenders, even outside of roblox, just create the illusion. The 2D or isometric ones are something else. Well, if you saw them, it would be useful if you could post some links so we can study them.

Tower Defense Simulator,Tower Blitz,All Star Tower Defense,GTD:A. I’m mainly talking about Enemies here not towers. I can’t really post links as they’re on roblox and fairly popular (besides GTD:A it’s not released)

I played Tower Defense Simulator quite a while ago, but I don’t remember it being like this. But I won’t go into it anymore. Have a nice day.

I would read this thread. I explain my method that uses client sided rendering to get 500 enemies with 60fps (and low recv)

Basically, enemies on the server are tables, send the tables to the client and render them there. We only have 1 part on the server per enemy which is used for projectile collision. No animations, tweening, or models on the server means increased server FPS and lower ping.

If you want better recv, use Vector2Int16/Vector3Int16 to compress numbers to 16 bit integers (no decimals and lower limit, but less data)

1 Like

Thank you so much Kdude, this has helped me greatly in my progress and I figured out how to make the enemies move because of you. However now I’m kind of stuck on how I’d make multiple of them move. Would I just simply do
for i,v in pairs(TableThatHoldsTheEnemies) do
and also I saw that you showed that dude how to move the enemies but my question is how would I move enemies based on their speed and not just

CFrame:ToWorldSpace(CFrame.new(0,0,-0.1))

or something on those lines. is there a specific formula I should follow?

1 Like

Yep, just store all your enemies tables in a table and loop through it.

So you’ll want each enemy to have its own speed stat, then have the base movement speed, and multiply them together. No real specific formula, just tinker with it until it feels good.

CFrame:ToWorldSpace(CFrame.new(0,0,-0.1 * EnemyInfo.Speed))
1 Like

You’ve been an amazing help so far but I have a question about Vector3int16,

If this would be the case and I’m increasing the Position via TableValues.CFrame = TableValues.CFrame:ToWorldSpace(CFrame.new(0,0,-0.1 * TableValues.Speed)) isn’t the Position in that CFrame.new a Vector3 and wouldn’t me increasing the speed be impossible or would the case be I just simplify the data from the server using Vector3int16 and send it to the client and replicate it there.