ID:2012650
 
(See the best response by Ter13.)
Code:

Problem description:
I've created a battle system with many mobs (like total war). So far I've tested the game with a total of 500-600 mobs participating, the game doesn't crash but lags.
So do you have any ideas to reduce the lag and hopefully increase the mobs??

My thoughts:
*I have movement lag=0.5-1 tick, does that waste many resources??
*I saw that Cross occurs thousand times because units are very close to each other
*Most lag occurs when more than 300 mobs move at the same time.
*Speed updates every 5 seconds for all mobs
*Battle checks update every second for all mobs.

So I believe main culprit is Move()
About the updates I'm thinking of making list of mobs fighting or moving so the for loop doesn't check every mob but the ones actually fighting or moving.

and lastly can someone tell me how much time is wasted with for loops
and what are the procs I should definitely avoid or limit in byond

It's my first time trying to optimize and know only the basics so any pointers are welcome :)

Also btw when a soldier is killed the mob isn't deleted I use the same mob in "Dead" icon state, so I have many corpses in the field. Should I limit them or they don't take many resources??
To me moving the mob every tick is fine, when a player is actually nearby to see it. But if I was going to have the mob roaming the map randomly while no player is around to even see it, I'd maybe move it every half second but with higher step_size, or preferably not move it at all and instead have it just teleport every once in a while to a nearby appropriate turf perhaps 4 tiles away.

How are you doing your battle checks? I don't recommend having an individual battle checking loop on each mob running each second. That'd be killer. Better to put the battle check loop on the PLAYER instead of 300 mobs, since you'll never have 300 players I assume. A simple version of what I do is keep a list of all enemy mobs in the /area/ and the player loops thru those to check if any of those mobs should attack it.

I'm no pro, I don't know if this helps you, but there it is.

If you activate the cpu profiler you will know what the culprit is. It might be Move() as you say.

The most intensive BYOND procs from my testing are, in this order: view(), range(), looping thru "world" (for(blah in world) or just for(blah) same thing), using an absurd amount of spawn(), using unneccessarily low sleep() times. There's a ton of other things I can't remember right now but those ones I mentioned can get intense.
Out of curiosity, are these mobs overlapping one another? Or are they all on separate tiles? If they are overlapping one another, 300 is about the right number to completely murder your project.
Tens of DU about the increasing tick lag when mobs cant be seen yeah that's a good idea, I will try it out. Well actually 1 player controls 300 mobs its like total war or age of empires where you control many units.

Ter13 right now I use icon_size of 192 pixels, so most mobs are in the same turf. I don't like having such a high icon_size myself but I do that because of the bug with big icons disappearing. So increasing the icon_size is a workaround. Is this a problem because of view() range()?? Because I'm going to create lists for mobs I want to check and not use range(). I hope they fix that bug, or provide a better workaround because that would be a massive help and would simplify many things.

Best response
Ter13 right now I use icon_size of 192 pixels, so most mobs are in the same turf.

Yeah... Found yer problem.

Every time something moves, it has to look through the contents of the turf it's leaving and the turf it's entering and build a list of full/partial blockages.

By moving 300+ mobs at a time with such a large turf size, you are filtering through potentially tens to hundreds of thousands of iterations of this filtering.

BYOND is capable of around 50K-100K moving objects moving per frame --provided they aren't bunched up on one another.

Just 300 objects moving within close proximity of one another will bring any world to its knees.
This is something I'd very much like to improve on at some point, as I think there are a couple of inefficiencies in the move routines. Those don't really show up except in these extreme edge cases, though.
a couple of inefficiencies in the move routines.

There are more than a couple. The fact that movables' Cross()/Uncross() functions being called are dependent on the default implementation of Enter()/Exit() is one of the biggest mistakes that Tom ever made with this engine (It ranks up there with the entire 350/400 feature set implementation). It's been a source of near constant headaches for me, and you know just how fond I am of mucking with BYOND's built-in movement and improving how it works.

EDIT: If this message seems shitty, you'll have to excuse me. I've been finishing off the leftover champagne from New Years that we never drank because we ewre looking for our cat. Sober Ter is blunt. Drunk Ter is ridiculous.
In response to Ter13
Go home Ter, you're drunk.
Go home Ter, you're drunk.

I am Ter, I am home, and I am drunk.

...Not sure what to do...
Nice I have some leftover wine myself so I can drink some and mess around with byond movement procs :D jk

Yeah that must be the problem then...
So since the problem with big icons isn't fixed can someone give me access to the files I need to give it a shot at solving this problem and some info about it. Not for an official fix but to try to patch it up a little or find another workaround. Is it difficult to fix?? Or maybe I can override default Move() proc for the battle part and customize it for my needs.

So is there any hope of solving my problem??
In response to Ter13
Not knowing is half the challenge (:
In response to Victorqr
Victorqr wrote:
So is there any hope of solving my problem??

Bring the tile size back down to something reasonable. Increasing the tile size not only doesn't fix the problem, it worsens almost every other problem.
Well I've already made a custom walk proc based on Move(), so I can just replace Move() with another proc that suits my game needs for the battle part, because having all my buildings disappearing is not a solution. Maybe I can allow soldier mobs to Enter a turf without checking their whole contents only the atoms close to them that actually have a chance of blocking their move.
Ter I saw somewhere that you said there is another workaround, having the icon set at even multiples of worlds icon_size. So if that is true then that is far better than rewriting Move().
icon set at even multiples of worlds icon_size

This only works for objects that are on the map at compiletime. Any objects created after runtime won't be added to the interesting turf list.

A better solution is to build your map as a tilemap, but apparently our younger developers don't like tile-based solutions.
Yeah I've read the post about the bug, so can't I manually increase the radius for these turfs?? I noticed that they disappear after a specific amount of tiles. So by increasing the tile size you manage to get them to be on that list you mention. Is there a specific radius for the interesting turf list? Or can't we like manually prioritize such turf containing large objects so they are included first and then normal obj/mob drawing occurs. It just doesn't seem to be a difficult problem so we don't have a fix all this time. I mean more difficult bugs have been solved, I guess most debugging now goes to webclient since its a new feature and this bug might have passed on the background. Correct me if I'm wrong I mean I've never actually read byond source code.

So about breaking them to tiles, it gets a little annoying when you have dynamic large icons but its still doable. So since I never used that method and all these objects are loaded in runtime. is there a way to make a list for each obj??
like putting all the smaller icons in place with a loop and also since these large objects have HP and are destructible where is preferable to store these HP?? I mean that every attack at a small 32x32 part of an obj must decrease an amount of HP of the whole building.
ok just tested with 32x32 grid and I'm in awe!! 6500 mobs walking smoothly! so if someone can answer the above questions then I could use that :) I never thought it could get that high!
noticed that they disappear after a specific amount of tiles.

I'm working on something that should be able to serve as a workaround for this issue. Give me a few hours to work the kinks out. It's essentially a softcode version of the code that Lummox will ultimately have to write to fix the problem himself.
Nice good luck :) When you are ready please show me your work.
When you are ready please show me your work.

This is gonna take a little while.

There are complications with my solution:

1) You can never assign the location of an object manually. You must use Move() or ForceMove(). Any manual assignment of locations on tracked objects will break the quadtree structure.

2) It will induce some CPU overhead because it has to poll observed objects for appearance updates every frame.

3) It will break animate() on any objects that are larger than 4 tiles in size unless you also animate() all overridden objects.

The solution isn't something that's entirely clean, but it does seem to be working so far. I just need to fix up a few things and I can show the code.
Page: 1 2