ID:38018
 
Ever wondered why your Attack verb isn't working? Wondered why the procedure is acting stupid? Well, your bug squishing moments start with finding where the bug is occurring. I believe I picked up this technique from Volte. It's called "Markers", and you use it to find out where your code stops working, or whether something has changed, so you can spend more time on fixing it than finding it. Here's a small sample verb:
mob/verb/Attack()
        for(var/mob/Enemy/M in get_step(src,src.dir))
                M.Health -= src.Strength
Yeah, the common, cheap, useless, crappy Attack verb. But, what if something goes wrong with it, like... something stops working? Then "mark it up" like this:
mob/verb/Attack()
        world << 1 //So you know that the verb is called.
        for(var/mob/Enemy/M in get_step(src,src.dir))
                world << 2 //Check if you find a /mob/Enemy in front of you
                //(the "for" loop will not execute this code block if nothing is found)
                M.Health -= src.Strength
                world << 3 //Make sure that you reached the end of the "for" code block.

Do you see what this does? It displays numbers that show which parts of the verb are executing. We know how we expect the program to run, and therefore, we know which numbers we should expect to appear when it does run. If one of the expected numbers doesn't come up, we know where to look for the problem. Now let's say there was no enemy in front of you. This is what would come up:
1
You notice it doesn't say 2 or 3. That's because there's no Enemy, so the code in the "for" loop doesn't get executed.

Now let's try another example:

mob/var/Happy

mob/verb/Check_Happy()
        var/MakeHappy = pick(0,1)
        src.Happy = pick
        if(src.Happy == 1)
                return
        else
                return
There are many things wrong here, and we'll fix it all up, using markers, and fix up the if's:
mob/var/Happy

mob/verb/Check_Happy()
        world << 1 //Make sure the verb is called
        var/MakeHappy = pick(0,1)
        src.Happy = MakeHappy
        world << 2 //Make sure that Happy is randomly selected
        if(src.Happy) //The old if was horrible, so now it's fixed
                world << 3 //Tells you that you're happy
        else if(!src.Happy) //Here you enforce Bullet Proof Code
                //(see Lummox JR's BYONDscape article)
                world << 4 //And there it tells you that you're sad

In the old if() statment is checks if Happy is 1, and 1 only. if(src.Happy) checks if Happy does not equal 0. Still not getting it? Perhaps ANOTHER example? Fine:
mob/verb/GotoGotoTest()
//this is the verb you try to execute
        world << 1
        src.GotoTest()

mob/proc/GotoTest()
        world << 2
        src.Test()

mob/proc/Test()
        world << 3
        src.Name()

mob/proc/Name()
        world << 4
        var/T = input("What's your name, buddy?") as text
        world << 5
        src.name = html_encode(T)
        world << 6
By using this, you can tell when a proc stops executing, and you'll notice if it doesn't ask you to change your name.

And here we will go away from outputting numbers, and into outputting variables. This will come in very handy. Most people use them, and most people call them "Debug Messages", but I like referring to them as "Markers". Typically "debug messages" can refer either to outputting a "checkpoint" indicator as in the earlier examples, or a variable value as in the examples here. This will save time finding out what's wrong, guaranteed, so don't hesitate to use it.

How about finding out if a variable has changed?

mob/var/Test="Hello"

mob/verb/TestVerb()
        src << "This is just a test!"
        src.Test = "Changed"
        if(src.Test == "Hello")
                world<<"Not changed"
As you can see, world << "Not changed" will never be called because the variable Test is changed along the code. So to mark it you'd add:
mob/var/Test = "Hello"

mob/verb/TestVerb()
        world << Test
        src << "This is just a test!"
        src.Test = "Changed"
        world << Test
        if(src.Test == "Hello")
                world << "Not changed"

It'll show up as:
Hello
This is just a test!
Changed
So, there you see Test isn't "Hello" anymore, but it's "Changed". And finally, what if you just want to see variables assigned to your mob, or to something else?
mob/var
        Happy=4
        Sad=1
        Gender="Male"

mob/verb/CheckVariables()
        var/Number=rand(1,5)
        world<<"The random number chosen was: [Number]"
        world<<"Your happy status: [Happy]"
        world<<"Your sad status: [Sad]"
        world<<"Your gender: [Gender]"
This will output:
The random number chosen was: (Some random number, from 1 to 5)
Your happy status: 4
Your sad status: 1
Your gender: Male
You can use Markers for just about ANYTHING! Whether it's a null object, or mob, or even if you just misspell a word, this system will help you track down where things are going wrong. Once you've done that, it's a lot easier to figure out the problem.
Nice Start Crashed

Although it needs some fixing up it does help


Twista(As known by crashed KingTwista)