hehe I want to know everyone's methods for saving processor time and preserving no lag...
what things do you normally look out for, etc?
what methods do you use?
So far I've come up with making sure that in my stat() for my mobs I check tosee if there's a client on the mob otherwise stat() with 30-40 people in a server takes a lot of processing...
then there's client inactivity, I have stat check for that also before updating...
I make it also that the world sleeps if everyone in it is inactive or not enough people are in the world...
1
2
ID:265259
Mar 15 2004, 9:59 am
|
|
Mar 15 2004, 10:33 am
|
|
Using a language other than dm.... :\
|
Jon Snow wrote:
So far I've come up with making sure that in my stat() for my mobs I check tosee if there's a client on the mob otherwise stat() with 30-40 people in a server takes a lot of processing... Stat() is not automatically called for mobs without a client. If you use 'if(statpanel("panelname"))' checks instead of just 'stapanel("panelname")' that will cut a lot of wasted cpu usage for complex statpanels. If you want to find out more about statpanels, check out my article on BYONDscape. It's a free read. I'd look up a link, but BYONDscape seems to be down right now. Ways I prevent lag: Avoiding large loops. Shut down all activity in places that aren't in use. (For example, my Darke Dungeon freezes a z level a few seconds after all players leave the level. (It gives the mobs a little while to follow the player, so people can't avoid a fight just by taking the stairs.) Cut down the frequency of checks. If your NPCs search for a target every tick, they are wasting a lot of CPU power. Cut it back to 10 ticks and most players will never notice the difference. Cut it back more for less CPU usage with a slightly more noticable delay. Stagger your checks. If you have 500 mobs on the map and they all check for a target every 50 ticks then every 50 ticks there is going to be a lag spike. When I kick off a proc loop in mob.New() I usually start it in a random amount of time. mob/New() ..() spawn(rand(1,50)) FiftyTickSearchCycle() In the 500 mob 50 tick example, you'd only have an average of 10 mobs searching for a target every tick, instead of 500 trying to do it all at once on the 50th tick. Keep HUD screen_locs simple. Screen_loc is very flexible, but due to a little glitch in how HUDs are drawn, they can slowdown a client tremendously. If you are experiencing lag, one of the best ways to track the source of it is profiling. Compile your world in debug mode, run it, and press ctrl+P in DS. You may click the links to refresh the profiling data and change from overall time to average time. If you see procs taking a lot of CPU time, investigate to see why they are. |
In response to Shadowdarke
|
|
Shadowdarke wrote:
If you want to find out more about statpanels, check out my article on BYONDscape. It's a free read. I'd look up a link, but BYONDscape seems to be down right now. http://www.byondscape.com/ascape.dmb/Shadowdarke.2003-0322/ |
In my experience, lag is more of a problem of connection, but then, i have rarly hosted anything with over 20 people in it.
|
Playing singleplayer games :)
I'm probably not the person to look to for advice since my experience with actually hosting something I made is pretty scanty, but just generally make sure that things aren't happening repeatedly that don't effect anyone. Along the lines of what Shadowdarke was talking about, if you've got 500 monsters on the map, don't have them all repeatedly checking for nearby players, have the players checking for nearby monsters to warn of the player's presence. Since there typically aren't more players than monsters... 10 players searching for monsters every other tick is a lot faster than 500 monsters searching for players every ten ticks. |
In response to Shadowdarke
|
|
ya some good tips, but one question...
if I wanted to subtract... say, turns... certain amounts depending on certain turfs... would it be better to do the checks and such in Move() or the turf's Enter()? |
In response to Jon Snow
|
|
Jon Snow wrote:
ya some good tips, but one question... If you want it to subtract the turns when you successfully enter a turf, use turf.Entered(). If it should subtract when you attempt to enter the turf, put it in turf.Enter(). That will make it easier to override for special situations on a turf by turf basis. For example, if you wanted a water turf to take 3 turns for typical mobs but only one turn for mobs with flippers, you could just change the water.Enter() proc. With a Move() based system, you would have to check the turf type and that would lead to a very messy if() tree when you have a lot of special exceptions. |
In response to Shadowdarke
|
|
Stagger your checks. If you have 500 mobs on the map and they all check for a target every 50 ticks then every 50 ticks there is going to be a lag spike. When I kick off a proc loop in mob.New() I usually start it in a random amount of time. In the 500 mob 50 tick example, you'd only have an average of 10 mobs searching for a target every tick, instead of 500 trying to do it all at once on the 50th tick. Here's another system of doing the same thing which isn't dependent on the rand() function: mob/New() ..() //Static variables continue to exist in memory; each call // of the mob/New() proc will use the newly increased // variable value. Thus, this will automatically create // delays from 1-50 when spawning mobs simultaneously. var/static/delay = 1; delay = ((delay++) % 50) spawn(delay) FiftyTickSearchCycle() |
In response to Spuzzum
|
|
Hrm... I wasn't aware of static in DM, nor do I see it listed in the reference or in the guide.
|
In response to tenkuu
|
|
Hrm... I wasn't aware of static in DM, nor do I see it listed in the reference or in the guide. I think he means global :P. |
In response to Theodis
|
|
I guess it's basically the same. Maybe I should have gone rooting through some old posts. ;)
|
If you are going to use stat meters for things like health, ammunition, magic power, ect. and you are going to have them on the map screen, do not put the code for changing its appearance in Stat, instead change it only when some action that changes it is taken.
Example: (Bad) mob/Stat() hp_meter.icon_state="[hp]/[max_hp]" ammo_meter.icon_state="[ammo]/[max_ammo]" mp_meter.icon_state="[mp]/[max_mp]" (Good) mob/verb/attack(mob/M in get_step(src,src.dir)) ammo-=1 M.hp-=1 UpdateMeters() mob/proc/UpdateMeters() hp_meter.icon_state="[hp]/[max_hp]" ammo_meter.icon_state="[ammo]/[max_ammo]" mp_meter.icon_state="[mp]/[max_mp]" That goes for more than just onscreen meters too, anything that you check in Stat() could be speeded up by checking only when the event happens. This is assuming the event happens less often than Stat() is called. If, for some reason, people are getting hit multiple times between Stat calls then of course Stat would be faster (Although less accurate). Another way to reduce the cpu usage is to make sure you don't abuse loops. Only put something in a loop if it is nessessary. For instance: mob/ViciousCreature That hunt procedure would be faster if you moved the prey check outside the loop. (It would also be a good idea to put a break in after the prey=M line so it does not continually loop without need.) mob/ViciousCreature This lag reducing code is similar to the Stat one mentioned above since they are both basically keeping things out of loops so that they do not happen continuously if they do not have to. And for my last speed efficient tactic, setting a value to a variable and using that variable is obviously faster than continually calculating a formula. Example: (slower) proc/ShowValue() (faster) proc/ShowValue() |
In response to Theodis
|
|
Theodis wrote:
Hrm... I wasn't aware of static in DM, nor do I see it listed in the reference or in the guide. No, I don't. |
In response to Spuzzum
|
|
I think he means global :P. There is no static type variable in DM. Though when global is used in the scope of a proc or a datum it behaves the same as a static variable in C. |
In response to Theodis
|
|
Theodis wrote:
I think he means global :P. There is. I wonder if it's brand new and undocumented, or ancient and undocumented... |
In response to Jon88
|
|
There is. I wonder if it's brand new and undocumented, or ancient and undocumented... Try out these pieces of code. mob verb Count1() var/global/counter world << ++counter Count2() var/global/counter world << ++counter Both those counter variables are unique but are destroyed when the scope of the proc is left just like static variables in C. [Edit] and read up the sub threads in tenku's post :). I aparently accidenlty got it right awhile ago without knowing static variables were called global :P. |
In response to tenkuu
|
|
Well, whatever the case is, I've been using them for months with absolutely no problems, so I figure they must have gotten put back in at some point. =P
|
In response to Spuzzum
|
|
Well, whatever the case is, I've been using them for months with absolutely no problems, so I figure they must have gotten put back in at some point. =P Well in Tom's post he noted "DM currently (and always will) support static vars. We are calling them 'global' (although you can still use the 'static' keyword if you want)." So static just does the exact same thing only it isn't documented :P. |
1
2