ID:47491
 
Keywords: tutorial
Modular: composed of standardized units or sections for easy construction or flexible arrangement - dictionary.com*


Many people seem to think the below code would be good:

mob/verb/Punch()
var/mob/M = locate(/mob) in get_step(src,dir) //find a mob in front of the player
flick("punch",src) //flick the punch icon state
if(M) //if it found said mob
view(src) << "[src.name] punches [M.name]"
M.HP -= 10
M.deathcheck(src)


However, if you have more than one attack that does almost the same thing, it wouldn't be so good. For example, what if you had a Kick() verb, too? And the only difference with the kick verb would be that it would deal more damage, say something else, and flick a different icon state. Would you copy and paste your punch code, then change the details? Probably! However, there is a much easier way to go about this, and it is with a modular proc:

mob/proc/Attack(name,damage,flickicon)
var/mob/M = locate(/mob) in get_step(src,dir) //find a mob in front of the player
flick(flickicon,src) //flick the punch icon state
if(M) //if it found said mob
view(src) << "[src.name] [name] [M.name]"
M.HP -= damage
M.deathcheck(src)

mob/verb
Punch()
Attack("punches",10,"punch")
Kick()
Attack("kicks",15,"kick")


Did you see what I did there? I defined a new proc, called Attack(), and gave it a few args. From there, I called the Attack proc from the verbs with these args, and Voila, you just saved a few lines of code. So right now you might be thinking, "So what's the big deal? I'm barely saving 3 or 4 lines!". Well, the big deal is that you can easily change the attack proc instead of changing the two verbs. Can you imagine having 200+ attacks that all do roughly the same thing, and then you figure out there's a bug in a bit of repetitive code? Well, then you have to spend 2+ hours fixing it. However, if use a proc to handle everything, you can change one little chunk of code and be over with it quickly! A huge time saver!

Now, what if I wanted to implement a status system, so that if a user is doing something, let's say taunting in this case, they can't attack. Well, you just tack on if(status != "taunting") on to every attack, right? Wrong. You simply use return (look it up in the DM reference if you don't know what it does) and a little if() statement:

var/status

mob/proc/Attack(name,damage,flickicon)
if(Status_Check()) //if they can't attack due to a status issue
return //cancel the attack
var/mob/M = locate(/mob) in get_step(src,dir) //find a mob in front of the player
flick(flickicon,src) //flick the punch icon state
if(M) //if it found said mob
view(src) << "[src.name] [name] [M.name]"
M.HP -= damage
M.deathcheck(src)

mob/proc/Status_Check()
if(status == "taunting")
src << "You can't attack while taunting!"
return 1//return one, which will mean don't attack
return null //return null, which will mean attack

mob/verb
Punch()
Attack("punches",10,"punch")
Kick()
Attack("kicks",15,"kick")


As your code expands, designing it like this is a good thing to do. That way, if you ever decide, "Hey I need to change this! I just added a new status condition!" you only have a minute or so of work, versus 2 hours. In my one game, I have a few basic procs, such as melee attack, projectile attack etc. (there are a few more), some stat/status procs, a death check proc, and a damage proc. I strung these all together, and now my semi-complicated battle system is simple to add attacks to and change. Plus, most of the attacks take but 2 lines of code. Overall, it's best to program this way. Its efficient, saves time, and, most importantly, prevents you from hitting the resource limit as many games have before.

Please comment if I made any mistakes, typos, etc.

*Yes, I know there was a definition pertaining specifically to computers, I just felt this definition was easier to understand.
Not that it Matters but you used the word 'args', It could be changed to arguments for better understanding.

You're not returning null on the Status_Check proc.
Bug: The second return in the Status_Check() proc should be null, not 1.
One thing I sort of disagree with is the whole "[src.name] [name] [M.name]" line. It might be better to give the name argument a different variable name like action.

"[src.name] [action] [M.name]"

That way, it reads more like a sentence instead of a juxtaposition of various variables all called "name". =)


This is a very nice article on encapsulation/information hiding, however!

For non-programmers: "Hiding" sounds furtive, but information hiding is a good thing. That means that your code has a black box that does exactly what you want it to, and you don't have to worry about flipping all of the little switches inside every time you want to make something happen. It also means that if there's something wrong with the box, you just get a new one. If you didn't have the black box, you'd have to go around and rewire all of the systems that didn't use the black box instead.
Yeah, after you pointed that out, calling the arg "name" sounds stupid >_<
I know what you mean I already have about twenty procs that run that that. I have a Naruto game so I have one for jutsu usage, damaging for attacks, damaging for jutsus, knockout, leveling, training. A whole bunch and they all work great. It's really a great way to code into a game with multiple, similar, actions.
Great job. Definitely more efficient.

Xooxer wrote:
Bug: The second return in the Status_Check() proc should be null, not 1.

I think 0 should be returned as it might be an easier concept for people to understand:
1 lets it activate. 0 stops it from activating.


But of course, this isn't a large issue or anything.
The return proc returns null by default. I guess having return 0 is more explicit, helping new programmers understand the process, but it's not necessary for a false return value. I'm just saying that it should have been a false return value, not a true one. :P

Good article, btw.
this, and it is with a modular proc:


mob/proc/Attack(name,damage,flickicon)
var/mob/M = locate(/mob) in get_step(src,dir) //find a mob in front of the player
flick(flickicon,src) //flick the punch icon state
if(M) //if it found said mob
view(src) << "[src.name] [name] [M.name]"
M.HP -= damage
M.deathcheck(src)

mob/verb
Punch()
Attack("punches",10,"punch")
Kick()
Attack("kicks",15,"kick")


be your best
thank you i needed something like this but in a game im making is useing guns can some one put a tutorial link or codes that will help me ?
i dont get it ????
nice