ID:1256906
 
(See the best response by Stephen001.)
Code:
proc
heal(mob/M,amount)
M.hp+=amount

//VS

mob/proc
heal(amount)
src.hp+=amount


Problem description: Which way is better. Which do you prefer and why?

I assume mob/proc is faster, but is duplicated as many times as many mobs there are in the world. Then if I had hundreds of mobs wouldn't it be waste of space (especially if the proc is a much much longer)?

The global proc method is way that I saw people recommended for a long time, but is it good to use for this particular and similar cases?

Best response
I think we could do with some clarifications here, for sure.

  1. Neither is appreciably faster. They'll perform 'about' the same, and that's probably all the matters for that, performance-wise.
  2. Procedures defined on an object/mob live in a symbol table, and so, their definition exists once in memory. Simply defining that procedure on mob will use the same memory regardless of how many mobs are in the world.
  3. Procedure definitions plain don't use a lot of memory either way, so who cares about that! 8D
  4. The global procedure route throws away a metric ton of design flexibility. See below.


Okay, basically, any arguments about speed, memory use do not matter here, it makes no difference, they're basically equivalent. In fact, stop asking which is faster, or uses less memory, because it doesn't matter for your game, I guarantee it. Any slowness or memory issue will be elsewhere.

They are not equivalent though, in terms of what you can do with them. Pretty much, I'd argue the complete opposite of what you've seen recommended (and frown at whoever recommended it). Here's why:

Specialisation

Okay, in our game, we have four races, humans, elves, dwarfs and undead. At first, healing for them is all the same:

So using the global method:

mob/player
var/health = 100

mob/player/human

mob/player/elf

mob/player/dwarf

mob/player/undead

proc/heal(var/mob/player/P, var/amount as num)
P.health += amount


Simple, but then we go "Ah, actually, I can do some cool things with healing, for my game." So we decide, humans just heal like before, elves get a bonus, dwarfs get reduced healing, and for the undead, healing actually hurts them!

mob/player
var/HP = 100

mob/player/human

mob/player/elf

mob/player/dwarf

mob/player/undead

proc/heal(var/mob/player/P, var/amount as num)
if (istype(P, /mob/player/undead))
P.health -= amount
return
else if (istype(P, /mob/player/elf))
amount *= 1.5
else if (istype(P, /mob/player/dwarf))
amount *= 0.7
P.health += amount


Alright ... not sooo bad, but if we keep adding special effects, and races, that's going to be a very long, and painful to read/debug kind of procedure.

However, by defining it on the mob, we can take advantage of inheritance, and specialising the procedure. So initially, we just have:

mob/player
var/health = 100

proc/heal(var/amount as num)
src.health += amount

mob/player/human

mob/player/elf

mob/player/dwarf

mob/player/undead


Pretty straight-forward, all sub-types get the procedure too, due to inheritance. Now to specialise:

mob/player
var/health = 100

proc/heal(var/amount as num)
src.health += amount

mob/player/human

mob/player/elf
heal(var/amount as num)
..(amount * 1.5)

mob/player/dwarf
heal(var/amount as num)
..(amount * 0.7)

mob/player/undead
heal(var/amount as num)
src.health -= amount


Suddenly you see, each individual procedure only talks about the mob it's interested in. This method is of course extendable up to as many types as you like without getting any longer in terms of an individual procedure. Similarly, you only have to worry about that specific type's special code, not whether or not you accidentally trigger something you're not meant to.

If healing of say .. the undead, is bugged, you just go to the undead definition, and debug that, where it's very plain and straight-forward to read.
mob/proc is ever so slightly faster because it doesnt have to decode the argument number, but its basicaly preference
Well it's not really preference, more design, as seen above.
Thank you Stephen for explaining this to me.