ID:1603629
 
(See the best response by FKI.)
The reasons I ask is because there are a lot things that are updated(attack mastery, attack delay, calculates stamina required to attack, stats) or calculated (crit/dodge chance, if you crit/dodge this attack, damage to the enemy, stats gained from attacking) and checked(what are you attacking, what are you attacking with) when you use the attack verb. I do this because I don't want to have to constantly update all these things, so I call them when they're needed. However, is this too many procs? What is the number of procs before you notice a delay in a verb functioning?
Best response
What you want to focus on is cutting down on unnecessary work the game may be doing. For example, in many games you see on Byond (namely in the anime section) use regenerating systems that recover one's health. These systems are running constantly, even when you are fully recovered. Sometimes these systems are also checking things having nothing to do with regeneration.

Generally speaking though, there is no such thing as having too many procs in one verb.
mob
proc
HPR()
spawn() while(src.KOED == 0 || src.hp <= src.maxhp)
if(rest == 0)
src.hpregen = src.maxhp / 200
else
src.hpregen = (src.maxhp / 200) * 10
if(src.hp < src.maxhp)
src.hp += src.hpregen
if(src.hp > src.maxhp)
src.hp = src.maxhp
sleep(50)


Speaking of regeneration systems, I've been using a spawn() while() loop for mine. While it doesn't loop the code over and over when it isn't needed, doesn't it still check every single second? Does preventing that few lines of code per player really cut down on that much unnecessary work for the game, or is it just an accumulative thing?
No, it's only checking every five seconds (based on what I see there).

Is there a check in place making sure that loop doesn't get started up more than once by accident? Other than that, I don't see anything you should worry about.
No, there isn't any check like that. The while loop seems kind of redundant (it'll always be true, so I could have put TRUE there as well) but do I need to have the spawn() part before it? I only put it there because I'm just mimicking what I see.

I want to optimize the code. So should I create a var that becomes true whenever the player is regening and then put an if statement that returns if the var is true, hp is <= the max hp and they're not koed? Then I'd change the while loop to true.

Like:
mob/proc
HPR()
spawn() while(TRUE)
if(src.KOED == 1 || src.hp >= src.maxhp || regening == 1)
sleep(50)
return
else
regening = 1
if(rest == 0)
src.hpregen = src.maxhp / 200
else
src.hpregen = (src.maxhp / 200) * 10
if(src.hp < src.maxhp)
src.hp += src.hpregen
if(src.hp > src.maxhp)
src.hp = src.maxhp
sleep(50)
regening = 0
The spawn is appropriate if you want the loop to run in the background (which I'm assuming you do).

And yes, that loop should be edited to only run when it's necessary (meaning only when you need to regenerate health). Should be relatively easy if you have all of your damage-related code in one place.

Edit

Hold on, I believe I can better get my point across through an example.
mob
var/current_health = 1000
var/maximum_health = 1000
var/tmp/regenerating = FALSE

proc/take_damage(damage, mob/attacker)
//code...
src.current_health = max(0, src.current_health - damage)
if(!src.regenerating)
src.regenerate()

proc/regenerate()
src.regenerating = TRUE
spawn()
while(src.current_health < src.maximum_health)
//regeneration code...

src.current_health += src.maximum_health / 200

sleep(50)

src.regenerating = FALSE


Just a quick example here. Through my take_damage proc, I control the mob's regeneration. I don't have to worry about it running more than once because take_damage ensures it doesn't, and the loop manages itself, stopping after the mob is fully regenerated.

Now if you want to stop regeneration when the mob is KOed, you can add it to the loop's conditional statement (inside the parenthesis) or add another while loop inside of the already-existing loop, like so:

    proc/regenerate()
src.regenerating = TRUE
spawn()
while(src.current_health < src.maximum_health)
//regeneration code...

while(src.KOed) sleep(10)

src.current_health += src.maximum_health / 200

sleep(50)


I wouldn't recommend the above approach unless you're certain of the possible situations the mob will be in. I use it because 1. I know being KOed is temporary and 2. I don't have to completely break out of the loop and re-call regeneration after the mob is no longer KOed. There are more reasons but those are just a couple conveniences for me.

I'd say don't worry too much about your code being pristine. I do this very thing and, honestly, I end up wasting a lot of time because of it. As long as your programming is convenient and understandable to you and whoever you work with, you're set.

Edit

Also, there would be an if at the beginning of regenerate checking to see if the mob's regenerating var is TRUE, stopping if it is. This is because there may be some cases where the mob may need to regenerate, but isn't necessarily in combat.
I didn't think of procing health regen when the player was damaged. Thats much more effective than running it all the time, I'll implement that, thanks! Though thats yet another proc added to the attack verb, but its better than those procs constantly running I guess.