ID:2351670
 
(See the best response by IainPeregrine.)
Code:
                New();
{
..();
Find_Him:
for(var/mob/earth/Him/a in world) {
if(a) { //WE found him!
src.loc=a.loc;
} else {
spawn(1 MINUTE) { goto Find_Him }
}
}
}
}


Problem description:
Wanting a NPC to find her lover when they spawn when loaded. When the world first spawn she finds them just fine. Now when they are killed she doesn't find him nor look for him. I have a guess that its because for(var/mob/earth/Him/a in world) is causing it. Just kinda lost. Any advice would be nice.
Best response
Ahoy there! I just wrote a giant post but the internet ate it, so now you get the disorganized and worse written version. Sorry :(

It's easy to give you a solution to your problem, but there are other much bigger problems that are evident from the code sample you provided. We all learn how to program with the help other other programmers, so I'm also going to point out some of these bigger problems and what you can do instead. Hopefully you'll get something positive from it and it'll help you sharpen your programming skills :)

First, here is the basic solution to your problem:
New()
..()
spawn()
var /mob/earth/Him/ourLover = locate() in world
while(!ourLover)
sleep(MINUTE)
ourLover = locate() in world
loc = ourLover.loc


This is how it works. First, we need to spawn off the code, because we usually want New() procs to return immediately, and our proc can sleep for multiple minutes. Using spawn() allows us the proc to return immediately, but the code that we spawned continues to execute.

Next, we define a variable called "ourLover". Notice that my variable has a descriptive name. Always give your variables names that describe their relationship. Good examples are things like "ourLover" or "longestWire"; bad examples are things like "a" or "wire". The "locate(typePath) in container" proc will attempt to locate an object of type "typePath" in the "container". If no typePath is supplied, it uses the type of the variable, in this case "/mob/earth/Him". So this line says "make a new variable of type /mob/earth/Him named ourLover, and then find that type of object in the world and put it into the variable".

Next, the while() loop will check if there's no lover. That's what the ! operator does, it return TRUE if the operand is FALSE (it flips or negates a value). So as long as ourLover is empty, the while() loop will run. Every time it runs, it sleeps for a minute and then tries to locate the lover again.

As soon as a lover is located, the while loop exits (or never starts at all) and the last line is executed: loc = ourLover.loc. Notice how we don't need to say "src.loc". Src is implied.

---

Now for the bigger problems. Curly braces and semicolons are unconventional in DM. Using them will make it harder for you to learn the language from the teaching resources, harder to get help on the forums (a lot of people don't understand them), and harder to work together with other programmers on large projects. It's highly recommended that you learn conventional DM (no semicolons or curly braces). Even if you choose to continue using them, you should definitely remove the semicolon from after the proc definition (on the first line). I'm surprised that compiles at all.

Labels and goto statements are included in the DM language because they are technically necessary for some very high level computer science problems, but you will never need them in your time on BYOND. The use of labels and especially goto statements are signs of major structural problems - I'll try and point out the structural problems in the code you posted:

The line "for(var/mob/earth/Him/a in world)" loops through all objects of that type in the entire world; each time through the loop, it stores an instance in the variable "a". This means that "a" will never be a false value, which means that your else, spawn(), and goto statement will never execute.

And if they DID execute, that would be an even bigger problem. Each time through the loop, it would spawn off a goto statement which would run the whole loop again. So if you had 10 iterations where "a" was false, then each would spawn off a loop that would loop through the same objects, and each one would spawn off another 10 more, meaning you'd have 100 spawned statements, and then 1000, and it would grow exponentially.

Also, once we find the "Him" object, we don't stop the loop, so it continues to loop through the world trying to find more lovers. You should read about the keywords "break" and "continue" which will help when dealing with loops.

As a general rule, if you're looping through everything in the world to try and find one object, then you should restructure your code. The correct structure here is to locate the object directly, as I wrote in the first code example.

Finally, consider writing comments for you code that say _why_ you're doing something, not just _what_ you're doing. Comments like "We found him" right after the statmenet "if(a)" are kinda obvious. We can tell what the code is doing by reading the code. What we want to know is what the code is _meant_ to do. And you should write these comments before you write the code, because they help you to understand how to structure your code before you ever write a line:
// When the NPC is created, locate its lover
// and place them in the same loc
New()
// Make sure to do the normal New() behavior:
// Spawn the locating logic so New() returns immediately
// Attempt to find a lover
// If we can't find a lover, wait a minute and try again.
// Keep trying until a lover is found.
// When a lover is finally found, set our location to its loc


Hope some of that helps! :)
^ This

i love highly detailed answers. I overlooked the loop recalling myself. huge issue, but easy to overlook.